dispatch event to parent ViewController in swift

前端 未结 2 550
感情败类
感情败类 2021-02-04 08:07

I\'m coming from as AS3 background so it might be easier for me to show you what I\'m trying to do with AS3. I have a UIViewController(root) and inside that I have a ContainerV

相关标签:
2条回答
  • 2021-02-04 08:42

    Well or you can use static variables, which is probably the most straightforward way.

    class ParentViewController: UIViewController {
    
        static var instance:ParentViewController?
    
        override func awakeFromNib() {
            self.dynamicType.instance = self
        }
    
        func parentFunction() {
            print("called \(#function) in \(self.dynamicType)")
        }
    }
    
    class ChildViewController: UIViewController {
        func childFunction() {
            ParentViewController.instance?.parentFunction()
        }
    
        override func viewDidAppear(_ animated: Bool) {
            childFunction()
        }
    }
    
    0 讨论(0)
  • 2021-02-04 08:48

    There are two ways:

    1) Use a delegate protocol (recommended)

    a) In your child, create a delegate protocol, and an optional property on the child VC that will hold the delegate.

    protocol ChildViewControllerDelegate {
    
    }
    
    class ChildViewController: UIViewController {
    
        var delegate:ChildViewControllerDelegate?
    }
    

    b) In the delegate protocol create a method that will be called when the button was pressed, and implement a buttonWasPressed() method in the child that calls this method on the delegate. (You'll want to connect this method up with a button in the storyboard)

    protocol ChildViewControllerDelegate {
        func childViewControllerDidPressButton(childViewController:ChildViewController)
    }
    
    class ChildViewController: UIViewController {
    
        var delegate:ChildViewControllerDelegate?
    
        @IBOutlet weak var button: UIButton!
    
        @IBAction func buttonWasPressed(sender: AnyObject) {
            self.delegate?.childViewControllerDidPressButton(self)
        }
    }
    

    c) Make your parent view controller conform to the child protocol

    class ParentViewController: UIViewController, ChildViewControllerDelegate {
    
        func childViewControllerDidPressButton(childViewController: ChildViewController) {
            // Do fun handling of child button presses!
        }
    }
    

    c) When the child is embedded in the parent a special kind of segue is run called an embed segue. You can see it in the storyboard - it’s the line that connects the child to the parent:

    shows the embed segue selected

    Add an identifier to that segue in the storyboard:

    shows the settings for embed segue, with the custom identifier set

    And a constant for it in the parent view controller:

    struct Constants {
        static let embedSegue = "embedSegue"
    }
    
    class ParentViewController: UIViewController, ChildViewControllerDelegate {
    
        func childViewControllerDidPressButton(childViewController: ChildViewController) {
            // Do fun handling of child button presses!
        }
    }
    

    d) Then in the parent view controller, override the prepareForSegue() method and check if segue.identifier matches what you had set as the identifier. If it does, then you can get a reference to the child view controller through segue.destinationViewController. Cast this as your child view controller, then you can set the parent to be its delegate:

    struct Constants {
        static let embedSegue = "embedSegue"
    }
    
    class ParentViewController: UIViewController, ChildViewControllerDelegate {
    
        override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
            if segue.identifier == Constants.embedSegue {
                let childViewController = segue.destinationViewController as ChildViewController
                childViewController.delegate = self
            }
        }
    
        func childViewControllerDidPressButton(childViewController: ChildViewController) {
            // Do fun handling of child button presses!
        }
    }
    

    e) Win!

    2) Use NSNotification and NSNotificationCenter

    You can think of these as similar to ActionScript events, however they don’t automatically bubble up through the view hierarchy like AS. Instead notifications are dispatched globally through NSNotificationCenter. I prefer to only use this when there are multiple objects that need to listen for one particular event.

    You can find more information about NSNotification and NSNotificationCenter here: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/

    0 讨论(0)
提交回复
热议问题