禁用显示的视图控制器的交互式解除

IOS13为模态视图控制器引入了一种新的 modalPresentationStyle .pageSheet(及其兄弟 .formSheet)设计方案。

The new sliding modal presentation in iOS 13

我们可以通过将视图控制器向下滑动 (互动式解散)来消除这些表格。尽管新的“撤销”特性非常有用,但它可能并不总是令人满意的。

问题: 我们如何才能关闭互动式解雇? 记住,我们的演讲风格是一样的。

77338 次浏览

选项1:

viewController.isModalInPresentation = true

Disabled interactive解雇

(禁用的交互式.pageSheet驳回是这样的。)

  • 自iOS 13以来,UIViewController包含了一个名为isModalInPresentation的新属性,必须将其设置为true以防止交互终止。
  • 它基本上忽略了视图控制器边界之外的事件。如果你不仅使用自动样式,还使用.popover等表示样式,请记住这一点。
  • 该属性默认为false

官方文档 .:如果true, UIKit将忽略视图控制器边界之外的事件,并防止视图控制器在屏幕上时被交互式丢弃。


选项2:

func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool {
return false
}
  • 从iOS 13开始,UIAdaptivePresentationControllerDelegate包含了一个名为presentationControllerShouldDismiss的新方法。
  • 此方法仅在呈现的视图控制器未以编程方式解散且其isModalInPresentation属性被设置为false时被调用。

不要忘记分配presentationController的委托。但是要注意,即使只是访问presentationController也会导致内存泄漏。

  1. 如果你想要与之前的iOS版本相同的行为(<就像全屏显示模型一样,只要将你的目标视图控制器的显示样式设置为UIModalPresentationStyle.fullScreen

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

    如果你正在使用故事板,只需选择segue,并从Presentation下拉菜单中选择Full Screen

    enter image description here < / p >

  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,我发现在使用导航控制器时禁用这种交互式撤销的最好方法是将导航控制器在属性检查器中的表示从自动更改为全屏。导航堆栈中的所有视图控制器都将是全屏的,用户无法将其解散。

属性检查器显示导航控制器的表示选项

苹果分享了一个关于它的示例代码在此链接

它使用isModalInPresentation作为许多用户的建议。

如果你有一些业务逻辑,比如所有字段都应该在驳回之前被填充,你应该:

ViewDidLoad上,如果你的ViewController已经在导航控制器中显示:

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

如果没有,就简单地使用

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

然后实现delegate方法:

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
}


}
所有的解决方案都很好,但在我的情况下,我需要一个停止运动的选项。 这是一个代码

如果你想阻止移动:

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

如果你想解锁移动:

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