Подтвердить что ты не робот

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.

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

4b9b3361

Ответ 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
})