webentwicklung-frage-antwort-db.com.de

Adaptive Segue in Storyboard Xcode 6. Ist Push veraltet?

Xcode 6 Interface Builder hat standardmäßig ein neues Kontrollkästchen "Größenklassen verwenden". Es macht Ansichten anpassungsfähig. enter image description here

Wenn ich versuche, zwischen zwei Ansichten in meinem Storyboard zu unterscheiden, habe ich neue Optionen: enter image description here

stattdessen alt:

enter image description here

Jetzt haben wir "Show" und "Modal präsentieren" anstelle von "Push" und "Modal". Die alten Optionen sind als veraltet markiert. Ich habe die Option "show" gewählt, weil sie in den Segue-Einstellungen "show" (z. B. Push) heißt.

enter image description here

Aber Push macht es nicht. Die Segue-Animation sieht aus wie eine Folie von unten (modal) und die Navigationsleiste verschwindet.

Die Frage ist: Wie kann ich dafür sorgen, dass "Show" wie Push funktioniert? Ist es möglich oder sollte ich stattdessen "Push (veraltet)" verwenden? Wo finde ich Informationen zu neuen Segue-Typen? Das einzige, was ich in der iOS8-Entwicklerbibliothek gefunden habe, ist Storyboards helfen Ihnen beim Entwerfen Ihrer Benutzeroberfläche , aber es gibt keine Informationen zu "show" segue.

AKTUALISIEREN

Ich habe versucht, ein neues Projekt zu erstellen und "show" funktioniert wirklich wie "Push". Ich denke, das Problem in meinem Projekt kann darin bestehen, dass ich den Navigationscontroller mit diesem Code wiederverwende, aber ich weiß nicht, wie ich es beheben soll.

if ( [segue isKindOfClass: [SWRevealViewControllerSegue class]] ) {
    SWRevealViewControllerSegue *swSegue = (SWRevealViewControllerSegue*) segue;

    swSegue.performBlock = ^(SWRevealViewControllerSegue* rvc_segue, UIViewController* svc, UIViewController* dvc) {

        UINavigationController* navController = (UINavigationController*)self.revealViewController.frontViewController;
        [navController setViewControllers: @[dvc] animated: NO ];
        [self.revealViewController setFrontViewPosition: FrontViewPositionLeft animated: YES];
    };

}

Danach versuche ich, NewViewController nach MainViewController zu pushen enter image description here

UPDATE 2:

Ich scheine nur iOS 7, iOS 7.1 Problem zu sein.

119
John Kakon

Ja, verwenden Sie "Show" anstelle von "Push".

Wie kann ich dafür sorgen, dass "Show" wie Push funktioniert? Ist es möglich oder sollte ich stattdessen "Push (depricated)" verwenden?

Es sollte; das tut es für mich. Ich verwende Xcode 6 Beta 2 und zum Testen habe ich die einzelne Ansichtsvorlage verwendet (Aufruf des vorgefertigten Ansichtscontrollers in IB "VC_A"). Ich habe dann einen weiteren View-Controller hinzugefügt ("VC_B"). Ich habe dann eine Schaltfläche auf VC_A hinzugefügt, um VC_B und eine andere von VC_B zurück zu VC_A anzuzeigen. Wenn ich einen Navigationscontroller als anfänglichen Ansichtscontroller im Storyboard hinzufüge und VC_A als RootViewController festlege, haben sowohl "Push" als auch "Show" den gleichen Effekt. Wenn ich keinen anfänglichen Navigationscontroller besitze und "show" verwende, erhalte ich das, was Sie beschrieben haben, indem der VC_B von unten nach oben rutscht. Wenn ich versuche, auf Push zuzugreifen, kommt es zu einem Absturz, da für Push ein Navigationscontroller erforderlich ist. Es sieht also so aus, als würde "show" einen Push ausführen, wenn ein Navigationscontroller bereitgestellt wird, und ein Geschenk mit einem modalen Übergangsstil erstellen, wenn kein Navigationscontroller vorhanden ist.

