新しいルートVCを設定することは可能でしょうか?
私のアプリは、ルートVCとなるテーブルビューを持つuinavigationコントローラーで初期化されます。
次に、テーブルビューから別のセグエをログインウィンドウに実行しています(モーダルモードで表示)その後ログインすると、redVC /アカウントページになります。ここでやりたいことは、赤い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として機能させることができます。
これを試してみてください
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
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
UINavigationControllerにはNSArrayであるviewControllersプロパティがあります。また、ビューコントローラーの独自のNSArrayに置き換えることができます。
これは、以下のサンプルコードに示すように実行できます。
let newViewController = self.storyboard?.instantiateViewControllerWithIdentifier("YourViewControllerollerID") as! YourViewController
let customViewControllersArray : NSArray = [newViewController]
self.navigationController?.viewControllers = customViewControllersArray as! [UIViewController]
この新しいルートビューコントローラーを表示する場合は、UINavigationControllerのpopToRootViewController()メソッドを呼び出すだけです。
self.navigationController?.popToRootViewControllerAnimated(true)
元の質問のコードスニペットを機能させるために、3行目に変更を加える必要がありました
let navigationController = self.navigationController!
新しいルートView Controllerの前にあるView Controllerの@IBActionでこのコードを使用しています。
元のコードを使用して、View Controllerに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)
Swift 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
次のコードを使用できます:
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)
新しいルートVCを設定することは可能ですか?
はい可能です。どのように行うかは、コンテキストに依存します...
私のアプリは、ルートVCとなるテーブルビューを持つuinavigationコントローラーで初期化されます。
実際には、一般に「ルートビューコントローラ」と呼ばれるものが2つあります。
UIWindow
には、書き込み可能なrootViewController
プロパティがあります。
UINavigationController
にはrootViewController
プロパティはありませんが、-initWithRootViewController:
という初期化子があります。 viewControllers
プロパティを設定することにより、navコントローラーの「ルート」View Controllerを設定できます。
ウィンドウのルートビューコントローラーを変更しようとしているようですが、表示するコードはnavコントローラーのviewControllers
プロパティのみを変更します。ウィンドウのrootViewController
プロパティを直接設定してみてください。ただし、そのアプローチをとると、Navigation Controllerもなくなることを理解してください。一方、ナビゲーションコントローラーを保持する場合は、現在のアプローチを使用します。
しかし、私はそれを機能させることはできません。そのため、画像内の赤いvcを新しいルートVCとして機能させることができます。
こちらの詳細情報が役立ちます。 「機能させられない」とはどういう意味ですか?何が起こり、何が起こると期待していますか?
ログインボタンをクリックすると、このコードを使用できます。
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var vc = mainStoryboard.instantiateViewControllerWithIdentifier("respectiveIdentifier") as ViewController
UIApplication.sharedApplication().keyWindow.rootViewController = vc
どのようにして、どこからredVCを発表していますか?
UINavigationControllerのルートビューコントローラーにすることで、ビューコントローラーをプッシュおよびポップすることができます。
self.navigationController?.viewControllers = [self];
スイフト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()
Swift 4.の場合。
AppDelegate.SwiftdidfinishedlaunchingWithOptionsメソッドのファイルに、次のコードを入力します。
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
}
それがうまくいくことを願っています。
いくつかのアニメーションで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
})
この回答は、新しいコントローラをインスタンス化および再構成することなく、現在のスタックのどこかから既存のViewControllerを使用する場合に適用されます。
ドキュメントには次のように書かれています:ルートビューコントローラーはウィンドウのコンテンツビューを提供します。このプロパティにView Controllerを割り当てると(プログラムまたはInterface Builderを使用して)、View Controllerのビューがウィンドウのコンテンツビューとしてインストールされます。新しいコンテンツビューは、ウィンドウサイズを追跡するように構成されており、ウィンドウサイズが変更されると変更されます。 ウィンドウに既存のビュー階層がある場合、新しいビューがインストールされる前に古いビューが削除されます。
ドキュメントが言っているように: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()
}
このコードを試すことができます
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
}
}
ルートとして設定するvcに移動したら、単にviewDidLoadを追加します。
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window?.rootViewController = self
*ベストプラクティスにより、上記のコードを実行しない場合、すでにルートであるかどうかを確認する必要があります。
Swift 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)
}
}