Szybko programowo przejdź do innego kontrolera widoku / sceny


83

Używam następującego kodu, aby programowo przejść do innego ViewController. Działa dobrze, ale w pewnym sensie ukrywa plik navigation bar. Jak to naprawić? (pasek nawigacji jest tworzony przez zagłębienie się ViewControllerw, navigation controllerjeśli ma to znaczenie).

let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)

let nextViewController = storyBoard.instantiateViewControllerWithIdentifier("nextView") as NextViewController
self.presentViewController(nextViewController, animated:true, completion:nil)

Odpowiedzi:


208

Szybki 5

Domyślnym stylem prezentacji modalnej jest karta. Pokazuje poprzedni kontroler widoku u góry i pozwala użytkownikowi odsunąć prezentowany kontroler widoku.

Aby zachować stary styl, musisz zmodyfikować kontroler widoku, który będziesz prezentować w następujący sposób:

newViewController.modalPresentationStyle = .fullScreen

To samo dotyczy zarówno kontrolerów tworzonych programowo, jak i kontrolerów tworzonych w scenorysach.

Szybki 3

Za pomocą programowo utworzonego kontrolera

Jeśli chcesz przejść do kontrolera utworzonego programowo, wykonaj następujące czynności:

let newViewController = NewViewController()
self.navigationController?.pushViewController(newViewController, animated: true)

Za pomocą kontrolera stworzonego przez StoryBoard

Jeśli chcesz przejść do kontrolera na StoryBoard z identyfikatorem „newViewController”, zrób to:

let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "newViewController") as! NewViewController
        self.present(newViewController, animated: true, completion: nil)

2
„as! NewViewController” nie jest potrzebne w opcji scenorysu
Lavi Avigdor

2
tak, wiem, że jest to opcjonalne, ale jeśli pokażemy, stanie się jasne, który
kontroler

4
Zadzwoń storyBoard.instantiateViewControlleri self.presentz głównego wątku, albo będziesz miał opóźnienie w pojawieniu się komponentów viewController
Alex

2
@Alex look, wywołanie tego z głównego wątku należy do programistów, właśnie napisałem odpowiedź na zadane powyżej pytanie. Twój komentarz do wywołania z głównego wątku nie jest tutaj odpowiedni.
jaiswal Rajan

Cześć ludzie: co do zasady, czy mogę zaproponować bardziej przyjazny ton? (To jest dość problem tutaj w SO) Zamiast tego do tematu: chociaż OP nie zadaje tego bezpośrednio, myślę, że ta dobra odpowiedź jest nadal odpowiednim miejscem do zapamiętania (dla każdego czytającego), że akcja musi się wydarzyć w głównym wątku
superjos

32

SWIFT 4.x

Ciągi w podwójnych cudzysłowach zawsze mnie mylą, więc myślę, że odpowiedź na to pytanie wymaga graficznej prezentacji, aby to wyjaśnić.

W przypadku aplikacji bankowej mam LoginViewController i BalanceViewController. Każdy ma swoje ekrany.

Aplikacja uruchamia się i wyświetla ekran logowania. Po pomyślnym zalogowaniu aplikacja otwiera ekran Salda.

Oto jak to wygląda:

wprowadź opis obrazu tutaj

wprowadź opis obrazu tutaj

Sukces logowania jest obsługiwany w następujący sposób:

let storyBoard: UIStoryboard = UIStoryboard(name: "Balance", bundle: nil)
let balanceViewController = storyBoard.instantiateViewController(withIdentifier: "balance") as! BalanceViewController
self.present(balanceViewController, animated: true, completion: nil)

Jak widać, „saldo” serii ujęć małymi literami znajduje się w drugiej linii kodu, a jest to identyfikator zdefiniowany w ustawieniach scenorysu, jak na załączonym zrzucie ekranu.

Termin „Saldo” przez duże „B” to nazwa pliku storyboardu , który jest używany w pierwszym wierszu kodu.

Wiemy, że używanie ciągów znaków zakodowanych na stałe w kodzie jest bardzo złą praktyką, ale w jakiś sposób w programowaniu na iOS stało się powszechną praktyką, a Xcode nawet o nich nie ostrzega.


niesamowite pokazy
Elias Fazel

1
Koleś, jesteś niesamowity!
OhhhThatVarun

16

Należy wypchnąć nowy kontroler widoku przy użyciu bieżącego kontrolera nawigacji, który nie jest obecny.

self.navigationController.pushViewController(nextViewController, animated: true)

dlaczego powinniśmy naciskać, czy jest jakaś korzyść?
DragonFire,

1
@DragonFire, bo op chce, żeby działał bez zasłaniania paska nawigacji. jeśli chcesz mieć projekt strony ze szczegółami wzorcowymi, na przykład między ekranem kontaktów WhatsApp a ekranem czatu, musisz pushużyć kontrolera widoku z kontrolerem nawigacji. (który będzie animowany od lewej do prawej), jeśli chcesz tylko pokazać, przedstawić, wyskakujące okienko na bieżącym ekranie (które będzie animowane od dołu do góry), po prostu użyj present.
Okan Kocyigit,

Dziękuję Ci! Działa
świetnie,

12

Według @jaiswal Rajan w jego odpowiedzi . Możesz zrobić pushViewController w ten sposób:

let storyBoard: UIStoryboard = UIStoryboard(name: "NewBotStoryboard", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "NewViewController") as! NewViewController
self.navigationController?.pushViewController(newViewController, animated: true)

1
Cześć, tylko się zastanawiam: po co powtarzać już opublikowaną odpowiedź? Może komentarz lub upvote też byłby w porządku. Czy są jakieś dalsze powody?
superjos

Prezentuje, aby nawigować za pomocą NavigationController. Dziękuję Ci.
Hiran DA Walawage

4

Więc jeśli przedstawisz kontroler widoku, nie pojawi się on w kontrolerze nawigacji. Zajmie to tylko cały ekran. W tym przypadku musisz utworzyć inny kontroler nawigacji i dodać swój nextViewControllerjako root do tego i przedstawić ten nowy navigationController.

Innym sposobem jest po prostu naciśnięcie kontrolera widoku.

self.presentViewController(nextViewController, animated:true, completion:nil)

Więcej informacji znajdziesz w dokumentacji Apple: - https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/#//apple_ref/doc/uid/TP40006926-CH3-SW96


presentViewControllerzostała zmieniona na present(loginController, animated:true, completion:nil)
kite_n_code

2
OperationQueue.main.addOperation {
   let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
   let newViewController = storyBoard.instantiateViewController(withIdentifier: "Storyboard ID") as! NewViewController
   self.present(newViewController, animated: true, completion: nil)
}

U mnie zadziałało, gdy umieściłem kod w środku OperationQueue.main.addOperation, który będzie wykonywany w głównym wątku.


1

Powyższy kod działa dobrze, ale jeśli chcesz nawigować z NSObjectklasy, na której nie możesz użyć self.present:

let storyBoard = UIStoryboard(name:"Main", bundle: nil)
if let conVC = storyBoard.instantiateViewController(withIdentifier: "SoundViewController") as? SoundViewController,
    let navController = UIApplication.shared.keyWindow?.rootViewController as? UINavigationController {
    
    navController.pushViewController(conVC, animated: true)
}

0

Wszystkie inne odpowiedzi brzmią dobrze, chciałbym opisać moją sprawę, w której musiałem zrobić animowany LaunchScreen, a następnie po 3 do 4 sekundach animacji kolejnym zadaniem było przejście do ekranu głównego. Próbowałem na segue, ale to stworzyło problem z widokiem celu. Na koniec uzyskałem dostęp do właściwości Window AppDelegates i przypisałem do niej nowy ekran NavigationController,

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let homeVC = storyboard.instantiateViewController(withIdentifier: "HomePageViewController") as! HomePageViewController

//Below's navigationController is useful if u want NavigationController in the destination View
let navigationController = UINavigationController(rootViewController: homeVC)
appDelegate.window!.rootViewController = navigationController

Jeśli tak, nie chcesz, aby navigationController w widoku docelowym, po prostu przypisz jako,

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let homeVC = storyboard.instantiateViewController(withIdentifier: "HomePageViewController") as! HomePageViewController
appDelegate.window!.rootViewController = homeVC
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.