Mar*_*aka 41 uiviewcontroller uikit ios swift ios13
在iOS 13之前,提供了用于覆盖整个屏幕的视图控制器。并且,在关闭后,将viewDidAppear执行父视图控制器功能。
现在,iOS 13默认将表单显示为视图控制器,这意味着卡将部分覆盖基础视图控制器,这意味着viewDidAppear不会被调用,因为父视图控制器从未真正消失过。
有没有一种方法可以检测到所显示的视图控制器工作表已被解雇?我可以在父视图控制器中重写某些其他功能,而不是使用某种委托?
mat*_*att 20
有没有一种方法可以检测到所显示的视图控制器工作表已被解雇?
是。
我可以在父视图控制器中重写某些其他功能,而不是使用某种委托?
不,“某种委托”是您的工作方式。使自己成为演示控制器的委托和重写presentationControllerDidDismiss(_:)。
缺少一个一般的运行时生成的事件,通知您所显示的视图控制器(无论是否为全屏)已被关闭,这确实很麻烦。但这不是一个新问题,因为始终存在非全屏显示的视图控制器。只是现在(在iOS 13中)有更多!我在其他地方对此主题进行了单独的问答:统一UIViewController“成为最前面的”检测工具?。
Pit*_*Pan 17
另一个取回viewWillAppear并viewDidAppear设置的选项
let vc = UIViewController()
vc.modalPresentationStyle = .fullScreen
Run Code Online (Sandbox Code Playgroud)
此选项全屏显示,关闭后调用上述方法
Mat*_*att 14
这是父视图控制器的代码示例,该子视图在子视图控制器呈现为工作表时(即,以默认的iOS 13方式)被通知时通知:
public final class Parent: UIViewController, UIAdaptivePresentationControllerDelegate
{
// This is assuming that the segue is a storyboard segue;
// if you're manually presenting, just see the delegate there.
public override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "mySegue" {
segue.destination.presentationController?.delegate = self;
}
}
public func presentationControllerDidDismiss(
_ presentationController: UIPresentationController)
{
// Only called when the sheet is dismissed by DRAGGING.
// You'll need something extra if you call .dismiss() on the child.
// (I found that overriding dismiss in the child and calling
// presentationController.delegate?.presentationControllerDidDismiss
// works well).
}
}
Run Code Online (Sandbox Code Playgroud)
Jerland2的答案很混乱,因为(a)最初的提问者想在关闭工作表时获得一个函数调用(而他实现了presentationControllerDidAttemptToDismiss,当用户尝试并无法关闭工作表时会调用它),并且(b)设置isModalInPresentation是完全正交的,实际上会使所呈现的图纸不可忽略(这与OP想要的相反)。
Vit*_*lii 10
如果您想在用户从该工作表中关闭模式工作表时执行某些操作。假设您已经有一些“关闭”按钮,其中包含一个@IBAction在关闭或执行其他操作之前显示警报的逻辑。您只想检测用户按下此类控制器的时刻。
就是这样:
class MyModalSheetViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.presentationController?.delegate = self
}
@IBAction func closeAction(_ sender: Any) {
// your logic to decide to close or not, when to close, etc.
}
}
extension MyModalSheetViewController: UIAdaptivePresentationControllerDelegate {
func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool {
return false // <-prevents the modal sheet from being closed
}
func presentationControllerDidAttemptToDismiss(_ presentationController: UIPresentationController) {
closeAction(self) // <- called after the modal sheet was prevented from being closed and leads to your own logic
}
}
Run Code Online (Sandbox Code Playgroud)
For future readers here is a more complete answer with implementation:
// Modal Dismiss iOS 13
modalNavController.presentationController?.delegate = modalVc
Run Code Online (Sandbox Code Playgroud)
// MARK: - iOS 13 Modal (Swipe to Dismiss)
extension ModalViewController: UIAdaptivePresentationControllerDelegate {
func presentationControllerDidAttemptToDismiss(_ presentationController: UIPresentationController) {
print("slide to dismiss stopped")
self.dismiss(animated: true, completion: nil)
}
}
Run Code Online (Sandbox Code Playgroud)
self.isModalInPresentation = true
Run Code Online (Sandbox Code Playgroud)
覆盖正在被驳回的viewWillDisappear内容UIViewController。它会通过布尔标志提醒您解雇isBeingDismissed。
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if isBeingDismissed {
print("user is dismissing the vc")
}
}
Run Code Online (Sandbox Code Playgroud)
** 如果用户向下滑动一半并向上滑动卡片,即使卡片没有被关闭,它仍然会注册为被关闭。但这是您可能不关心的极端情况。
迅速
viewWillAppear在iOS13 中调用的一般解决方案
class ViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("viewWillAppear")
}
//Show new viewController
@IBAction func show(_ sender: Any) {
let newViewController = NewViewController()
//set delegate of UIAdaptivePresentationControllerDelegate to self
newViewController.presentationController?.delegate = self
present(newViewController, animated: true, completion: nil)
}
}
extension UIViewController: UIAdaptivePresentationControllerDelegate {
public func presentationControllerDidDismiss( _ presentationController: UIPresentationController) {
if #available(iOS 13, *) {
//Call viewWillAppear only in iOS 13
viewWillAppear(true)
}
}
}
Run Code Online (Sandbox Code Playgroud)