主UITabBarController

时间:2017-12-21 13:49:53

标签: ios swift

问题

如何正确地从深度嵌套的视图中更新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?.firstRunself.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中的变量/状态?

0 个答案:

没有答案