Свіфт програмно перейдіть до іншого контролера перегляду / сцени


83

Я використовую наступний код для програмного переходу до іншого ViewController. Це чудово працює, але це дещо, як приховує navigation bar. Як це виправити? (панель навігації створюється шляхом вбудовування ViewControllerв, navigation controllerякщо це важливо.)

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

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

Відповіді:


208

Стрімкий 5

За замовчуванням модальний стиль презентації - картка. Це показує попередній контролер перегляду у верхній частині і дозволяє користувачеві відкинути поданий контролер перегляду.

Щоб зберегти старий стиль, вам потрібно змінити контролер подання, який ви будете представляти таким чином:

newViewController.modalPresentationStyle = .fullScreen

Це однаково як для програмно створених контролерів, так і для створених розкадрувань.

Стрімкий 3

За допомогою програмно створеного контролера

Якщо ви хочете перейти до контролера, створеного програмно, виконайте такі дії:

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

За допомогою StoryBoard, створеного контролера

Якщо ви хочете перейти до контролера на StoryBoard з ідентифікатором "newViewController", зробіть наступне:

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

2
"як! NewViewController" не потрібен у варіанті розкадрування
Лаві Авігдор,

2
так, я знаю, що це необов’язково, але якщо ми покажемо, то стане зрозуміло, який контролер перегляду призначений для іншого розробника
jaiswal Rajan

4
Телефонуйте storyBoard.instantiateViewControllerі self.presentз основного ланцюжка, інакше у вас буде затримка у появі компонентів viewController
Алекс

2
Алекс, подивіться, розробник повинен зателефонувати йому з основного потоку, я щойно написав відповідь на запитання, задане вище. Ваш коментар до дзвінка з основного потоку тут не підходить.
jaiswal Rajan

Привіт, підглядає: як загальне правило, чи можу я запропонувати більш дружній тон? (Це досить проблематика тут, на SO). Натомість до теми: хоча це не задається безпосередньо ОП, я думаю, що ця хороша відповідь все ж є відповідним місцем, щоб пам’ятати (кожному, хто читає), що дія має відбуватися в основному потоці
superjos

32

SWIFT 4.x

Рядки в подвійних лапках мене завжди бентежать, тому я думаю, що для відповіді на це питання потрібна якась графічна презентація, щоб це зрозуміти.

Для банківської програми у мене є LoginViewController та BalanceViewController. У кожного є свої екрани.

Програма запускається та відображає екран входу. Після успішного входу програма відкриває екран Баланс.

Ось як це виглядає:

введіть тут опис зображення

введіть тут опис зображення

Успіх входу в систему обробляється так:

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

Як бачите, "баланс" ідентифікатора раскадровки малими літерами - це те, що міститься у другому рядку коду, і це ідентифікатор, який визначається в налаштуваннях розкадровки, як на скріншоті, що додається.

Термін "Баланс" із великим "B" - це назва файлу розкадровки , який використовується в першому рядку коду.

Ми знаємо, що використання жорстко закодованих рядків у коді є дуже поганою практикою, але якимось чином у розробці iOS це стало звичною практикою, і Xcode навіть не попереджає про них.


приголомшливі демонстрації
Еліас

1
Чувак ти чудовий!
OhhhThatVarun

16

Ви повинні натиснути на новий контролер перегляду, використовуючи поточний контролер навігації, який не присутній.

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

чому ми повинні наполягати, чи є якась користь?
DragonFire

1
@DragonFire, оскільки op хоче, щоб це працювало, не закриваючи панель навігації. якщо ви хочете мати головну детальну сторінку, наприклад, між екраном контактів WhatsApp та екраном чату, ви повинні мати pushконтролер перегляду з вашим контролером навігації. (це буде анімувати зліва направо), якщо ви просто хочете показати, представити, спливаюче вікно на поточному екрані (що буде анімувати знизу вгору), просто використовуйте present.
Okan Kocyigit

Дякую! Працює ласощі, зберігаючи вкладки мого навігаційного контролера тощо
David_2877

12

За словами @jaiswal Rajan у своїй відповіді . Ви можете зробити pushViewController таким чином:

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

1
Привіт, просто цікаво: навіщо повторювати вже розміщену відповідь? Можливо, коментар чи прихильність також були б нормальними. Або позаду є інші міркування?
superjos

Він представляє навігацію за допомогою NavigationController. Дякую.
Хіран Д.А. Валавадж

4

Отже, якщо ви представите контролер перегляду, він не відображатиметься в контролері навігації. Це займе всього екран. У цьому випадку вам потрібно створити інший контролер навігації та додати його nextViewControllerяк root для цього та представити новий навігаційний контролер .

Інший спосіб - просто натиснути на контролер перегляду.

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

Для отримання додаткової інформації перевірте документацію Apple: - https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/#//apple_ref/doc/uid/TP40006926-CH3-SW96


presentViewControllerбуло перейменовано на 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)
}

Це спрацювало для мене, коли я помістив код всередину OperationQueue.main.addOperation, який буде виконуватися в основному потоці для мене.


1

Наведений вище код працює добре, але якщо ви хочете перейти з NSObjectкласу, де ви не можете використовувати 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

Усі інші відповіді звучать добре, я хотів би висвітлити свою справу, де мені довелося зробити анімований LaunchScreen, а потім через 3-4 секунди анімації наступним завданням було перейти на головний екран. Я пробував серії, але це створило проблему для перегляду місця призначення. Тож наприкінці я отримав доступ до властивості Window AppDelegates і призначив йому новий екран 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

Якщо в корпусі, ви не хочете NaviController у поданні призначення, то просто призначте як,

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.