Wo finde ich Informationen zu neuen Segue-Typen?

Daher habe ich einige Informationen in der Sitzung "Was ist neu in Interface Builder" gefunden hier . Wenn Sie sich die Folien ansehen, wird auf einer Folie (41) die Änderung erwähnt. Wenn Sie sich dieses Sitzungsvideo ansehen, können Sie zu Minute 38:00 springen, wo über adaptive Segmente gesprochen wird. Sie erklären, dass der adaptive Bereich "Anzeigen" beispielsweise den Kontext berücksichtigt, wenn entschieden wird, wie die Präsentation eines neuen Ansichtscontrollers erfolgen soll.

95
Spencer Hall

Es gibt bereits eine akzeptierte Antwort, aber ich wollte ein bisschen mehr Informationen geben, möglicherweise Informationen, die vorher nicht verfügbar waren.

Wie bereits erwähnt, wurden die Segmente "Push" und "Modal" verworfen und durch "Show" bzw. "Modal" ersetzt. Laut der Dokumentation von Apple wurden die neuen Segmente weiter in Segmente unterteilt, die sich an Größenklassen anpassen. Die älteren Versionen sollten nur zur Unterstützung von iOS-Versionen verwendet werden, die älter als iOS 8 sind.

Das Dokument im folgenden Link erklärt dies und die Beschreibung aller verfügbaren alten und neuen Segmente.

Hinzufügen eines Segues zwischen Szenen in einem Storyboard

Für den Fall, dass sich die URL in Zukunft ändert, ist dies die Erklärung für jeden neuen Abschnitt:

Show

Präsentieren Sie den Inhalt je nach Bildschirminhalt im Detail- oder Masterbereich. Wenn die App eine Master- und Detailansicht anzeigt, wird der Inhalt in den Detailbereich verschoben. Wenn die App nur den Master oder das Detail anzeigt, wird der Inhalt auf den aktuellen View Controller-Stapel verschoben.

Detail anzeigen

Präsentieren Sie den Inhalt im Detailbereich. Wenn die App eine Master- und Detailansicht anzeigt, ersetzt der neue Inhalt das aktuelle Detail. Wenn die App nur den Master oder das Detail anzeigt, ersetzt der Inhalt den oberen Bereich des aktuellen View Controller-Stacks.

Modal präsentieren

Präsentieren Sie den Inhalt modal. Es gibt Optionen zum Auswählen eines Präsentationsstils (UIModalPresentationStyle) und eines Übergangsstils (UIModalTransitionStyle).

Präsentiert als Popover

Präsentieren Sie den Inhalt als Popover, das in einer vorhandenen Ansicht verankert ist. Es gibt eine Option, um die möglichen Richtungen des Pfeils festzulegen, der an einer Kante der Popover-Ansicht angezeigt wird (UIPopoverArrowDirection). Es gibt auch eine Option zum Angeben der Ankeransicht.

32
alondono

tldr; Löschen Sie den Segue, der nicht richtig verschoben wird, und erstellen Sie ihn im Storyboard neu, indem Sie ihn von UIView/UIControl auf den Zielansichts-Controller ziehen.

An den anderen Antworten ist nichts auszusetzen, aber hier wird erklärt, was passiert, wie Sie überprüfen können, ob es passiert, und wie Sie das Problem in Zukunft beheben können.

Hintergrund

In meinem Fall funktionierte keiner meiner Show Segues, obwohl ich bereits einen UINavigationController als anfänglichen View-Controller hatte (mit meinem Content-UIViewController als Root).

Warum und wie die Show abbricht

Das Show-Segment wird unterbrochen, wenn eine Aktion mit dem Segment in der Quell-XML des Storyboards verknüpft ist. Ein typisches Szenario, das dies verursacht, könnte sein, dass Sie einen Abschnitt von einem zuvor im Code aufgerufenen manuellen Abschnitt neu definiert haben. Dadurch verbleiben die folgenden Bits im Storyboard-XML.

