在紧凑环境中未要求iOS 13的presentationControllerDidDismiss()进行弹出框调用 [英] iOS 13's presentationControllerDidDismiss() Not Called for Popover in Compact Environment

查看:116
本文介绍了在紧凑环境中未要求iOS 13的presentationControllerDidDismiss()进行弹出框调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为iOS 13的新卡片式"模式视图更新我的应用程序.使用 UIAdaptivePresentationControllerDelegate presentationControllerDidAttemptToDismiss() presentationControllerDidDismiss()函数,所有程序都运行良好.但是,对于将 .modalPresentationStyle 设置为 .popover 的视图,在紧凑环境中(例如,手机或iPad分拆或滑盖).在常规尺寸的课堂环境(例如iPad全屏)中显示时,可以正确调用它.

I am updating my app for iOS 13’s new "card-style" modal views. All has been working well using UIAdaptivePresentationControllerDelegate’s presentationControllerDidAttemptToDismiss() and presentationControllerDidDismiss() functions. But, for views that have their .modalPresentationStyle set to .popover, presentationControllerDidDismiss() is not called when being presented in compact environments (such as a phone or iPad in split or slide-over). It’s called correctly when presented in a regular size class environment (such as an iPad full-screen).

我的代码设置起来非常简单:

My code setting this up is pretty straightforward:

呈现弹出窗口的代码:

func showChooser() {
    // other setup code...
    navController.modalPresentationStyle = .popover
    navController.popoverPresentationController?.barButtonItem = self.viewController?.navigationItem.leftBarButtonItem
    self.present(navController, animated: true)
}

然后,显示的控制器符合 UIAdaptivePresentationControllerDelegate 并进行设置:

Then, the presented controller conforms to UIAdaptivePresentationControllerDelegate and sets up:

// 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().

When the view is presented in regular size-class environments, it is displayed correctly as a popover. When the user taps outside the popover, then presentationControllerDidDismiss() is called. However, when the same code is presented in a compact environment, it’s displayed correctly (as a card style), but when the user drags down the view, presentationControllerDidDismiss() is not called.

如果将 .modalPresentationStyle 更改为诸如 .pageSheet .formSheet 之类的其他内容,则无论哪种压缩方式都可以正常工作或定期演示.

If I change the .modalPresentationStyle to something else such as .pageSheet or .formSheet, then it all works as expected in either compact or regular presentations.

我尝试在紧凑的环境中使用委托人的 adaptivePresentationStyle()将样式更改为 .formSheet ,但是 presentationControllerDidDismiss()是仍然没有被正确调用.

I’ve tried using the delegate's adaptivePresentationStyle() to change the style to .formSheet on compact environments, but presentationControllerDidDismiss() is still not called correctly.

更新:我应该提到我当前的解决方法是检查大小类并根据需要更改 .modalPresentationStyle :

Update: I should have mentioned that my current workaround is to check the size class and change .modalPresentationStyle as needed:

if self.traitCollection.horizontalSizeClass == .compact {
    navController.modalPresentationStyle = .automatic
} else {
    navController.modalPresentationStyle = .popover
    navController.popoverPresentationController?.barButtonItem = self.viewController?.navigationItem.leftBarButtonItem
}

这行得通,但是似乎仅使用 .popover 样式应该可以正确调整并调用正确的委托方法.

This works, but it seems that just using the .popover style should adapt properly and call the correct delegate methods.

更新2:我已经更新了上面的代码,以阐明 presented 视图控制器是处理委托方法的控制器.

Update 2: I've updated the code above to clarify that the presented view controller is the one handling the delegate methods.

此外,在深入研究之后,我注意到,如果 presenting 视图控制器是委托并处理委托方法,那么这一切都可以按预期进行.由于它也可以在紧凑环境中的所有 .modalPresentationStyle except 弹出框的 presented 视图控制器中工作,因此,弹出框时可能存在一些生命周期问题以这种方式呈现?

Also, after digging into this more, I noticed that if the presenting view controller is the delegate and handles the delegate methods, then this all works as expected. Since it also works in the presented view controller for all .modalPresentationStyle's except popover in compact environments, perhaps there is some lifetime issue when popovers are presented in that way?

关于我可能做错了什么的任何想法?

Any ideas about what I might be doing wrong?

推荐答案

问题仅仅是时机之一.您正在第二个视图控制器中执行此操作:

The problem is merely one of timing. You're doing this in the second view controller:

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

那太晚了.您可以在配置和执行演示的位置设置委托:

That's too late. You can set the delegate where you configure and perform the presentation:

func showChooser() {
    navController.modalPresentationStyle = .popover
    navController.popoverPresentationController?.barButtonItem = 
        self.viewController?.navigationItem.leftBarButtonItem
    navController.presentationController?.delegate = // *
        navController.viewControllers[0] 
        as! UIAdaptivePresentationControllerDelegate
    self.present(navController, animated: true)
}

如果您希望坚持让第二个视图控制器将其自身设置为委托,请尽早进行操作.第一个好机会是 willMove :

If you prefer to insist upon having the second view controller set itself as delegate, do it earlier. The first good opportunity is willMove:

override func willMove(toParent parent: UIViewController?) {
    self.parent?.presentationController?.delegate = self
}

这篇关于在紧凑环境中未要求iOS 13的presentationControllerDidDismiss()进行弹出框调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