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.