Swift ios установил новый контроллер корневого представления
Интересно, можно ли установить новый корень VC?
Мое приложение получает init с контроллером uinavigation, у которого представление таблицы является корневым VC.
Затем из представления таблицы я запускаю другой segue в окно входа в систему (присутствует модально). Если вы затем войдете в систему, вы попадете на страницу red VC/account. Теперь я хочу установить красный VC в качестве нового корневого VC приложения и удалить все базовые VC. Чтобы я мог отображать кнопку меню/значок вместо кнопки "Назад"
Я нашел это, но я не понимаю, как его использовать:
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
let yourViewController: ViewController = storyboard.instantiateViewControllerWithIdentifier("respectiveIdentifier") as! ViewController
let navigationController = self.window?.rootViewController as! UINavigationController
navigationController.setViewControllers([yourViewController], animated: true)
Но я не могу заставить его работать. Таким образом, можно сделать красный vc в картине действующим как новый корень VC.
![введите описание изображения здесь]()
Ответы
Ответ 1
Возможно, вам стоит попробовать это
let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
let redViewController = mainStoryBoard.instantiateViewControllerWithIdentifier("respectiveIdentifier") as! ViewController
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.window?.rootViewController = redViewController
Ответ 2
Обновление Swift 3: -
let testController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "testController") as! TestController
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window?.rootViewController = testController
Ответ 3
UINavigationController имеет свойство viewControllers, которое представляет собой NSArray, и вы можете заменить его собственным NSArray контроля viewlrs.
Это можно сделать как показано в приведенном ниже примере кода.
let newViewController = self.storyboard?.instantiateViewControllerWithIdentifier("YourViewControllerollerID") as! YourViewController
let customViewControllersArray : NSArray = [newViewController]
self.navigationController?.viewControllers = customViewControllersArray as! [UIViewController]
И если вы хотите показать этот новый контроллер корневого представления, вы можете просто вызвать метод UINavigationController popToRootViewController().
self.navigationController?.popToRootViewControllerAnimated(true)
Ответ 4
Чтобы получить фрагмент кода из исходного вопроса для работы, мне пришлось внести изменения в третью строку
let navigationController = self.navigationController!
Я использую этот код в @IBAction в контроллере представления, который предшествует новому контроллеру корневого представления.
Используя исходный код, я получал сообщение о том, что у моего контроллера просмотра не было члена с именем window
. Посмотрев documentation, я не смог найти свойство с именем window
. Мне интересно, был ли исходный блок кода выше предназначен для использования внутри файла UINavigationController
.
Вот блок целиком.
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
let todayViewController: TodaysFrequencyViewController = storyboard.instantiateViewControllerWithIdentifier("todaysFrequency") as! TodaysFrequencyViewController
let navigationController = self.navigationController!
navigationController.setViewControllers([todayViewControl ler], animated: true)
Ответ 5
Свифт 4 Ответ
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "YourViewController") as! YourViewController
let navigationController = UINavigationController(rootViewController: nextViewController)
let appdelegate = UIApplication.shared.delegate as! AppDelegate
appdelegate.window!.rootViewController = navigationController
Ответ 6
Интересно, можно ли установить новый корень VC?
Да, это возможно. Как вы это делаете, зависит от контекста...
Мое приложение получает init с контроллером uinavigation, у которого представление таблицы является корневым VC.
На самом деле есть две вещи, которые обычно называются "контроллером корневого представления":
-
UIWindow
имеет свойство rootViewController
, которое можно записать.
-
UINavigationController
не имеет свойства rootViewController
, но имеет инициализатор, называемый -initWithRootViewController:
. Вы можете установить контроллер контроллера "root" контроллера навигации, установив для него свойство viewControllers
.
Похоже, вы пытаетесь изменить контроллер представления корневого окна, но в коде, который вы показываете, изменяется только свойство nav controller viewControllers
. Попробуйте напрямую установить свойство rootViewController
окна. Поймите, однако, что если вы примете такой подход, то навигационный контроллер тоже уйдет. Если вы хотите сохранить навигационный контроллер, с другой стороны, пойдите с вашим текущим подходом.
Но я не могу заставить его работать. Таким образом, можно сделать красный vc в картине действующим как новый корень VC.
Дополнительная информация здесь была бы полезна. Что вы подразумеваете под "не может заставить его работать"? Что происходит и что вы ожидаете?
Ответ 7
Вы можете использовать этот бит кода:
let newViewController = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
let customViewControllersArray : NSArray = [newViewController]
self.navigationController?.viewControllers = customViewControllersArray as! [UIViewController]
self.navigationController?.pushViewController(newViewController, animated: true)
Ответ 8
Этот код можно использовать при нажатии кнопки входа в систему: -
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var vc = mainStoryboard.instantiateViewControllerWithIdentifier("respectiveIdentifier") as ViewController
UIApplication.sharedApplication().keyWindow.rootViewController = vc
Ответ 9
Как и откуда вы представляете redVC?
Вы можете сделать это контроллером корневого контроллера вашего UINavigationController, так что у вас все еще будет возможность нажимать и просматривать контроллеры просмотров.
self.navigationController?.viewControllers = [self];
Ответ 10
когда вы находитесь в vc, который хотите установить как root, просто добавьте в свой viewDidLoad:
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window?.rootViewController = self
* В соответствии с лучшей практикой вы должны проверить, является ли это уже корнем, если не выполнить вышеприведенный код.
Ответ 11
Свифт 3
Файл AppDelegate:
@IBAction func btnGoBack(_ sender: UIButton){
self.goToHomeVC()
}
func goToHomeVC(){
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier :"HomeVC") as! HomeVC
let navController = UINavigationController.init(rootViewController: viewController)
if let window = self.appDelegate.window, let rootViewController = window.rootViewController {
var currentController = rootViewController
while let presentedController = currentController.presentedViewController {
currentController = presentedController
}
currentController.present(navController, animated: true, completion: nil)
}
}
Ответ 12
Swift 4
let storyBoard = UIStoryboard(name: "Your_Storyboard_Name", bundle:Bundle.main)
self.window = UIWindow(frame: UIScreen.main.bounds)
let yourVc = storyBoard.instantiateViewController(withIdentifier: "YourIdentifier") as? YourViewController
if let window = window {
window.rootViewController = yourVc
}
self.window?.makeKeyAndVisible()
Ответ 13
Вы можете попробовать этот код
func switchRootViewController(rootViewController: UIViewController, animated: Bool, completion: (() -> Void)?) {
guard let window = UIApplication.shared.keyWindow else { return }
if animated {
UIView.transition(with: window, duration: 0.5, options: .transitionCrossDissolve, animations: {
let oldState: Bool = UIView.areAnimationsEnabled
UIView.setAnimationsEnabled(false)
window.rootViewController = rootViewController
UIView.setAnimationsEnabled(oldState)
}, completion: { (finished: Bool) -> () in
if (completion != nil) {
completion!()
}
})
} else {
window.rootViewController = rootViewController
}
}
Ответ 14
Ссылка на связанный вопрос
Этот ответ относится к использованию существующего ViewController из текущего стека без создания экземпляра и перенастройки нового контроллера.
Документация гласит: Контроллер корневого представления обеспечивает представление содержимого окна. Присвоение контроллера представления этому свойству (программно или с помощью Interface Builder) устанавливает представление контроллеров представления как представление содержимого окна. Новое представление содержимого настроено на отслеживание размера окна, изменяющегося при изменении размера окна. Если окно имеет существующую иерархию представлений, старые представления удаляются до установки новых.
Как сказано в документации: он удаляет все представления в стеке при обмене rootViewController. Неважно, что с контроллером. Поэтому удалите ViewController из стека, чтобы гарантировать, что его представление не будет удалено.
Это привело в моем случае к следующему решению:
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
guard let pageVC = self.onboardingDelegate as? OnboardingPageViewController else { return } // my current stack is in a pageViewController, it also is my delegate
let vc = self // holding myself
pageVC.subViewControllers.removeLast() // removing myself from the list
pageVC.setViewControllers([pageVC.subViewControllers[0]], direction: .forward, animated: false, completion: nil) // remove the current presented VC
appDelegate.window?.rootViewController = vc
vc.onboardingDelegate = nil
appDelegate.window?.makeKeyAndVisible()
}
Ответ 15
Для быстрой 4.0.
В файле AppDelegate.swift в методе didfinishedlaunchingWithOptions, поместите следующий код.
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
let rootVC = MainViewController() // your custom viewController. You can instantiate using nib too. UIViewController(nib name, bundle)
let navController = UINavigationController(rootViewController: rootVC) // Integrate navigation controller programmatically if you want
window?.rootViewController = navController
return true
}
Надеюсь, это будет хорошо работать.
Ответ 16
Если вам нужно установить rootViewController с некоторыми анимациями, вот код:
guard let window = UIApplication.shared.keyWindow else {
return
}
guard let rootViewController = window.rootViewController else {
return
}
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "MainTabbar")
vc.view.frame = rootViewController.view.frame
vc.view.layoutIfNeeded()
UIView.transition(with: window, duration: 0.3, options: .transitionCrossDissolve, animations: {
window.rootViewController = vc
}, completion: { completed in
// maybe do something here
})