Oh Mann, das bereitete mir ein paar Tage lang Kopfschmerzen und konnte nicht herausfinden, wie ich das machen sollte. Das Schlimmste war, dass das Erstellen eines neuen Xcode iOS-Projekts mit der Master-Detail-Vorlage einwandfrei funktionierte. Glücklicherweise war diese kleine Tatsache am Ende, wie ich die Lösung fand.
Es gibt einige Beiträge, die darauf hindeuten, dass die Lösung darin besteht, die neue primaryViewControllerForCollapsingSplitViewController:
Methode zu implementieren UISplitViewControllerDelegate
. Ich habe das ohne Erfolg versucht. Was Apple in der Master-Detail-Vorlage tut, die zu funktionieren scheint, ist die Implementierung der neuen splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:
Delegat-Methode ( atmen Sie tief ein, um all dies zu sagen) (wieder aktiviert UISplitViewControllerDelegate
). Laut den Dokumenten ist diese Methode:
Fordert den Delegierten auf, den primären Ansichtscontroller anzupassen und den sekundären Ansichtscontroller in die reduzierte Schnittstelle zu integrieren.
Lesen Sie den Diskussionsteil dieser Methode, um genauere Informationen zu erhalten.
Apple geht folgendermaßen damit um:
- (BOOL)splitViewController:(UISplitViewController *)splitViewController
collapseSecondaryViewController:(UIViewController *)secondaryViewController
ontoPrimaryViewController:(UIViewController *)primaryViewController {
if ([secondaryViewController isKindOfClass:[UINavigationController class]]
&& [[(UINavigationController *)secondaryViewController topViewController] isKindOfClass:[DetailViewController class]]
&& ([(DetailViewController *)[(UINavigationController *)secondaryViewController topViewController] detailItem] == nil)) {
// Return YES to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
return YES;
} else {
return NO;
}
}
Diese Implementierung führt im Wesentlichen Folgendes aus:
- Wenn
secondaryViewController
es das ist, was wir erwarten (a UINavigationController
) und es zeigt, was wir erwarten (a DetailViewController
- Ihr View Controller), aber kein Modell hat ( detailItem
), dann " Return YES to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
"
- Andernfalls kehren Sie zurück, "
NO
damit der Controller für geteilte Ansichten versuchen kann, den Inhalt des Controllers für sekundäre Ansichten in die reduzierte Oberfläche zu integrieren".
Die Ergebnisse sind für das iPhone im Hochformat wie folgt (entweder im Hochformat oder im Hochdrehen - oder genauer gesagt in der kompakten Größenklasse):
- Wenn Ihre Ansicht korrekt ist
- und hat ein Modell, zeigen Sie die Detailansicht Controller
- Hat aber kein Modell, zeigen Sie den Master View Controller
- Wenn Ihre Ansicht nicht korrekt ist
- Zeigen Sie den Master View Controller an
Klar wie Schlamm.
UISplitViewController
und kehre immerYES
von dieser Methode zurück. Dann habe ich die Klasse für geteilte Ansichten in Storyboard geändert, da ich den Master immer im Hochformat auf dem iPhone anzeigen möchte. :)UISplitViewController
aber festgestellt, dass das nicht funktioniert hat: EssplitViewController:collapseSecondaryViewController:ontoPrimaryViewController:
wurde nie aufgerufen. Stattdessen habe ich Apples Vorlage kopiert und in das AppDelagate eingefügt. Dies erforderte einige Änderungen beim Erstellen des UISplitViewController unterapplication didFinishLaunchingWithOptions:
(wo ich auch Apples Vorlage kopiert habe).splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:
nie angerufen. Es scheint, dass der Delegat dieapplicationDidFinishLaunchingWithOptions:
Methode meines App-Delegaten richtig festlegt . Hat jemand anderes dieses Problem gesehen und diese Lösung NICHT funktioniert?Hier ist die akzeptierte Antwort in Swift. Erstellen Sie einfach diese Unterklasse und weisen Sie sie Ihrem splitViewController in Ihrem Storyboard zu.
quelle
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
Schnelle Version der richtigen Antwort von Mark S.
Wie in der Master-Detail-Vorlage von Apple bereitgestellt.
Klärung
(Was Mark S sagte, war etwas verwirrend)
Diese Delegatenmethode wird aufgerufen
splitViewController: collapseSecondaryViewController: ontoPrimaryViewController:
, weil sie genau das tut. Wenn Sie zu einer kompakteren Breitengröße wechseln (z. B. beim Drehen des Telefons von Querformat zu Hochformat), muss der geteilte Ansichts-Controller in nur eine davon reduziert werden.Diese Funktion gibt einen Booleschen Wert zurück, um zu entscheiden, ob das Detail reduziert und der Master angezeigt werden soll oder nicht.
In unserem Fall entscheiden wir also basierend darauf, ob ein Detail ausgewählt wurde oder nicht. Woher wissen wir, ob unser Detail ausgewählt ist? Wenn wir der Master-Detail-Vorlage von Apple folgen, sollte der Detailansichts-Controller eine optionale Variable mit den Detailinformationen haben. Wenn sie also Null (.None) ist, ist noch nichts ausgewählt, und wir sollten den Master anzeigen, damit der Benutzer etwas auswählen kann.
Das ist es.
quelle
Apple's Master-Detail template
, er soll nicht großartig oder prägnant sein, sondern nur sachlich. :)Aus der Dokumentation benötigen Sie einen Delegaten verwenden , um das zu sagen ,
UISplitViewController
nicht die Detailansicht in den „kollabierte Schnittstelle“ (dh des „Portrait - Modus“ in diesem Fall) zu integrieren. In Swift 4 wurde die dafür zu implementierende Delegate-Methode umbenannt:quelle
Meine App wurde in Swift 2.x geschrieben und konnte gut laufen. Nach der Konvertierung in Swift 3.0 (mithilfe des XCode-Konverters) werden zuerst Details angezeigt, anstatt Master im Hochformat. Das Problem ist, dass der Name der Funktion splitViewController nicht geändert wird, um mit der neuen Funktion von UISplitViewControllerDelegate übereinzustimmen.
Nachdem der Name dieser Funktion manuell geändert wurde, kann meine App jetzt ordnungsgemäß funktionieren:
quelle
self.delegate = self
aufviewDidLoad
Verfahren..m:
quelle
Wenn Sie keine Standardwerte haben, die im Detailansicht-Controller angezeigt werden sollen, können Sie einfach den Standard-Übergang zwischen dem SplitViewController und Ihrem Detail-UIViewController im Storyboard löschen. Dadurch wird es immer zuerst in den Master View Controller verschoben.
Der Nebeneffekt davon ist, dass Sie in SplitViewController nicht zwei Ansichten im Querformat, sondern eine Ansicht in voller Größe sehen, bis Show Detail Segue im Master View Controller ausgelöst wird.
quelle
Für alle Leute, die den Freitag-Bereich von cs193p nicht finden konnten:
In Swift 3.1.1 hat das Erstellen einer Unterklasse von UISplitViewController und das Implementieren einer seiner Delegate-Methoden für mich wie ein Zauber funktioniert:
Mein Storyboard
quelle
public func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool
Meiner Meinung nach sollten Sie dieses Problem allgemeiner lösen. Sie können den UISplitViewController in Unterklassen unterteilen und ein Protokoll in den eingebetteten Ansichtscontrollern implementieren.
Beispielimplementierung in UITableViewController:
Ich hoffe es hilft. Sie können diese Klasse also wiederverwenden und müssen lediglich ein Protokoll implementieren.
quelle
Entfernen Sie einfach DetailViewController von SplitView-Controllern, wenn Sie es benötigen, um vom Master aus zu starten.
quelle
Dies funktionierte für mich unter iOS-11 und Swift 4:
quelle
Die Funktion wird in neuen Versionen von Swift umbenannt, sodass dieser Code unter Swift 4 funktioniert:
quelle
Xamarin / C # -Lösung
quelle
Setzen Sie einfach die
preferredDisplayMode
Eigenschaft vonUISplitViewController
auf.allVisible
quelle