Linking child view controllers to a parent view controller within storyboard

后端 未结 5 1892

Can you associate child view controllers to a custom container view controller in Storyboard?

I can link child view controllers to a tab view controller, and I can l

5条回答
  •  囚心锁ツ
    2020-11-30 19:58

    The problem with @Ben's (otherwise reasonable) answer is that it only works at one level of nesting. Beyond that, it would required that every subsequent VC is customized to save the nesting view controller in prepareForSegue.

    To solve this, I spent too much time exploring an NSObject based index that that you could add to the Storyboard, bind to a scene, and which would then register it's parent VC in a global index, based on type and restorationId. That works / can work, but is too much effort in the end, and still requires the two step process of visually binding, and programmatically looking up.

    For me, the simplest and most general solution is to lazily descend the view controller hierarchy

    In my simple test project, I added the following lines to viewDidLoad:

        self.left.data = [
            "Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro.",
            "De carne lumbering animata corpora quaeritis." ]
    

    where left is defined as:

    lazy var left:CollectionViewController = { [unowned self] in
        return self.childViewControllerWithId("Left") as! CollectionViewController }()
    

    and childViewControllerWithId is defined as:

    extension UIViewController {
        func childViewControllerWithId(rid:String) -> UIViewController? {
    
            // check immediate child controllers
            for vc in self.childViewControllers as! [UIViewController] {
                if vc.restorationIdentifier == rid { return vc }
            }
    
            // check nested controllers
            for vc in self.childViewControllers as! [UIViewController] {
                if let vc = vc.childViewControllerWithId(rid) {
                    return vc
                }
            }
    
            assert(false, "check your assumptions")
            return nil
        }
    }
    

    Note that you could do other find variants based on type, if need be. Also note that the above requires that you define the restoration id in the Storyboard file. If you did not have repeated instances of the same view controller, then using type would be easier.

    And to state what is hopefully obvious, you don't need to implement prepareForSegue, nor do you have to use the lazy loading, you just have to call find(...).

提交回复
热议问题