<connections>
    <segue destination="85t-Z1-hxf" kind="show" identifier="ToOptions" action="showDetailViewController:sender:" id="gdZ-IX-KcN">
</connections>

Nota Bene Storyboard als XML anzeigen; Klicken Sie mit der rechten Maustaste auf die Storyboard-Datei und wählen Sie Öffnen als> Quellcode . Verwenden Sie zum Zurücksetzen Öffnen als> Interface Builder - Storyboard

Um benutzerdefinierte Aktionen bei Verwendung des Segues aus dem Storyboard zu berücksichtigen, können Sie einfach auf prepareForSegue tippen, den Zielansichts-Controller abfangen und alle Methoden von diesem Speicherort aus aufrufen. In jedem Fall ist der Nebeneffekt für diesen kleinen Fehler (der Fehler ist die Tatsache, dass wenn Sie das Segment neu definieren, es nicht richtig in xml eingerichtet ist ~ dh die Aktion bleibt auch nach dem Ändern des Segues in eines, das von einem UIView aus ausgeführt wird (oder) UIControl) zu einem Target View Controller).

Leider schlägt die direkteste Lösung fehl. Wenn Sie also nur das xml-Attribut für die Aktion aus dem Storyboard entfernen, wird [~ # ~] nicht [~ # ~] das Problem beheben. Stattdessen muss man einfach den Abschnitt löschen und neu erstellen im Storyboard.

Nach der Neuerstellung hat das Storyboard-XML keine Aktion mehr, die mit dem jeweiligen Segment verknüpft ist, und die Show wird als Push ausgeführt.

Beispiel Xml für korrekte Show Segue

  <connections>
    <segue destination="RbV-Au-WV9" kind="show" identifier="ToOptions" id="5dm-os-bcS"/>
  </connections>

Milderung

Um eine Wiederholung zu vermeiden, muss man sich nach Möglichkeit nur an nicht manuelle Storyboard-Segmente halten, indem man mit prepareForSegue die erforderlichen Aktionen basierend auf dem Zielansichts-Controller hinzufügt. Wenn Sie mischen und anpassen müssen, stellen Sie vorsichtshalber sicher, dass in Ihren Show-Segues keine Aktionen im Storyboard-XML-Format angefügt sind. Wenn Sie mit älteren Projekten arbeiten, sollten Sie dem Storyboard-Quellcode besondere Aufmerksamkeit schenken, da ich einige Probleme entdeckt habe.

23
Tommie C.

Wie Scott Robertson hier kommentiert , sieht dies aus wie ein Fehler in iOS 7.

Es scheint, dass in iOS 8 der Übergang zur Laufzeit abgeleitet wird (korrektes Verhalten), während in iOS 7 der Übergang zur Entwurfszeit abgeleitet wird (fehlerhaftes Verhalten).

Die einfachste Lösung besteht darin, einen nicht verwendeten Navigationscontroller zum Storyboard hinzuzufügen und zu verknüpfen, sodass der betreffende Ansichtscontroller Teil dieses Navigationscontrollers ist. Sie müssen den Navigationscontroller eigentlich nicht instanziieren, sondern benötigen lediglich den fehlerhaften Ansichtscontroller, um zu wissen, dass er in einen Navigationscontroller eingebettet ist.

Hinweis: Die Simulation einer Navigationsleiste ist für diese Zwecke nicht ausreichend. Sie müssen tatsächlich einen Navigationscontroller im Push-Stapel haben.

So reproduzieren Sie den Fehler:

  1. Erstellen Sie ein neues Storyboard, das Größenklassen verwendet.
  2. Erstellen Sie zwei Ansichtscontroller (keine Navigationscontroller).
  3. Lassen Sie den ersten Ansichts-Controller den zweiten Ansichts-Controller über einen Show (z. B. Push) - Bereich anzeigen, der beispielsweise mit einer Schaltfläche verknüpft ist.
  4. Zeigen Sie im Code den ersten Ansichtscontroller an, binden Sie ihn jedoch mit der Methode initWithRootViewController: In einen Navigationscontroller ein.
  5. Führen Sie die App unter iOS 7 aus.
  6. Tippen Sie auf die Schaltfläche, die den Push ausführen soll.
  7. Unter iOS 7 erhalten Sie einen modalen Übergang anstelle eines Push-Vorgangs. Unter iOS 8 erhalten Sie das richtige Push-Verhalten.

enter image description here

So beheben Sie den Fehler:

  1. Fügen Sie dem Storyboard einen Navigationscontroller hinzu, und legen Sie den ersten Ansichtscontroller als Stammansichtscontroller fest. (Hinweis: Das Hinzufügen der zweiten als Root-View-Controller behebt diesen Fehler NICHT.)
  2. Geben Sie eine Junk-ID ein, um die Warnung zu unterdrücken, dass auf den Navigationscontroller nicht zugegriffen werden kann, und um sich selbst zu dokumentieren, dass er nur als Problemumgehung vorhanden ist. (z.B. workaround for show segues in iOS 7).

enter image description here

Beachten Sie, wie der Navigationscontroller im zweiten Bild hinzugefügt wurde und dass er keine ankommenden Pfeile enthält (d. H., Es gibt keine Möglichkeit, ihn zu instanziieren, außer die View Controller-ID zu verwenden).

20
Senseful

Ich weiß, dass ich zu spät komme, aber ich wollte mitteilen, was ich gelernt habe. Dies ist in der Tat ein Fehler und ist noch heute vorhanden (18.12.2014).

Ich habe einen Artikel darüber geschrieben hier .

Es ist leicht reproduzierbar; unter iOS8 funktioniert einwandfrei und sogar unter iOS7.x, solange Sie einen Ansichtscontroller nicht programmgesteuert in den Stapel schieben, bevor Sie das Segue Show aufrufen.

Wenn Sie nur mithilfe von Storyboard-Verbindungen auf den Stapel pushen, funktioniert dies. aber anscheinend, wenn Sie über Code pushen, ist die Eigenschaft navigationController von pushed UIViewControllernil, und wenn Sie Show aufrufen, wird sie als modal angenommen, weil Es gibt keine Navigation, um den Stapel zu steuern.

Bisherige einzige Problemumgehung ist entweder kein Push per Code (nicht durchführbar) oder die Verwendung des jetzt veralteten Push.

Ich habe ein Radar angemeldet (Link zum Artikel). Fühlen Sie sich frei, Duplikate mit der Hoffnung einzureichen, Apple zur Behebung dieses Problems).

