簡體   English   中英

禁用呈現視圖 controller 的交互式關閉

[英]Disable the interactive dismissal of presented view controller

iOS 13為模態呈現的視圖控制器引入了modalPresentationStyle .pageSheet (及其兄弟.formSheet )的新設計……

iOS 13 中新的滑動模式演示

…我們可以通過向下滑動呈現的視圖 controller 來關閉這些工作表(交互式關閉) 盡管新的“pull-to-dismiss”功能非常有用,但它可能並不總是可取的。

問題:我們如何關閉交互式解雇? - 請記住,我們保持演示風格相同。

選項1:

viewController.isModalInPresentation = true

殘疾人互動解雇

(禁用交互式.pageSheet解雇行為就像這樣。)

  • 從 iOS 13 開始, UIViewController包含一個名為isModalInPresentation的新屬性,必須將其設置為true以防止交互式isModalInPresentation
  • 它基本上忽略了視圖控制器邊界之外的事件。 如果您不僅使用自動樣式,還使用.popover等演示樣式,請.popover
  • 默認情況下,此屬性為false

來自官方文檔:如果為true ,則 UIKit 會忽略視圖控制器邊界之外的事件,並防止視圖控制器在屏幕上時交互式關閉。


選項 2:

func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool {
    return false
}
  • 從 iOS 13 開始, UIAdaptivePresentationControllerDelegate包含一個名為presentationControllerShouldDismiss的新方法。
  • 僅當呈現的視圖控制器未以編程方式解除並且其isModalInPresentation屬性設置為false才會調用此方法。

提示:不要忘記分配presentationController 的委托。

  1. 如果您想要與之前的 iOS 版本(< iOS13)相同的行為,如全屏模型展示,只需將目標視圖控制器的展示樣式設置為UIModalPresentationStyle.fullScreen

     let someViewController = \\*VIEW CONTROLLER*\\ someViewController.modalPresentationStyle = .fullScreen

    如果您使用故事板,只需選擇 segua 並從Presentation下拉菜單中選擇Full Screen

    在此處輸入圖片說明

  2. 如果您只想禁用交互式關閉並保持新的演示樣式,請將UIViewController屬性isModalInPresentation設置為true

     if #available(iOS 13.0, *) { someViewController.isModalInPresentation = true // available in IOS13 }

屬性isModalInPresentation可能會有所幫助。

從文檔:

當您將其設置為true ,UIKit 會忽略視圖控制器邊界之外的事件,並防止視圖控制器在屏幕上時交互式關閉。

你可以這樣使用它:

let controller = MyViewController()
controller.isModalInPresentation = true
self.present(controller, animated: true, completion: nil)

如果您使用故事板來布局您的 UI,我發現在使用導航控制器時禁用此交互式關閉的最佳方法是將屬性檢查器中導航控制器的顯示從自動更改為全屏。 導航堆棧中的所有視圖控制器都將全屏顯示並且無法被用戶關閉。

屬性檢查器顯示導航控制器的呈現選項

您現在可以實現交互手勢識別器的代理,並在嘗試同時與滑塊交互時禁用交互。 這樣,您可以保持交互式關閉,而滑塊按預期工作。

您可以像這樣禁用向下滑動:

let controller = storyboard?.instantiateViewController(withIdentifier: "NextVC") as! NextVC
let navigationController = UINavigationController(rootViewController: controller)
self.present(navigationController, animated: true, completion: {
   navigationController.presentationController?.presentedView?.gestureRecognizers?[0].isEnabled = false
})

如果你有一些業務邏輯,比如在解雇之前應該填寫所有字段,你應該:

如果您的 ViewController 已在導航控制器中呈現,則在ViewDidLoad

func viewDidLoad() { 
    self.navigationController?.presentationController?.delegate = self
}

如果沒有,只需使用

func viewDidLoad() { 
    self.presentationController?.delegate = self
}

然后實現委托方法:

extension ViewController: UIAdaptivePresentationControllerDelegate {

    func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool {
        guard let text = firstName.text, text.isEmpty else { return false }
        guard let text = lastName.text, text.isEmpty else { return false }
        ...
    
        return true
    }

}

Apple 在此鏈接上分享了有關它的示例代碼

它使用isModalInPresentation作為許多用戶的建議。

所有解決方案都很好,但就我而言,我需要一個選項來停止移動。 所以這是一個代碼。

如果你想阻止移動:

self.yourViewController?.presentedView?.gestureRecognizers?[0].isEnabled = false

如果你想解鎖移動:

self.yourViewController?.presentedView?.gestureRecognizers?[0].isEnabled = true

暫無
暫無

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

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