【问题标题】:How to update View of parent Viewcontroller after a modal Viewcontroller is dimissed如何在模态视图控制器被解除后更新父视图控制器的视图
【发布时间】:2019-10-04 14:36:49
【问题描述】:

我有一个UIBarButtonItem,当它被解除时,我想从模态视图控制器的值进行更新。目前我只能通过获取我不想要的当前可见视图控制器来做到这一点。有没有办法在关闭模态视图后更新父视图控制器。

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

【问题讨论】:

  • 是使用协议(委托)

标签: ios swift uiviewcontroller uinavigationcontroller


【解决方案1】:

我认为您应该在模态控制器实例中存储对父控制器的引用。您可以使用协议使其更通用。声明如下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
    }
}

本文中的所有代码都在 Xcode 10.2.1 中进行了测试。我用的是 Swift 5。

【讨论】:

  • HomeViewController 是我要去的vc。我为什么要实例化它并呈现它?
  • @sk123 您能否在您提供EditUserAccountViewController 实例的位置添加代码?
【解决方案2】:

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

1.EditUserAccountViewController中创建一个closure

var handler: ((String?)->())?

2.EditUserAccountViewControllerHomeViewController呈现时,设置这个closure的值

controller.handler = {(name) in
    self.accountButton.title = name
}

3. 在按下saveButtonEditUserAccountViewController 被关闭时调用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)
        }
    }
}

【讨论】:

  • HomeViewController 是我要去的vc。我为什么要实例化它并呈现它?
  • 这只是解决问题的一种方法。你显然可以使用任何你想要的控制器。
  • 我只想更新 UIBarbuttonItem 一个 EditVC 被解除
  • 这就是上面代码中发生的事情。 HomeViewController 呈现EditUserAccountViewController 并将处理程序设置在EditUserAccountViewController 中,当EditUserAccountViewController 被解除时调用。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 2012-05-10
    • 1970-01-01
    • 1970-01-01
    • 2017-02-27
    • 2017-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多