如何正确地从深度嵌套的视图中更新UITabBarController中的变量/状态而不需要噩梦般的委托链?
我的应用程序设置了一个主UITabBarController,它包含许多UINavigationControllers(每个选项卡一个),然后可以容纳各种其他视图控制器(它可以像UITableViewController中的单元格中的自定义控件一样深)。我没有使用IB - 它都是以编程方式创建的。
在任何给定时间(例如)它基本上都是这样的:
MainTabBarViewController
-> UINavigationController
-> CancelOnboardingButton (UIBarButtonItem) // should update variable
-> PackagesOverviewViewController (UIPageViewController)
-> PackagesListTableViewController (UITableViewController)
-> PackagesListItemTableViewCell (UITableViewCell)
-> CompleteOnboardingButton (UIButton) // should update variable
在我的自定义UITabBarController(类:MainTabBarController)中,我有一个变量,应该根据用户是否已完成对该包的激活来切换为选项卡设置的UINavigationControllers。因此,如果用户点击CompleteOnboardingButton
按钮,MainTabBarViewController
中的变量会更新(见下文),则标签栏会发生变化,生活也会很好。
当然,MainTabBarController不了解UIButton,并且各种动作可能会更新MainTabBarController变量(例如,最后点击按钮,整个点击取消按钮等)。
class MainTabBarViewController: UITabBarController, UITabBarControllerDelegate {
var firstRun : Bool = true
...
func goToProgram(_ programID: String){
if firstRun {
// First present the onboarding screens
// At the end, these should update firstRun to false
} else {
setViewControllers([array_of_tabs], animated: true)
}
}
}
我尝试了一些解决方案,例如self.tabBarController?.firstRun
和self.navigationController?.tabBarController.firstRun
,这些解决方案(a)使我的应用程序崩溃,(b)要求我的自定义按钮知道 他们是(这是不可取的)。
我做过这样的事情:
let vc : MainTabBarViewController = MainTabBarViewController()
vc.firstRun = false
...但我不认为和之上的理由是正确的,因为它创造了一个新的实例(我' m来自PHP背景,但我猜这里的想法是一样的吗?)
我已经尝试.addTarget(nil, action: #selector(someSelector), for: .touchUpInside)
让它冒出来了,但是XCode抱怨someSelector
不在拿着按钮的班级中(我以为我可以添加{{} 1}} someSelector
中的函数,它会在那里捕获它。)
我可以使用MainTabBarViewController
,但这需要我的NotificationCenter
知道按钮存在才能收听(因此我没有开放的观察员)。
当然,我必须相信,在没有通过每个视图控制器添加代理和协议的情况下,在视图链上传递状态/操作的更简单方法。
我在这里缺少什么?如何从深层嵌套的视图中正确更新UITabBarController中的变量/状态?