13
esttorhe

Ich hatte das gleiche Problem mit Segues in Xcode 7 und iOS 7.1.2. Das Anzeigen von Segmenten (neue Funktion von iOS 8) funktioniert wie das Anzeigen von Segmenten in iOS 7 und ermöglicht es Ihnen nicht, Ihre Ansichts-Controller in den Navigations-Controller-Stapel zu verschieben, wenn Sie definieren den Seguetyp mit Xcode in Ihrem Storyboard. Aus diesem Grund gibt Ihr self.navigationController den Wert nil zurück, da der View Controller nicht auf den Stapel verschoben wurde und Sie ihn nicht einfügen können.

Ich verstehe nicht, warum Apple hat keine Benachrichtigungen für diesen Fall in Xcode hinzugefügt, wenn Sie Ihre App für iOS 7 benötigen. Sie sagen, dass die Push-Methode veraltet ist, aber Show funktioniert mit iOS 7 nicht richtig.

Was habe ich getan, um das Problem zu beheben:

Ich habe die MYShowSegue-Klasse mit .h erstellt

#import <UIKit/UIKit.h>

@interface MYShowSegue : UIStoryboardSegue

@end

Und .m-Datei mit nur einer Methode ausführen :

#import "MYShowSegue.h"

@implementation MYShowSegue

