【发布时间】:2020-03-27 16:02:30
【问题描述】:
我正在为 iOS 13 的新“卡片式”模式视图更新我的应用程序。使用UIAdaptivePresentationControllerDelegate 的presentationControllerDidAttemptToDismiss() 和presentationControllerDidDismiss() 函数,一切运行良好。但是,对于将.modalPresentationStyle 设置为.popover 的视图,presentationControllerDidDismiss() 在紧凑型环境中呈现时不会被调用(例如手机或 iPad 处于拆分或滑过状态)。当在常规尺寸类环境(如 iPad 全屏)中呈现时,它会被正确调用。
我的代码设置非常简单:
显示弹出框的代码:
func showChooser() {
// other setup code...
navController.modalPresentationStyle = .popover
navController.popoverPresentationController?.barButtonItem = self.viewController?.navigationItem.leftBarButtonItem
self.present(navController, animated: true)
}
然后,呈现的控制器符合UIAdaptivePresentationControllerDelegate 并设置:
// This is in the presented view controller (i.e. the popover)
override func viewDidLoad() {
// other setup removed for brevity…
self.navigationController?.presentationController?.delegate = self
}
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
print("did dismiss")
self.cancel?()
}
当视图在常规尺寸等级环境中呈现时,它会正确显示为弹出框。当用户在弹出框外点击时,会调用presentationControllerDidDismiss()。但是,相同的代码在紧凑的环境中呈现时,可以正确显示(作为卡片样式),但是当用户向下拖动视图时,不会调用presentationControllerDidDismiss()。
如果我将 .modalPresentationStyle 更改为其他名称,例如 .pageSheet 或 .formSheet,那么无论是在紧凑的演示文稿中还是在常规演示文稿中,它都可以正常工作。
我尝试在紧凑型环境中使用代理的 adaptivePresentationStyle() 将样式更改为 .formSheet,但仍然无法正确调用 presentationControllerDidDismiss()。
更新:
我应该提到我目前的解决方法是检查大小类并根据需要更改.modalPresentationStyle:
if self.traitCollection.horizontalSizeClass == .compact {
navController.modalPresentationStyle = .automatic
} else {
navController.modalPresentationStyle = .popover
navController.popoverPresentationController?.barButtonItem = self.viewController?.navigationItem.leftBarButtonItem
}
这行得通,但似乎只使用.popover 样式应该正确适应并调用正确的委托方法。
更新 2: 我更新了上面的代码,以阐明 presented 视图控制器是处理委托方法的控制器。
另外,在深入研究之后,我注意到如果 presenting 视图控制器是委托并处理委托方法,那么这一切都按预期工作。由于它也适用于紧凑环境中所有.modalPresentationStyle 的 except 弹出框的 presented 视图控制器,因此以这种方式显示弹出框时可能存在一些生命周期问题?
关于我可能做错了什么有什么想法吗?
【问题讨论】:
-
很好的研究。一个问题。
willDismiss怎么样?这叫什么? -
@matt,不,也没有被调用。在紧凑环境中调用的唯一委托方法是
adaptivePreesentationStyle()。 -
我会尝试重现此内容,如果我有任何想法,请告诉您。再次,良好的研究。同时还有一个想法:观察呈现的视图控制器确实不需要获取
dismiss委托方法,因为它自己的viewDidDisappear会捕捉到这一点。 -
@matt,我很感激。关于
viewDidDisappear的好点。这在这种情况下可以工作。现在 iOS 默认使用这种卡片样式的模态视图,这在其他情况下也可以工作,因为在当前模态视图之上显示另一个模态时不再调用viewDidDisappear。 -
好的,我已经给出了一些其他解决方法,这些解决方法将导致
will和did按预期开始工作。很抱歉让您失望了,但我认为我们不能将此视为错误。
标签: ios swift uiviewcontroller uikit ios13