簡體   English   中英

push segue后使用導航堆棧刪除視圖控制器(使用Storyboard segues)

[英]Remove view controller from navigation stack after push segue (using Storyboard segues)

我的應用程序包含在UINavigationController 根視圖控制器A本質上是登錄視圖,其中用戶將輸入憑證,並且一旦成功將通過推送segue呈現簡檔視圖控制器B. 現在,用戶獲得B導航欄上的后退按鈕以導航回A。 我希望B現在成為導航堆棧上的根視圖控制器,有效地防止用戶在新的應用程序啟動之前回到A。

在使用push segue的同時處理此問題的正確方法是什么? 我應該在沒有segue的情況下執行B的演示並使用新的導航控制器有效地啟動B關閉嗎?

只需替換UIWindowrootViewController即可 controllerAcontrollerB可以是您想要的任何Viewcontroller類。

您可以使用一個簡單的UITableViewController作為Loginpage ,然后使用保存controllerBUINavigationController替換UIWindowrootViewController

[UIView transitionFromView:controllerA.view
                        toView:controllerB.view
                      duration:0.65f
                       options:(UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionCrossDissolve)
                    completion:^(BOOL finished){
                        delegate.window.rootViewController = controllerB;
                    }];

我知道這個問題有點老了,但是自己經歷了這個問題后,我終於找到了一個解決方案,我認為這個解決方案比接受的答案要好。

  1. 使登錄控制器成為導航控制器的根控制器。

  2. 登錄成功后,從導航控制器viewcontrollers數組中刪除登錄控制器,並附加應用程序的初始viewcontroller。

     if let navigationController = navigationController { var viewControllers = navigationController.viewControllers for (index, viewController) in viewControllers.enumerated() where viewController is LoginViewController { viewControllers.remove(at: index) } let storyBoard = UIStoryboard(name: "Main", bundle: Bundle.main) let initialViewController = storyBoard.instantiateViewController(withIdentifier: "InitialViewController") viewControllers.append(initialViewController) navigationController.setViewControllers(viewControllers, animated: true) } 
  3. 您唯一需要做的就是將以下行添加到初始viewcontroller的viewDidLoad中:

     navigationItem.hidesBackButton = true 

將動畫設置為true的setViewControllers方法負責處理您指定為需求的推送動畫。

編輯:

我已經創建了一個可以添加到登錄控制器的方法,這不僅適用於您希望登錄控制器顯示為應用程序中的第一個視圖控制器,而且還有以后的身份驗證失敗(過期的憑據等)和您以模態方式顯示登錄控制器:

    func authenticationDidSucceed() {
        // If the LoginController is in a navigation stack then
        // replace it with the initial viewcontroller of the app
        guard navigationController?.viewControllers.contains(self) ?? false else {
            // Else it must be presented modally, so dismiss it
            dismiss(animated: true, completion: nil)
            return
        }

        guard let navigationController = navigationController else { return }

        var viewControllers = navigationController.viewControllers

        if let index = viewControllers.index(of: self) {
            viewControllers.remove(at: index)
        }

        viewControllers.append(UIStoryboard(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "InitialViewController"))

        navigationController.setViewControllers(viewControllers, animated: true)
    }

請記住上面的第3步。

B應該包含在它自己的導航控制器中,因為A將不再可訪問。 你必須使用push segue以外的東西。 transitionWithView效果很好:

UINavigationController *newNavController;

[UIView transitionWithView:delegate.window
                  duration:0.5
                   options:UIViewAnimationOptionTransitionCrossDissolve
                animations:^
 {
     [delegate.window addSubview:newNavController.view];
 }
                completion:^(BOOL finished)
 {
     delegate.window.rootViewController = newNavController;
 }];

[delegate.window makeKeyAndVisible];

我用SEGUE從導航controller A導航到另一個controller B ,而我希望得到controller A deinitialized后推到controller B的話,我會說這是為了去除干凈,最簡單的方法controller AviewDidDisappear和把它取消初始化。

 final class A: UIViewController {

    override func viewDidDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        navigationController?.viewControllers.removeAll(where: { self === $0 })
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM