Modal View Controller präsentieren und schließen

76

Kann mir jemand den Beispielcode geben, mit dem ich zuerst einen Modal View Controller präsentieren und dann schließen kann? Das habe ich versucht:

NSLog(@"%@", blue.modalViewController);
[blue presentModalViewController:red animated:YES];
NSLog(@"%@", blue.modalViewController);
[blue dismissModalViewControllerAnimated:YES];
NSLog(@"%@", blue.modalViewController);

Dieser Code befindet sich in viewDidLoad ("blau" und "rot" sind beide Unterklassen von UIViewController). Ich gehe davon aus, dass ich die rote Ansicht anzeigen und sie dann sofort mit einigen Animationen ausblenden werde. Dieser Code zeigt jedoch nur die modale Ansicht und schließt sie nicht ab. Irgendeine Idee? Das erste Protokoll zeigt "null", während die beiden anderen Protokolle anzeigen<RedViewController: 0x3d21bf0>

Ein weiterer Punkt ist, wenn ich diesen Code in applicationDidFinishLaunching einfüge: Die rote Ansicht wird überhaupt nicht angezeigt und alle Protokolle erhalten "null".

Phunehehe
quelle
Wie jemand unten sagt, presentModalViewController:animated:ist veraltet. Jetzt müssen Sie presentModalViewController:animated:completion:die folgenden Operationen im Abschlussblock verwenden und ausführen (wenn Sie warten möchten, bis sie redangezeigt werden). Lesen Sie auf jeden Fall den Artikel, den @MatterGoal vorschlägt: developer.apple.com/library/ios/#featuredarticles/… .
Ferran Maylinch

Antworten:

109

Wenn Sie diesen Code in applicationDidFinishLaunching einfügen, kann es zunächst vorkommen, dass vom Interface Builder instanziierte Controller noch nicht mit Ihrer Anwendung verknüpft sind (daher sind "rot" und "blau" immer noch vorhanden nil).

Um Ihre erste Frage zu beantworten, machen Sie falsch, dass Sie dismissModalViewControllerAnimated:den falschen Controller anrufen ! Es sollte so sein:

[blue presentModalViewController:red animated:YES];
[red dismissModalViewControllerAnimated:YES];

Normalerweise sollte der "rote" Controller beschließen, sich irgendwann zu entlassen (möglicherweise, wenn auf die Schaltfläche "Abbrechen" geklickt wird). Dann könnte der "rote" Controller die Methode aufrufen self:

[self dismissModalViewControllerAnimated:YES];

Wenn es immer noch nicht funktioniert, hat es möglicherweise etwas damit zu tun, dass der Controller animiert dargestellt wird, sodass Sie den Controller möglicherweise nicht so schnell nach dem Präsentieren schließen dürfen.

Tom van Zummeren
quelle
58
Laut dem View Controller-Programmierhandbuch für iPhone OS ist dies falsch, wenn Sie modale View Controller schließen, für die Sie die Delegierung verwenden sollten. Machen Sie sich also vor dem Präsentieren Ihrer Modalansicht zum Delegaten und rufen Sie den Delegierten vom Modalansichts-Controller an, um ihn zu schließen.
Oscar Gomez
1
Denken Sie daran, dass diese Art der Darstellung der modalen Ansicht seit io6 abgeschrieben wird. Verwendung: [self presentViewController: animiert: Vervollständigung:]; stattdessen
simon_smiley
5
@OscarGomez Nein, das View Controller-Programmierhandbuch sagt nicht, dass dieser Ansatz falsch ist. Es heißt jedoch, dass der von Ihnen vorgeschlagene Ansatz der „bevorzugte Ansatz“ ist. Mit anderen Worten, während Ihr Ansatz in vielen Situationen funktioniert, ist er nicht der einzige Ansatz, sondern der, den Sie zuerst ausprobieren sollten. Ich schlage vor, Sie fügen den Ansatz, den Sie zitieren, als zusätzliche Antwort hinzu, da es mehrere brauchbare Antworten auf eine Frage wie diese gibt und Ihre für einige Leser möglicherweise besser ist.
Slipp D. Thompson
4
[self dismissModalViewControllerAnimated:YES];ist veraltet
alternatiph
Was ist der Unterschied zwischen Aufruf dismissModalViewControllerAnimatedan redoder blue? Aus den Dokumenten geht hervor, dass wir es anrufen sollten blue(die präsentierende VC) ...
Ferran Maylinch
18

