简体   繁体   English

当通过手势关闭呈现的视图 controller 时如何获得通知?

[英]How to get notified when a presented view controller is dismissed with a gesture?

It is possible in some cases (iPhone X, iOS 13) to dismiss presented view controllers with a gesture, by pulling from the top.在某些情况下(iPhone X,iOS 13)可以通过从顶部拉动以手势关闭呈现的视图控制器。

In that case, I can't seem to find a way to notify the presenting view controller.在这种情况下,我似乎找不到通知呈现视图 controller 的方法。 Did I miss something?我错过了什么?

The only I found would be to add a delegate method to the viewDidDisappear of the presented view controller.我发现的唯一方法是将委托方法添加到呈现视图 controller 的 viewDidDisappear 中。

Something like:就像是:

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

It is also possible to manage this via notifications, using a vc subclass but it is still not satisfactory.也可以通过通知来管理它,使用 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)
    }
}

There must be a better way to do this?必须有更好的方法来做到这一点?

From iOS 13 Apple has introduced a new way for the users to dismiss the presented view controller by pulling it down from the top.从 iOS 13 开始,Apple 引入了一种新方法,用户可以通过从顶部拉下视图 controller 来dismiss呈现的视图。 This event can be captured by implementing the UIAdaptivePresentationControllerDelegate to the UIViewController you're presenting on, in this case, the Presenting controller.可以通过将UIViewController实现到您正在演示的UIAdaptivePresentationControllerDelegate来捕获此事件,在本例中为Presenting controller。 And then you can get notified about this event in the method presentationControllerDidDismiss .然后您可以在方法presentationControllerDidDismiss中获得有关此事件的通知。 Here is the code example:-这是代码示例:-

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

Note:笔记:

  1. This method only gets triggered for dismissing by swiping from the top and not for the programmatic dismiss(animated:,completion:) method.此方法仅会通过从顶部滑动来触发,而不是程序化的dismiss(animated:,completion:)方法。
  2. You don't need any custom delegate or Notification observer for getting the event where the user dismisses the controller by swiping down, so you can remove them.您不需要任何自定义委托或Notification观察者来获取用户通过向下滑动关闭 controller 的事件,因此您可以删除它们。

Adopt UIAdaptivePresentationControllerDelegate and implement presentationControllerDidAttemptToDismiss (iOS 13+)采用UIAdaptivePresentationControllerDelegate并实现presentationControllerDidAttemptToDismiss (iOS 13+)

extension Presenting : UIAdaptivePresentationControllerDelegate {

    func presentationControllerDidAttemptToDismiss(_ presentationController: UIPresentationController) {
       presentationController.presentingViewController.presentedDidDismiss(self)
    }
}

UIPresentationController has a property presentingViewController . UIPresentationController有一个属性presentingViewController The name is self-explanatory.这个名字是不言自明的。 You don't need the explicit delegate protocol.您不需要显式委托协议。

The method is actually called to be able to show a dialog for example to save changes before dismissing the controller.实际上调用该方法是为了能够显示一个对话框,例如在关闭 controller 之前保存更改。 You can also implement presentationControllerDidDismiss()您还可以实现presentationControllerDidDismiss()

And do not post notifications to controllers which are related to each other.并且不要向彼此相关的控制器发布通知。 That's bad practice.这是不好的做法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在关闭所显示的ViewController时获得通知 - Get notified when a presented ViewController is dismissed 关闭呈现的视图控制器时如何恢复焦点? - How to restore focus when presented view controller is dismissed? 检测何时关闭呈现的视图控制器 - Detect when a presented view controller is dismissed 模态显示/关闭视图控制器时通知? - Notification when view controller is presented modally/dismissed? 获取视图控制器中已关闭的PopupDialog的通知 - Get notified of dismissed PopupDialog in view controller 调用viewWillAppear时显示视图控制器的问题被解除 - Issue with calling viewWillAppear of presenting view controller when presented one is dismissed 为什么简单的模态视图控制器在显示和关闭时会滞后? - Why would a simple modal view controller lag when presented and dismissed? TabBarController viewDidAppear 在呈现的视图控制器关闭时未调用 - TabBarController viewDidAppear not called when presented view controller dismissed 知道何时使用手势关闭拆分视图控制器的主对象 - Know when split view controller's master is dismissed with a gesture 从主视图控制器知道何时解散了所提供的模态视图控制器? - Knowing from the main view controller when the presented modal view controller is dismissed?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM