繁体   English   中英

为什么“作为弹出框存在”segue 会覆盖整个屏幕?

[英]Why is 'present as popover' segue covering the whole screen?

在我的项目中,我在屏幕的右下角有一个按钮,我在情节提要中添加了另一个 uiviewcontroller,将控件拖动到我想要的 uiviewcontroller 作为弹出框,然后将该视图控制器大小设置为 (300, 300) 并检查'使用首选的显式大小'。 当我加载应用程序并单击按钮时,整个屏幕都被“弹出窗口”覆盖。 我还尝试进入 popoverViewController 的 .m 文件并设置大小,但这也不起作用。
有任何想法吗?

编辑:因为看起来我必须全屏显示,这很好,但是我仍然遇到了我之前遇到的其他一些问题。 我的弹出屏幕会出现,我将背景黑色和 alpha 设为 0.5 以使其透明,但它会执行动画,然后一旦动画完成,屏幕将从 0.5 不透明度变为完全黑色,唯一的我能看到的是电池图标。

OP 使用 Objective-C。 这个答案 swift 提供了代码。 将 swift 转换为 Objective-C 应该很容易。

在新添加的 ViewController 中,在“Simulated Metrics”下将“Size”更改为“Freeform”,将“Status Bar”更改为“None”。

在“模拟大小”下,将视图的高度和宽度更改为您希望弹出框内容的实际大小。

为新添加的 VC 创建一个 segue。 使用 segue 类型作为“Present As Popover”并为 segue 命名,例如“popoverSegue”。

在要触发此 segue 的UIPopoverPresentationControllerDelegate ,添加UIPopoverPresentationControllerDelegate协议。

class ViewController: UIViewController, UIPopoverPresentationControllerDelegate {
}

覆盖 prepareForSegue 函数以捕获您的 popover segue。 将 modalPresentationStyle 设置为 .Popover 以明确声明您想要一个弹出框,然后将视图的 popoverPresentationController 的委托属性分配给 self:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "popoverSegue" {
            let popoverViewController = segue.destinationViewController as! UIViewController
            popoverViewController.modalPresentationStyle = UIModalPresentationStyle.Popover
            popoverViewController.popoverPresentationController!.delegate = self
        }
    }

实现adaptivePresentationStyleForPresentationController 函数来告诉你的应用你真的想要那个popover 展示并且不接受替换:

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
        return UIModalPresentationStyle.None
    }

在这些之后,我可以在 iPhone 上得到一个弹出窗口,它不是全屏而是为 ViewController 设置的大小。

在此处输入图片说明

来源:使用 Swift 在 iPhone 上的 iPad Style Popovers

感谢Bharat 的出色回答,我个人使用了一个 UIStoryboardSegue,它的功能几乎相同。 这样,我可以在故事板中更改 segue 的类,拥有我想要的东西,而不会污染我的控制器:

class AlwaysPopupSegue : UIStoryboardSegue, UIPopoverPresentationControllerDelegate
{
    override init(identifier: String?, source: UIViewController, destination: UIViewController)
    {
        super.init(identifier: identifier, source: source, destination: destination)
        destination.modalPresentationStyle = UIModalPresentationStyle.popover
        destination.popoverPresentationController!.delegate = self
    }
    func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
        return UIModalPresentationStyle.none
    }
}

斯威夫特 3-5 版本

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "SEGUE_IDENTIFIER" {
            let popoverViewController = segue.destination as! YourViewController
            
            popoverViewController.modalPresentationStyle = UIModalPresentationStyle.popover
            popoverViewController.popoverPresentationController!.delegate = self
        }
    }
    
    func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
        return UIModalPresentationStyle.none
    }
    

斯威夫特 4 版本

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "SegueIdentifier" {
            let popoverViewController = segue.destination
            popoverViewController.modalPresentationStyle = .popover
            popoverViewController.presentationController?.delegate = self
     }
}

不要忘记添加

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

在 iPhone 上,您可以创建一个可以管理所有弹出框的自定义视图控制器。 由于每个视图控制器都有自己的导航控制器,您可以将一个新的视图控制器添加到 app.window.rootviewcontroller 作为 du 视图并将所有视图放在前面。

如果你不想自己写,你可以使用这样的东西,例如: http : //cocoapods.org/pods/FPPopover

这是 Swift 5 代码,上面提到的一些/大部分解决方案都是有效的。 这是努力提出完整的解决方案。 这个例子假设你使用了一个用于弹出视图控制器的 xib 但这也可以工作,例如,为 segue 做准备。 这是一个完整的代码:

呈现视图控制器:

let popoverVC = PopoverVC(nibName: "popoverVC", bundle: nil)
popoverVC.completionHandler = { [unowned self] (itemIndex : Int?) in
    if let itemIndex = itemIndex
    {
         // Do completion handling
    }
}

popoverVC.preferredContentSize = CGSize(width: 200, height: 60)
popoverVC.modalPresentationStyle = .popover

if let pvc = popoverVC.popoverPresentationController {
    pvc.permittedArrowDirections = [.down]
    pvc.delegate = self
    pvc.sourceRect = button.frame
    pvc.sourceView = button // Button popover is presented from
    present(popoverVC, animated: true, completion: nil)
}

这个很重要:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM