194

iOS 13为模态呈现的视图控制器引入了一种新设计modalPresentationStyle .pageSheet(及其兄弟.formSheet)……</p>

iOS 13 中新的滑动模式演示

…我们可以通过向下滑动呈现的视图控制器来关闭这些工作表(交互式关闭)。尽管新的“pull-to-dismiss”功能非常有用,但它可能并不总是可取的。

问题:我们如何关闭交互式解雇? - 请记住,我们保持演示风格相同。

4

8 回答 8

360

选项1:

viewController.isModalInPresentation = true

禁用交互式解雇

(禁用交互式.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 的委托。

于 2019-06-05T11:11:34.223 回答
80
  1. 如果您想要与以前的 iOS 版本 (< iOS13) 相同的行为,例如全屏模型演示,只需将目标视图控制器的演示样式设置为UIModalPresentationStyle.fullScreen

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

    如果您使用情节提要,只需选择 segua 并从Full Screen下拉列表中选择Presentation

    在此处输入图像描述

  2. 如果您只想禁用交互式解除并将新的演示文稿样式集UIViewController属性保留isModalInPresentationtrue.

    if #available(iOS 13.0, *) {
        someViewController.isModalInPresentation = true // available in IOS13
    }
    
于 2019-06-06T22:45:36.783 回答
8

该物业isModalInPresentation可能会有所帮助。

从文档中:

当您将其设置为 时true,UIKit 会忽略视图控制器范围之外的事件,并防止视图控制器在屏幕上的交互解除。

你可以像这样使用它:

let controller = MyViewController()
controller.isModalInPresentation = true
self.present(controller, animated: true, completion: nil)
于 2019-09-25T10:28:24.350 回答
5

如果您使用故事板来布局您的 UI,我发现在使用导航控制器时禁用此交互式解除的最佳方法是将属性检查器中导航控制器的显示从自动更改为全屏。然后,导航堆栈中的所有视图控制器都将全屏显示,并且无法被用户关闭。

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

于 2019-10-11T12:43:29.433 回答
4

如果你有一些业务逻辑,比如所有字段都应该在解雇之前填写,你应该:

ViewDidLoad如果您的 ViewController 已出现在导航控制器中,则打开:

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
    }

}
于 2021-05-25T18:49:30.973 回答
2

您现在可以实现交互手势识别器的委托,并在尝试同时与滑块交互时禁用交互。这样,您可以保持交互式关闭,而滑块按预期工作。

您可以像这样禁用向下滑动:

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
})
于 2020-12-09T05:08:59.357 回答
1

Apple在此链接上共享了有关它的示例代码

它使用isModalInPresentation尽可能多的用户建议。

于 2019-12-11T12:22:09.813 回答
0

所有解决方案都很好,但就我而言,我需要一个停止移动的选项。所以这是一个代码。

如果你想阻止移动:

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

如果你想解锁运动:

self.yourViewController?.presentedView?.gestureRecognizers?[0].isEnabled = true
于 2021-09-07T08:11:08.393 回答