iOS 17 UIKit Popover 在 iPad 上崩溃 - UIPopoverPresentationController 应该有一个非零的 sourceView

iOS 17 UIKit Popover Crash on iPad - UIPopoverPresentationController should have a non-nil sourceView

提问人:Nathan Dudley 提问时间:10/13/2023 更新时间:10/13/2023 访问量:219

问:

在 iPadOS 17 上,关闭弹出框然后再次快速显示弹出框时会发生崩溃。通常错误如下:

UIPopoverPresentationController should have a non-nil sourceView or barButtonItem set before the presentation occurs

但是,我偶尔会看到以下内容:

Application tried to present modally a view controller that is already being presented by the [main view controller]

这是重现此崩溃所需的最小源代码:

class ViewController: UIViewController {

    let popoverVC = UIViewController()
    
    @IBOutlet var showPopoverButton: UIButton!
    
    @IBAction func showPopoverTapped(_ sender: UIButton) {
        popoverVC.modalPresentationStyle = .popover
        popoverVC.popoverPresentationController?.sourceView = showPopoverButton
        present(popoverVC, animated: true)
    }
}

关于此问题,需要考虑的其他一些事项:

  1. 这在 iOS 16 或更早版本上不会发生。
  2. 设置 on 不起作用。.sourceRectpopoverPresentationController
  3. 设置弹出框的 or 不起作用。framepreferredContentSize
  4. 崩溃发生在有或没有情节提要(硬编码 UI)的 UIKit 中。
  5. SwiftUI 中不会发生崩溃。请不要建议将 SwiftUI 作为修复程序。
  6. 我可以在演示之前添加一个以确保不是,但它没有效果。guardsourceViewnil

出现此问题似乎是因为在显示新的弹出框时,弹出框视图控制器未从内存中完全解除分配。这造成了某种冲突。我已经成功地旋转了,我很乐意发布该解决方案,但首先我想看看是否有更少的黑客解决方法。我不想简单地覆盖,因为我想要默认行为,并且宁愿不重写我自己的弹出动画以满足这个错误。UIPopoverPresentationController.dismissalTransitionWillBegindismissalTransitionWillBegin

enter image description here

iOS iPad UIKIT UIPopoverController iPadOS

评论

0赞 HangarRash 10/13/2023
如果将线移动到线之后会发生什么?popoverVC.popoverPresentationController?.sourceView = showPopoverButtonpresent(popoverVC, animated: true)
0赞 Nathan Dudley 10/16/2023
不幸的是,这个提议的更改仍然间歇性地发生崩溃。我实际上很惊讶它根本无法工作,因为在演示之前没有设置。sourceView

答:

2赞 Joe Pham 10/13/2023 #1

我在 iPadOS 17 上也遇到了同样的崩溃。它不会一直发生,所以为什么会发生这种情况很棘手。

我目前的解决方法是在继续显示新视图控制器之前,先检查当前视图控制器是否正在显示另一个视图控制器。到目前为止,这似乎对我有用。

guard self.presentedViewController == nil else { return }

评论

1赞 Nathan Dudley 10/16/2023
哇 - 简单明了,比打雪花干净得多。希望苹果能解决根本问题,但目前这似乎是安全的。