在不同的标签

时间:2015-09-22 12:30:09

标签: ios swift uiviewcontroller uinavigationcontroller uitabbarcontroller

更新 这段代码看起来像我想要的那样,但我很好奇现在这是一个不好的策略。

func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController) {
    print("pop view controller from tab bar")

    if tabBarController.selectedIndex == 2 {
        print("appdel detected index 2 tab")
        let navCont = viewController as! UINavigationController
        navCont.popToRootViewControllerAnimated(true)
    }
}

原始问题: 我有一些代码将删除另一个选项卡引用的数据。我想确保在[编辑记录VC]中执行此代码时,它将强制选项卡弹回到根视图,即使代码在其自己的选项卡上执行:

[ ---------------TAB BAR CONTROLLER ------------------ ]
  TAB 0              TAB 1         TAB 2           TAB 3
     |                 |              |              |
     |                 |              |              |
  [NAV CONTR 0]  [NAV CONTR 1]  [NAV CONTR 2]  [NAV CONTR 3]
                       |              |        
                       |              |  
                   [Table VC]      [Map VC]
                       \              /
                        \            /
                         \          /
                       [View Record VC]
                               |
                               |
                       [Edit Record VC]

在上图中,当我删除[Edit Record VC]中的记录时,我想将Nav Controller 1和Nav Controller 2弹出到第一个VC。我怎样才能做到这一点?我已经尝试过各种我能想到的方法,但代码并没有工作。

我想这样做的原因是因为如果NAV CONTR 2导航到[编辑记录VC]并删除记录,[查看记录VC]仍然会引用该记录,导致它指向已删除的对象。当我在删除后尝试打开NAV CONTR 2选项卡时,它会导致崩溃

3 个答案:

答案 0 :(得分:2)

对事件做出反应的多个对象听起来像是NSNotification的作业。

制作听取通知(resetToFirstController或其他内容)的导航控制器子类的NAV CONTR 1和NAV CONTR 2实例。将发布通知作为删除逻辑的一部分。

当每个控制器收到通知时,它会弹出到它的根...或者你选择的“安全”控制器。

答案 1 :(得分:1)

我想展示Phillip Mills的实际实现,我做的就像魅力一样。

首先请参阅NSNotification上的这篇文章,(NotificationCenter issue on Swift 3),这是对swift3语法的一个非常好的参考。

因此,在控制器中,您希望能够弹出到导航的根控制器,您需要添加以下函数,print是可选的,但是非常有用,因此您可以看到正在发生的事情。

    // MARK: - Notifications
    func resetToTopView(notification: NSNotification){
        _ = navigationController?.popToViewController(self, animated: true)
        print("poppedViewController for TABNAMEHERE Successfully!")
    }

接下来,您需要注册此功能,以便通知中心可以调用它。只需在同一控制器的viewDidLoad中添加以下NotificationCenter代码即可。

func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(self, selector: #selector(self.resetToTopView(notification:)), name: k_resetToTopViewForYourTabNotification, object: nil)
}

如果您没有在程序中为k_resetToTopViewForYourTabNotification设置常量,则上面的代码会出错。我通常在一个名为globals的地方创建一个文件,我将这些常量放在这里。

要定义它,就像这样。

let k_resetToTopViewForYourTabNotification = Notification.Name("resetToTopViewForYourTabNotification")

然后在另一个选项卡或代码中的任何其他位置,即使是另一个选项卡,如果要调用该函数将视图控制器弹回到根目录,只需调用此命令。 / p>

NotificationCenter.default.post(name: k_resetToTopViewForYourTabNotification, object: nil)

非常简单和漂亮:)。

答案 2 :(得分:0)

首例:要选择其他标签索引

guard let VCS = self.navigationController?.viewControllers else {return }
for controller in VCS {
    if controller.isKind(of: TabBarController.self) {
        let tabVC = controller as! TabBarController
        tabVC.selectedIndex = index . (Select any index for tab)
        self.navigationController?.popToRootViewController(animated: true)
    }
}

第二种情况::要访问RootViewController变量时

guard let VCS = self.navigationController?.viewControllers else {return }
for controller in VCS {
    if controller.isKind(of: TabBarController.self) {
        let tabVC = controller as! TabBarController
        //    tabVC.selectedIndex = 0 . //no need of this line if you want to access same tab where you have started your navigation
        let VCs = tabVC.selectedViewController as! MyViewController
        VCs.variableName = true . //access your variable
        self.navigationController?.popToRootViewController(animated: true)
    }
}