在 Swift 中关闭模态呈现的视图控制器后,如何重新加载 ViewController?
How can you reload a ViewController after dismissing a modally presented view controller in Swift?
我有第一个 tableViewController,它在单击单元格时打开第二个 tableViewcontroller。第二个视图控制器以模态方式呈现(Show Detail segue)并被关闭:
self.dismissViewControllerAnimated(true, completion: {})
此时,第二个视图控制器滑开并显示其下方的第一个视图控制器。然后我想重新加载第一个视图控制器。我知道这可能需要使用委托函数,但不确定具体如何实现它
您可以简单地重新加载 viewDidAppear:
中的数据,但这可能会导致 table 在某些情况下被不必要地刷新。
更灵活的解决方案是使用您猜对的协议。
假设您第一个 tableViewController 的 class 名字是 Table1VC
,第二个名字是 Table2VC
。您应该定义一个名为 Table2Delegate
的协议,它将包含一个方法,例如 table2WillDismissed
。
protocol Table2Delegate {
func table2WillDismissed()
}
那么你应该让你的 Table1VC
实例符合这个协议并在你的委托方法的实现中重新加载你的 table。
当然,为了让它工作,您应该添加一个 属性 到 Table2VC
来容纳代表:
weak var del: Table2Delegate?
并将其值设置为您的 Table1VC
实例。
设置委托后,只需在 Table2VC
实例中调用 dismissViewControllerAnimated
之前添加对委托方法的调用。
del?.table2WillDismissed()
self.dismissViewControllerAnimated(true, completion: {})
这将使您能够精确控制 table 何时重新加载。
我解决它的方式有点不同,因为我不想要这种依赖性。
这种方法适用于以模态方式呈现控制器,因为呈现的控制器不会在您关闭呈现的控制器时重新加载。
无论如何解决!
相反,你创建一个单例(中介)
protocol ModalTransitionListener {
func popoverDismissed()
}
class ModalTransitionMediator {
/* Singleton */
class var instance: ModalTransitionMediator {
struct Static {
static let instance: ModalTransitionMediator = ModalTransitionMediator()
}
return Static.instance
}
private var listener: ModalTransitionListener?
private init() {
}
func setListener(listener: ModalTransitionListener) {
self.listener = listener
}
func sendPopoverDismissed(modelChanged: Bool) {
listener?.popoverDismissed()
}
}
Presenting controller 是否实现了这样的协议:
class PresentingController: ModalTransitionListener {
//other code
func viewDidLoad() {
ModalTransitionMediator.instance.setListener(self)
}
//required delegate func
func popoverDismissed() {
self.navigationController?.dismissViewControllerAnimated(true, completion: nil)
yourTableViev.reloadData() (if you use tableview)
}
}
最后在您的 viewDid/WillDisappear 函数或自定义函数中的 PresentedViewController 中添加:
ModalTransitionMediator.instance.sendPopoverDismissed(true)
Swift 5:
您可以访问呈现 ViewController (presentingViewController) 属性 并在视图消失时使用它重新加载 table 视图。
class: FirstViewController {
var tableView: UITableView
present(SecondViewController(), animated: true, completion: nil)
}
在您的第二个视图控制器中,您可以在 viewWillDisappear 方法中添加以下代码:
class SecondViewController {
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let firstVC = presentingViewController as? FirstViewController {
DispatchQueue.main.async {
firstVC.tableView.reloadData()
}
}
}
}
当您关闭第二个ViewController 时,第一个ViewController 的table视图将重新加载。
我有第一个 tableViewController,它在单击单元格时打开第二个 tableViewcontroller。第二个视图控制器以模态方式呈现(Show Detail segue)并被关闭:
self.dismissViewControllerAnimated(true, completion: {})
此时,第二个视图控制器滑开并显示其下方的第一个视图控制器。然后我想重新加载第一个视图控制器。我知道这可能需要使用委托函数,但不确定具体如何实现它
您可以简单地重新加载 viewDidAppear:
中的数据,但这可能会导致 table 在某些情况下被不必要地刷新。
更灵活的解决方案是使用您猜对的协议。
假设您第一个 tableViewController 的 class 名字是 Table1VC
,第二个名字是 Table2VC
。您应该定义一个名为 Table2Delegate
的协议,它将包含一个方法,例如 table2WillDismissed
。
protocol Table2Delegate {
func table2WillDismissed()
}
那么你应该让你的 Table1VC
实例符合这个协议并在你的委托方法的实现中重新加载你的 table。
当然,为了让它工作,您应该添加一个 属性 到 Table2VC
来容纳代表:
weak var del: Table2Delegate?
并将其值设置为您的 Table1VC
实例。
设置委托后,只需在 Table2VC
实例中调用 dismissViewControllerAnimated
之前添加对委托方法的调用。
del?.table2WillDismissed()
self.dismissViewControllerAnimated(true, completion: {})
这将使您能够精确控制 table 何时重新加载。
我解决它的方式有点不同,因为我不想要这种依赖性。
这种方法适用于以模态方式呈现控制器,因为呈现的控制器不会在您关闭呈现的控制器时重新加载。
无论如何解决!
相反,你创建一个单例(中介)
protocol ModalTransitionListener {
func popoverDismissed()
}
class ModalTransitionMediator {
/* Singleton */
class var instance: ModalTransitionMediator {
struct Static {
static let instance: ModalTransitionMediator = ModalTransitionMediator()
}
return Static.instance
}
private var listener: ModalTransitionListener?
private init() {
}
func setListener(listener: ModalTransitionListener) {
self.listener = listener
}
func sendPopoverDismissed(modelChanged: Bool) {
listener?.popoverDismissed()
}
}
Presenting controller 是否实现了这样的协议:
class PresentingController: ModalTransitionListener {
//other code
func viewDidLoad() {
ModalTransitionMediator.instance.setListener(self)
}
//required delegate func
func popoverDismissed() {
self.navigationController?.dismissViewControllerAnimated(true, completion: nil)
yourTableViev.reloadData() (if you use tableview)
}
}
最后在您的 viewDid/WillDisappear 函数或自定义函数中的 PresentedViewController 中添加:
ModalTransitionMediator.instance.sendPopoverDismissed(true)
Swift 5:
您可以访问呈现 ViewController (presentingViewController) 属性 并在视图消失时使用它重新加载 table 视图。
class: FirstViewController {
var tableView: UITableView
present(SecondViewController(), animated: true, completion: nil)
}
在您的第二个视图控制器中,您可以在 viewWillDisappear 方法中添加以下代码:
class SecondViewController {
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let firstVC = presentingViewController as? FirstViewController {
DispatchQueue.main.async {
firstVC.tableView.reloadData()
}
}
}
}
当您关闭第二个ViewController 时,第一个ViewController 的table视图将重新加载。