簡體   English   中英

當通過手勢關閉呈現的視圖 controller 時如何獲得通知?

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

在某些情況下(iPhone X,iOS 13)可以通過從頂部拉動以手勢關閉呈現的視圖控制器。

在這種情況下,我似乎找不到通知呈現視圖 controller 的方法。 我錯過了什么?

我發現的唯一方法是將委托方法添加到呈現視圖 controller 的 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)
    }
}

必須有更好的方法來做到這一點?

從 iOS 13 開始,Apple 引入了一種新方法,用戶可以通過從頂部拉下視圖 controller 來dismiss呈現的視圖。 可以通過將UIViewController實現到您正在演示的UIAdaptivePresentationControllerDelegate來捕獲此事件,在本例中為Presenting controller。 然后您可以在方法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).
    }
}

筆記:

  1. 此方法僅會通過從頂部滑動來觸發,而不是程序化的dismiss(animated:,completion:)方法。
  2. 您不需要任何自定義委托或Notification觀察者來獲取用戶通過向下滑動關閉 controller 的事件,因此您可以刪除它們。

采用UIAdaptivePresentationControllerDelegate並實現presentationControllerDidAttemptToDismiss (iOS 13+)

extension Presenting : UIAdaptivePresentationControllerDelegate {

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

UIPresentationController有一個屬性presentingViewController 這個名字是不言自明的。 您不需要顯式委托協議。

實際上調用該方法是為了能夠顯示一個對話框,例如在關閉 controller 之前保存更改。 您還可以實現presentationControllerDidDismiss()

並且不要向彼此相關的控制器發布通知。 這是不好的做法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM