IOS13为模态视图控制器引入了一种新的 modalPresentationStyle .pageSheet(及其兄弟 .formSheet)设计方案。
modalPresentationStyle
.pageSheet
.formSheet
我们可以通过将视图控制器向下滑动 (互动式解散)来消除这些表格。尽管新的“撤销”特性非常有用,但它可能并不总是令人满意的。
问题: 我们如何才能关闭互动式解雇? 记住,我们的演讲风格是一样的。
viewController.isModalInPresentation = true
(禁用的交互式.pageSheet驳回是这样的。)
UIViewController
isModalInPresentation
true
.popover
false
从官方文档 .:如果true, UIKit将忽略视图控制器边界之外的事件,并防止视图控制器在屏幕上时被交互式丢弃。
func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool { return false }
UIAdaptivePresentationControllerDelegate
presentationControllerShouldDismiss
不要忘记分配presentationController的委托。但是要注意,即使只是访问presentationController也会导致内存泄漏。
presentationController
如果你想要与之前的iOS版本相同的行为(<就像全屏显示模型一样,只要将你的目标视图控制器的显示样式设置为UIModalPresentationStyle.fullScreen
UIModalPresentationStyle.fullScreen
let someViewController = \*VIEW CONTROLLER*\ someViewController.modalPresentationStyle = .fullScreen
如果你正在使用故事板,只需选择segue,并从Presentation下拉菜单中选择Full Screen。
Presentation
Full Screen
< / p >
如果你只是想禁用交互式撤销并保持新的表示样式,将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已经在导航控制器中显示:
ViewDidLoad
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