如何在关闭模态 Viewcontroller 后更新父视图 Viewcontroller

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

我有一个UIBarButtonItem,我想从模态viewController的值更新,当它是dismissed.At时我只能通过获取当前可见viewController 这是我不想要的。有没有一种方法可以在关闭模态后更新父 viewController。

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)
       }
   }
}

这是编辑后关闭的模态

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
            }
        }    
    }
}

我认为您应该在模态控制器实例中存储对父控制器的引用。您可以使用协议使其更通用。声明以下 protocol:

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

AnyObject 需要将对 AccountButtonProvider 的引用声明为 weak。我猜你会需要它来避免内存泄漏。

使HomeViewController符合AccountButtonProvider:

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

然后将下面的属性添加到EditUserAccountViewController:

weak var accountButtonProvider: AccountButtonProvider?

在展示 EditUserAccountViewController 之前初始化此 属性。为此,将 editUserAccountVC.accountButtonProvider = self 添加到 accountButton(_:):

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

你还应该修改saveButton(_:):

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

此 post 中的所有代码均已在 Xcode 10.2.1 中测试。我用了 Swift 5.

您可以使用closure来解决您的问题陈述。

1.EditUserAccountViewController

中创建一个closure
var handler: ((String?)->())?

2.EditUserAccountViewControllerHomeViewController

呈现时设置这个closure的值
controller.handler = {(name) in
    self.accountButton.title = name
}

3. 当按下 saveButton

EditUserAccountViewController 消失时调用 closure
self.dismiss(animated: true) {
    self.handler?(self.firstName)
}

编译后的代码:

class HomeViewController: UIViewController {
    @IBOutlet weak var accountButton: UIBarButtonItem!

    @IBAction func openEditUserAccountVC(_ sender: Any) {
        if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "EditUserAccountViewController") as? EditUserAccountViewController {
            controller.handler = {(name) in
                self.accountButton.title = name
            }
            self.present(controller, animated: true, completion: nil)
        }
    }
}

class EditUserAccountViewController: UIViewController {
    var firstName: String?
    var handler: ((String?)->())?

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

只需使用委托设计模式。它简单易懂。