- (void) perform {

    if ([[[self sourceViewController] navigationController] respondsToSelector:@selector(showViewController:sender:)]) {

        id sender = nil;
        [[[self sourceViewController] navigationController] showViewController:[self destinationViewController] sender:sender];
    }else{

        [[[self sourceViewController] navigationController] pushViewController:[self destinationViewController] animated:YES];
    }
}

@end

Dann müssen Sie einen benutzerdefinierten Typ für jeden Abschnitt in Ihrem Storyboard festlegen und eine neue Klasse dafür auswählen, in meinem Fall MYShowSegue.

Custom Segue Example

Diese Lösung wird Ihnen helfen, eine vollständige Unterstützung Ihrer iOS 7-Apps zu erhalten. Sie verwenden die pushViewController -Methode, um Ihre Ansichten zu pushen, und für iOS 8,9 usw .Ihr segue funktioniert mit der neuen (iOS 8) Methode showViewController

Vergiss nicht, dasselbe mit all deinen Abschnitten in deinem Storyboard zu tun.

2
Igor Tikhonov

Dies geschieht immer noch in iOS 10.x.

Das Löschen und Wiedereinsetzen von Segues hat für mich nichts gelöst:

Problem: Die erforderliche Funktionalität bestand aus 7 Segmenten, die nur als "Push" (tatsächlich als Show-Detail) fungieren. Tatsächlich würde jedoch nur das erste von mir hinzugefügte Segment "Push" ausführen, während sich alle anderen Segmente modal verhalten würden. Dies geschieht, obwohl der Interface Builder die einzelnen Segmente identisch beschreibt.

Lösung: Ich musste die Aktion zu den 6 Abschnitten hinzufügen, die sie nicht hatten.

Original Storyboard XML

<connections>
  <segue destination="tIr-4a-WfZ" kind="showDetail" identifier="A" action="showViewController:sender:" id="8yd-Ne-7KA"/>
  <segue destination="4mB-YE-5dM" kind="showDetail" identifier="B" id="Uod-JC-786"/>
  <segue destination="Qh5-bJ-KcE" kind="showDetail" identifier="C" id="3PW-nV-hWl"/>
  <segue destination="EI6-f4-QBB" kind="showDetail" identifier="D" id="WUK-ju-KDm"/>
  <segue destination="nTz-N4-fpW" kind="showDetail" identifier="E" id="Id6-bW-Huc"/>
  <segue destination="JEp-CH-6dW" kind="showDetail" identifier="F" id="G0L-XW-7f4"/>
  <segue destination="AET-S1-O6h" kind="showDetail" identifier="G" id="3NK-93-wTy"/>
</connections>

Ich habe dies durch Hinzufügen von showViewController: sender geändert

<connections>
  <segue destination="tIr-4a-WfZ" kind="showDetail" identifier="A" action="showViewController:sender:" id="8yd-Ne-7KA"/>
  <segue destination="4mB-YE-5dM" kind="showDetail" identifier="B" action="showViewController:sender:" id="Uod-JC-786"/>
  <segue destination="Qh5-bJ-KcE" kind="showDetail" identifier="C" action="showViewController:sender:" id="3PW-nV-hWl"/>
  <segue destination="EI6-f4-QBB" kind="showDetail" identifier="D" action="showViewController:sender:" id="WUK-ju-KDm"/>
  <segue destination="nTz-N4-fpW" kind="showDetail" identifier="E" action="showViewController:sender:" id="Id6-bW-Huc"/>
  <segue destination="JEp-CH-6dW" kind="showDetail" identifier="F" action="showViewController:sender:" id="G0L-XW-7f4"/>
  <segue destination="AET-S1-O6h" kind="showDetail" identifier="G" action="showViewController:sender:" id="3NK-93-wTy"/>
</connections>
1
Damo