it-swarm.com.de

Dargestellten View Controller abweisen

Ich habe eine theoretische Frage. Jetzt lese ich Apples ViewController guide.

Sie schrieben: 

Wenn es Zeit ist, einen präsentierten View-Controller zu schließen, wird der Der bevorzugte Ansatz besteht darin, den Presenting View Controller abzulehnen es. Mit anderen Worten, wenn immer möglich, derselbe View-Controller wie Der View-Controller sollte auch die Verantwortung für .__ übernehmen. es abweisen Obwohl es verschiedene Techniken gibt, um das .__ zu benachrichtigen. Darstellen des View-Controllers, den der präsentierte View-Controller anzeigen soll abgelehnt werden, ist die bevorzugte Technik die Delegation.

Aber ich kann nicht erklären, warum ich ein Protokoll in präsentem VC erstellen und Delegatvariable hinzufügen, eine Delegat-Methode erstellen muss, um VC zu präsentieren, um das präsentierte VC zu verwerfen, anstatt einen einfachen Aufruf in Presentation zu erstellen Ansicht der Controller-Methode 

[self dismissViewControllerAnimated:NO completion:nil]

Warum ist die erste Wahl besser? Warum empfiehlt Apple es?

94
nikitahils

Ich denke, Apple hält sich hier ein wenig für ein potenziell kludiges Stück API. 

  [self dismissViewControllerAnimated:NO completion:nil]

Ist eigentlich ein bisschen eine Geige. Sie können dies zwar legitimerweise auf dem präsentierten View-Controller aufrufen, die Nachricht wird jedoch nur an den präsentierenden View-Controller weitergeleitet. Wenn Sie etwas anderes tun möchten, als nur den VC zu kündigen, müssen Sie dies wissen und Sie müssen es genauso wie eine Delegatmethode behandeln - da es so ziemlich das ist, was es ist, ein etwas unflexibles Eingebackenes Methode delegieren. 

Vielleicht sind sie auf eine Menge schlechten Codes gestoßen, weil die Leute nicht wirklich verstanden haben, wie dies zusammengesetzt wird, daher ihre Vorsicht. 

Aber natürlich, wenn Sie nur die Sache abweisen müssen, fahren Sie fort.

Mein eigener Ansatz ist ein Kompromiss, zumindest erinnert er mich daran, was los ist:

  [[self presentingViewController] dismissViewControllerAnimated:NO completion:nil]

[schnell]

  self.presentingViewController?.dismiss(animated: false, completion:nil)
102
foundry

Dies ist für die Wiederverwendbarkeit des View-Controllers.

Ihr View Controller sollte sich nicht darum kümmern, ob er als modal dargestellt, auf einem Navigationscontroller oder ähnlichem angezeigt wird. Wenn Ihr View Controller sich selbst entlässt, gehen Sie davon aus, dass er modal dargestellt wird. Sie können diesen Ansichtscontroller nicht auf einen Navigationscontroller verschieben.

Indem Sie ein Protokoll implementieren, lassen Sie den übergeordneten View-Controller entscheiden, wie er präsentiert/verschoben und entlassen/abgelegt wird.

46

Aktualisiert für Swift 3

Ich bin hierher gekommen, um den aktuellen (präsentierten) View Controller abzulehnen. Ich gebe diese Antwort für jeden, der mit demselben Ziel hierher kommt.

Navigationssteuerung

Wenn Sie einen Navigationscontroller verwenden, ist das ganz einfach.

Zurück zum vorherigen View-Controller:

// Swift
self.navigationController?.popViewController(animated: true)

// Objective-C
[self.navigationController popViewControllerAnimated:YES];

Zurück zum Root-View-Controller:

// Swift
self.navigationController?.popToRootViewController(animated: true)

// Objective-C
[self.navigationController popToRootViewControllerAnimated:YES];

(Danke an diese Antwort für das Objective-C.)

Modal View Controller

Wenn ein View Controller modal dargestellt wird, können Sie ihn (vom zweiten View Controller) durch Aufruf abweisen

// Swift
self.dismiss(animated: true, completion: nil)

// Objective-C
[self dismissViewControllerAnimated:YES completion:nil];

Die Dokumentation sagt,

Der Präsentations-View-Controller ist dafür verantwortlich, die Ansicht zu schließen Controller präsentiert. Wenn Sie diese Methode in der dargestellten Ansicht aufrufen, __. Controller selbst, fordert UIKit den Presenting-View-Controller auf, die Entlassung.

Es funktioniert also für den vorgestellten View-Controller, um es für sich selbst aufzurufen. Hier ist ein vollständiges Beispiel.

Delegierte

In der Frage des OP ging es darum, wie komplex es ist, Delegierte zur Ablehnung einer Ansicht zu verwenden. 

Bis jetzt habe ich keine Delegaten benötigt, da ich normalerweise einen Navigationscontroller oder modale Ansichtscontroller habe. Wenn ich jedoch das Delegatemuster in der Zukunft verwenden muss, werde ich ein Update hinzufügen.

41
Suragch

Meiner Erfahrung nach ist es praktisch, wenn Sie es vonanyViewController entfernen möchten und verschiedene Aufgaben für jeden Viewcontroller ausführen müssen, der es abweist. Jeder viewController, der das Protokoll verwendet, kann die Ansicht auf seine eigene Weise verwerfen. (ipad vs iphone, oder Weitergabe unterschiedlicher Daten beim Abweisen aus verschiedenen Ansichten, Aufruf verschiedener Methoden beim Abbruch usw.)