Schnell

Aktualisiert für Swift 3

Geben Sie hier die Bildbeschreibung ein

Storyboard

Erstellen Sie zwei View Controller mit jeweils einer Schaltfläche. Setzen Sie für den zweiten Ansichts-Controller den Klassennamen auf SecondViewControllerund die Storyboard-ID auf secondVC.

Code

ViewController.swift

import UIKit
class ViewController: UIViewController {

    @IBAction func presentButtonTapped(_ sender: UIButton) {
        
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let myModalViewController = storyboard.instantiateViewController(withIdentifier: "secondVC")
        myModalViewController.modalPresentationStyle = UIModalPresentationStyle.fullScreen
        myModalViewController.modalTransitionStyle = UIModalTransitionStyle.coverVertical
        self.present(myModalViewController, animated: true, completion: nil)
    }
}

SecondViewController.swift

import UIKit
class SecondViewController: UIViewController {
    
    @IBAction func dismissButtonTapped(_ sender: UIButton) {
        self.dismiss(animated: true, completion: nil)
    }
}

Quelle:

Suragch
quelle
13

Der einfachste Weg, den ich in xcode 4.52 müde war, bestand darin, eine zusätzliche Ansicht zu erstellen und sie mit segue modal zu verbinden (Steuerung ziehen Sie die Schaltfläche von Ansicht eins in die zweite Ansicht, wählen Sie Modal). Ziehen Sie dann eine Schaltfläche in die zweite Ansicht oder die von Ihnen erstellte modale Ansicht. Steuern und ziehen Sie diese Schaltfläche in die Header-Datei und verwenden Sie die Aktionsverbindung. Dadurch wird eine IBaction in Ihrer controller.m-Datei erstellt. Finden Sie Ihren Schaltflächenaktionstyp im Code.

[self dismissViewControllerAnimated:YES completion:nil];
max
quelle
Beachten Sie, dass diese automatisch leitet die Nachricht an self.presentingViewController(nach der UIViewController Dokumentation) so für Klarheit ist es besser, rufen Sie an[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
Hatchmaster J
9

presentModalViewController:

MainViewController *mainViewController=[[MainViewController alloc]init];
[self.navigationController presentModalViewController:mainViewController animated:YES];

entlassenModalViewController:

[self dismissModalViewControllerAnimated:YES];
Jerry Thomsan
quelle
3

Der einfachste Weg, dies zu tun, ist die Verwendung von Storyboard und einem Segue.

Erstellen Sie einfach einen Segue vom FirstViewController (nicht vom Navigationscontroller) Ihres TabBarControllers zu einem LoginViewController mit der Login-Benutzeroberfläche und nennen Sie ihn "showLogin".

Erstellen Sie eine Methode, die ein BOOL zurückgibt, um zu überprüfen, ob der angemeldete Benutzer und / oder seine Sitzung gültig ist ... vorzugsweise im AppDelegate. Nennen Sie es isSessionValid.

Überschreiben Sie auf Ihrem FirstViewController.m die Methode viewDidAppear wie folgt:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    if([self isSessionValid]==NO){
        [self performSegueWithIdentifier:@"showLogin" sender:self];
    }
}

Wenn sich der Benutzer erfolgreich angemeldet hat, schließen Sie einfach den LoginViewController oder öffnen Sie ihn, um Ihre Registerkarten anzuzeigen.

Funktioniert 100%!

Ich hoffe es hilft!

Oscar Salguero
quelle
3

Schnell

self.dismissViewControllerAnimated(true, completion: nil)

Michael
quelle