Search code examples
iosswiftuiviewcontrolleruinavigationcontroller

How to update View of parent Viewcontroller after a modal Viewcontroller is dimissed


I have a UIBarButtonItem that i want to update from the value of a modal viewController when its been dismissed.At the moment i can only do it by getting the current visible viewController which is what i don't want. Is there a way i update the parent viewController after dismissing the modal one.

class HomeViewController: UIViewController {

    @IBOutlet weak var accountButton: UIBarButtonItem!

    override func viewWillAppear(_ pAnimated: Bool) {
        super.viewWillAppear(pAnimated)
        self.accountButton.title = User.current!.firstName
   }

@IBAction func accountButton(_ pSender: UIBarButtonItem) {
        let editUserAccountVC = UIStoryboard.fs_instantiateFromStoryboard("Main", identifier: "EditUserAccountViewController") as! EditUserAccountViewController
        let navVC = UINavigationController(rootViewController: editUserAccountVC)
        navVC.view.tintColor = self.view.tintColor
        self.present(navVC, animated: true)
       }
   }
}

This is the modal that is dismissed after editing

class EditUserAccountViewController: UIViewController {

    var firstName: String?

    @IBAction func saveButton(_ sender: Any) {
        self.dismiss(animated: true) {
            if let thePresentedViewController = self.presentingViewController as? HomeViewController {
                thePresentedViewController.accountButton.title = self.firstName
            }
        }    
    }
}

Solution

  • I think you should store a reference to the parent controller in the modal controller instance. You can made it more generic with protocols. Declare the following protocol:

    protocol AccountButtonProvider: AnyObject {
        var accountButtonTitle: String? { set get }
    }
    

    AnyObject is required to declare a reference to AccountButtonProvider as weak. I guess you will need it to avoid memory leaks.

    Make HomeViewController conform to AccountButtonProvider:

    extension HomeViewController: AccountButtonProvider {
        var accountButtonTitle: String? {
            set {
                accountButton.title = newValue
            }
            get {
                return accountButton.title
            }
        }
    }
    

    Then add the following property to EditUserAccountViewController:

    weak var accountButtonProvider: AccountButtonProvider?
    

    Initialise this property before you present EditUserAccountViewController. To do it add editUserAccountVC.accountButtonProvider = self to accountButton(_:):

    @IBAction func accountButton(_ pSender: UIBarButtonItem) {
        let editUserAccountVC = UIStoryboard.fs_instantiateFromStoryboard("Main", identifier: "EditUserAccountViewController") as! EditUserAccountViewController
        editUserAccountVC.accountButtonProvider = self
    }
    

    You should also modify saveButton(_:):

    @IBAction func saveButton(_ sender: Any) {
        self.dismiss(animated: true) {
            self.accountButtonProvider?.actionButtonTitle = self.firstName
        }
    }
    

    All code in this post was tested in Xcode 10.2.1. I used Swift 5.