Bearbeiten:

Um zu klären, wenn Sie nur die Ansicht abweisen möchten, sehe ich keine Notwendigkeit, das Delegiertenprotokoll festzulegen. Wenn Sie verschiedene Dinge tun müssen,, nachdemSie es von verschiedenen Präsentations-View-Controllern abweisen, ist dies der beste Weg, den Delegierten zu verwenden.

6
jhilgert00

versuche dies:

[self dismissViewControllerAnimated:true completion:nil];

Ein Punkt ist, dass dies ein guter Codierungsansatz ist. Es erfüllt viele OOP-Prinzipien, z. B. SRP, Trennung von Anliegen usw. 

Der View-Controller, der die View darstellt, sollte also derjenige sein, der sie abweist. 

Zum Beispiel sollte eine Immobilienfirma, die ein Haus zur Miete gibt, die Autorität sein, es zurückzunehmen.

Swift 3.0 // View Controller in Swift deaktivieren 

self.navigationController?.popViewController(animated: true)
dismiss(animated: true, completion: nil)
2
Pranit

Zitat aus View Controller-Programmierhandbuch , "Wie View Controller andere View Controller darstellen".

Jeder View-Controller in einer Kette von präsentierten View-Controllern verfügt über verweist auf die anderen Objekte in der Kette. In anderen Wörter, ein präsentierter View-Controller, der eine andere Ansicht darstellt Der Controller hat gültige Objekte in sowohl dem PresentingViewController als auch dem Eigenschaften von PresentViewController. Sie können diese Beziehungen zu .__ verwenden. Durchlaufen Sie die Kette der View-Controller nach Bedarf. Zum Beispiel wenn Wenn der Benutzer den aktuellen Vorgang abbricht, können Sie alle Objekte in .__ entfernen. die Kette, indem der zuerst präsentierte View-Controller entlassen wird . Beim Abweisen eines View-Controllers wird nicht nur dieser View-Controller aber auch beliebige Ansichtssteuerungen.

Auf der einen Seite sorgt dies für ein schönes ausgewogenes Design, eine gute Abkopplung usw. ... Aber auf der anderen Seite ist es sehr praktisch, da Sie schnell zu einem bestimmten Punkt in der Navigation zurückkehren können. 

Ich persönlich würde jedoch lieber Abwicklungssegmente verwenden, als zu versuchen, den Presenting Controller-Baum rückwärts zu durchqueren, über den Apple in diesem Kapitel spricht, von dem das Zitat stammt. 

2
svena

Neben der Antwort von Michael Enriquez fällt mir noch ein anderer Grund ein, warum dies ein guter Weg ist, sich vor einem unbestimmten Zustand zu schützen:

Sagen Sie, ViewControllerA präsentiert ViewControllerB modal. Da Sie den Code für ViewControllerA möglicherweise nicht geschrieben haben, kennen Sie den Lebenszyklus von ViewControllerA nicht. Es kann etwa 5 Sekunden nach Anzeige des View Controllers ViewControllerB absagen.

Wenn Sie in diesem Fall einfach dismissViewController von ViewControllerB verwenden, um sich selbst zu entlassen, befinden Sie sich in einem undefinierten Zustand - vielleicht kein Absturz oder schwarzer Bildschirm, sondern aus Ihrer Sicht ein undefinierter Zustand.

Wenn Sie stattdessen das Delegatenmuster verwenden, sind Sie über den Status von ViewControllerB informiert und können für einen Fall wie den von mir beschriebenen Fall programmieren.

1
Mayur

Schnell

let rootViewController:UIViewController = (UIApplication.shared.keyWindow?.rootViewController)!

        if (rootViewController.presentedViewController != nil) {
            rootViewController.dismiss(animated: true, completion: {
                //completion block.
            })
        }
0
Rishi Chaurasia

Wenn Sie modal verwenden, sehen Sie die Ansicht.

[self dismissViewControllerAnimated:NO completion:nil];
0
ErasmoOliveira

Sie können Ihr SuperView-Fenster schließen

self.view.superview?.window?.close()

0
MR.Code

Das ist viel Quatsch. Delegierung ist in Ordnung, wenn dies erforderlich ist, aber wenn der Code komplexer wird - und das ist der Fall -, muss es einen Grund dafür geben.

Ich bin mir sicher, dass Apple seine Gründe hat. Es ist jedoch klarer und prägnanter, den vorgelegten VC einfach zu entlassen, es sei denn, es gibt einen wahren Grund, etwas anderes zu tun, und niemand von heute hat einen präsentiert, den ich sehen kann. 

Protokolle eignen sich hervorragend, wenn sie benötigt werden. Bei objektorientiertem Design ging es jedoch nie darum, dass Module unnötig miteinander kommunizieren. 

Tom Love (Mitentwickler von Objective C) kommentierte einmal, dass Objective C "elegant", "klein", "knackig" und "klar" (im Vergleich zu C++) sei. Leicht für ihn zu sagen. Delegierung ist ein nützliches Feature, das "nur deshalb" überfordert war, und obwohl ich gerne in der Sprache arbeite, fürchte ich mich vor der Idee, dass Felling gezwungen ist, unnötige Syntax zu verwenden, um die Dinge komplexer zu gestalten, als sie sein müssen.

0