在没有 segue 的情况下呈现一个 popover——Popover 仍然是全屏的

Presenting a popover without segue -- Popover is still full screen

我有一个 UIViewController,里面有一个我以编程方式创建的按钮(我们就称它为 MyViewController)。我试图在点击按钮时显示一个弹出窗口。让我们调用弹出窗口 DestinationViewController。点击按钮时将调用以下函数:

func buttonAction(_ button: UIView) {
   var popover = storyboard?.instantiateViewController(withIdentifier: "destinationVC") as? DestinationViewController
   popover?.popoverPresentationController?.delegate = self
   popover?.modalPresentationStyle = .popover
   popover?.popoverPresentationController?.sourceView = button
   //popover?.popoverPresentationController?.sourceRect = CGRect(x: 0, y: 0, width: 50, height: 50)
   popover?.preferredContentSize = CGSize(width: 200, height: 100)

   present(popover!, animated: true, completion: nil)         
}

(我注释掉了 sourceRect 行,因为它什么也没做,但我不知道是不是我用错了。)

此外,我确保 MyViewController 符合 UIPopoverPresentationControllerDelegate 协议。所以MyViewController实现了函数:

func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
   return .none
}

最后,在 DestinationViewController 的情节提要中,我选中了宽度为 200、高度为 100 的框 "Use Preferred Explicit Size"。

但是,我的 DestinationViewController 仍然全屏显示。我读过 adaptivePresentationStyle 函数应该可以防止这种情况,但没有运气。我知道使用 segue 会使其正常工作,但我无法在情节提要中进行 segue,因为我的按钮是以编程方式制作的。

关于我应该如何解决这个问题有什么想法吗?我不太熟悉制作弹出窗口,所以我需要一些帮助。

您需要先将 modalPresentationStyle 设置为 .popover 才能访问 popoverPresentAtionController 属性:

来自the documentation

If you created the view controller but have not yet presented it, accessing this property creates a popover presentation controller when the value in the modalPresentationStyle property is UIModalPresentationStyle.popover. If the modal presentation style is a different value, this property is nil.

由于您在设置委托之前没有设置模态呈现样式,因此不会创建弹出框呈现控制器。当您设置 .sourceView 时,将创建弹出框控制器,因为现在的呈现样式是 .popover,但不会在此实例上设置委托。

此外,您可以通过在按钮操作处理程序代码中使用 performSegue,将 segue 与您在代码中创建的按钮一起使用。