当呈现的视图控制器被手势关闭时如何得到通知?
How to get notified when a presented view controller is dismissed with a gesture?
在某些情况下(iPhone X,iOS 13)可以通过从顶部拉动手势来关闭呈现的视图控制器。
在那种情况下,我似乎找不到通知呈现视图控制器的方法。我错过了什么吗?
我发现的唯一方法是向呈现的视图控制器的 viewDidDisappear 添加委托方法。
类似于:
class Presenting: UIViewController, PresentedDelegate {
func someAction() {
let presented = Presented()
presented.delegate = self
present(presented, animated: true, completion: nil)
}
func presentedDidDismiss(_ presented: Presented) {
// Presented was dismissed
}
}
protocol PresentedDelegate: AnyObject {
func presentedDidDismiss(_ presented: Presented)
}
class Presented: UIViewController {
weak var delegate: PresentedDelegate?
override func viewDidDisappear(animated: Bool) {
...
delegate?.presentedDidDismiss(self)
}
}
也可以使用 vc 子类通过通知来管理它,但仍然不能令人满意。
extension Notification.Name {
static let viewControllerDidDisappear = Notification.Name("UIViewController.viewControllerDidDisappear")
}
open class NotifyingViewController: UIViewController {
override open func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NotificationCenter.default.post(name: .viewControllerDidDisappear, object: self)
}
}
一定有更好的方法吗?
采用UIAdaptivePresentationControllerDelegate
并实施presentationControllerDidAttemptToDismiss
(iOS 13+)
extension Presenting : UIAdaptivePresentationControllerDelegate {
func presentationControllerDidAttemptToDismiss(_ presentationController: UIPresentationController) {
presentationController.presentingViewController.presentedDidDismiss(self)
}
}
UIPresentationController
有一个 属性 presentingViewController
。这个名字是不言自明的。您不需要显式委托协议。
实际调用该方法是为了能够显示一个对话框,例如在关闭控制器之前保存更改。您还可以实施 presentationControllerDidDismiss()
并且不要 post 向彼此相关的控制器发送通知。这是不好的做法。
来自 iOS13 Apple 为用户引入了一种新方法 dismiss
通过从顶部向下拉呈现的视图控制器。可以通过将 UIAdaptivePresentationControllerDelegate
实现到您正在呈现的 UIViewController
来捕获此事件,在本例中为 Presenting
控制器。然后您可以在方法 presentationControllerDidDismiss
中收到有关此事件的通知。这是代码示例:-
class Presenting: UIViewController, UIAdaptivePresentationControllerDelegate {
func someAction() {
let presented = Presented()
presented.presentationController?.delegate = self
present(presented, animated: true, completion: nil)
}
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
// Only called when the sheet is dismissed by DRAGGING.
// You'll need something extra if you call .dismiss() on the child.
// (I found that overriding dismiss in the child and calling
// presentationController.delegate?.presentationControllerDidDismiss
// works well).
}
}
注:
- 此方法仅在通过从顶部滑动而关闭时触发,而不是程序化
dismiss(animated:,completion:)
方法。
- 您不需要任何自定义委托或
Notification
观察器来获取用户通过向下滑动关闭控制器的事件,因此您可以删除它们。
在某些情况下(iPhone X,iOS 13)可以通过从顶部拉动手势来关闭呈现的视图控制器。
在那种情况下,我似乎找不到通知呈现视图控制器的方法。我错过了什么吗?
我发现的唯一方法是向呈现的视图控制器的 viewDidDisappear 添加委托方法。
类似于:
class Presenting: UIViewController, PresentedDelegate {
func someAction() {
let presented = Presented()
presented.delegate = self
present(presented, animated: true, completion: nil)
}
func presentedDidDismiss(_ presented: Presented) {
// Presented was dismissed
}
}
protocol PresentedDelegate: AnyObject {
func presentedDidDismiss(_ presented: Presented)
}
class Presented: UIViewController {
weak var delegate: PresentedDelegate?
override func viewDidDisappear(animated: Bool) {
...
delegate?.presentedDidDismiss(self)
}
}
也可以使用 vc 子类通过通知来管理它,但仍然不能令人满意。
extension Notification.Name {
static let viewControllerDidDisappear = Notification.Name("UIViewController.viewControllerDidDisappear")
}
open class NotifyingViewController: UIViewController {
override open func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NotificationCenter.default.post(name: .viewControllerDidDisappear, object: self)
}
}
一定有更好的方法吗?
采用UIAdaptivePresentationControllerDelegate
并实施presentationControllerDidAttemptToDismiss
(iOS 13+)
extension Presenting : UIAdaptivePresentationControllerDelegate {
func presentationControllerDidAttemptToDismiss(_ presentationController: UIPresentationController) {
presentationController.presentingViewController.presentedDidDismiss(self)
}
}
UIPresentationController
有一个 属性 presentingViewController
。这个名字是不言自明的。您不需要显式委托协议。
实际调用该方法是为了能够显示一个对话框,例如在关闭控制器之前保存更改。您还可以实施 presentationControllerDidDismiss()
并且不要 post 向彼此相关的控制器发送通知。这是不好的做法。
来自 iOS13 Apple 为用户引入了一种新方法 dismiss
通过从顶部向下拉呈现的视图控制器。可以通过将 UIAdaptivePresentationControllerDelegate
实现到您正在呈现的 UIViewController
来捕获此事件,在本例中为 Presenting
控制器。然后您可以在方法 presentationControllerDidDismiss
中收到有关此事件的通知。这是代码示例:-
class Presenting: UIViewController, UIAdaptivePresentationControllerDelegate {
func someAction() {
let presented = Presented()
presented.presentationController?.delegate = self
present(presented, animated: true, completion: nil)
}
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
// Only called when the sheet is dismissed by DRAGGING.
// You'll need something extra if you call .dismiss() on the child.
// (I found that overriding dismiss in the child and calling
// presentationController.delegate?.presentationControllerDidDismiss
// works well).
}
}
注:
- 此方法仅在通过从顶部滑动而关闭时触发,而不是程序化
dismiss(animated:,completion:)
方法。 - 您不需要任何自定义委托或
Notification
观察器来获取用户通过向下滑动关闭控制器的事件,因此您可以删除它们。