在iPhone上以编程方式显示真正的popover视图

时间:2015-05-21 09:00:21

标签: ios iphone swift uipopovercontroller popover

修改 添加了方法3(见下面的评论)。

我想在我的应用程序中创建一些小的弹出窗口,但我不能使用故事板,因为这些弹出窗口的锚点将是用户创建的UIControl。

我想创建真正的弹出窗口,如here所述(不是全屏版)。它使用故事板很好用但在这种情况下我需要它没有segues工作。

此外,我发现this post该人试图做一些非常相似的事情。我尝试使用 // approach 1 中该帖子的解决方案。在//方法2中,我尝试了this网站上的解决方案(尽管我认为它只适用于iPad,但我的想法不合适......)。

// long press gesture: show additional control elements
func showLongPressMenu(recognizer: UILongPressGestureRecognizer) {

    // approach 1
    let newPopoverVC1 = UIViewController(nibName: "LinkAreaPopupView", bundle: NSBundle.mainBundle())
    newPopoverVC1.modalPresentationStyle = .Popover
    newPopoverVC1.preferredContentSize = CGSizeMake(137.0, 28.0)
    var newPopoverController = newPopoverVC1.popoverPresentationController!
    newPopoverController.delegate = self
    newPopoverController.permittedArrowDirections = .Any
    newPopoverController.sourceView = ???
    newPopoverController.sourceRect = ???
    presentViewController(newPopoverVC1, animated: true, completion: nil)

    // approach 2
    let newPopoverVC2 = UIViewController(nibName: "LinkAreaPopupView", bundle: NSBundle.mainBundle())
    newPopoverVC2.modalPresentationStyle = .Popover
    let popAnchorRect = self.frame
    let newPopover = UIPopoverController(contentViewController: newPopoverVC2)
    newPopover.presentPopoverFromRect(popAnchorRect, inView: ???, permittedArrowDirections: .Any, animated: true)

    // approach 3
    let vc = UIViewController()
    vc.preferredContentSize = CGSizeMake(137.0, 28.0)
    vc.modalPresentationStyle = .Popover

    if let pres = vc.popoverPresentationController {
        pres.delegate = self
    }

    // THIS DOES NOT WORK
    self.superview.presentViewController(vc, animated: true, completion: nil)

    let popView = LinkAreaPopupView()
    vc.view.addSubview(popView)
    popView.frame = vc.view.bounds
    popView.autoresizingMask = .FlexibleWidth | .FlexibleHeight

    if let pop = vc.popoverPresentationController {
        pop.sourceView = (self as UIView)
        pop.sourceRect = (self as UIView).bounds
    }
}

委托功能:

// don't allow to substitute the presentation style of popover controllers (to fullscreen for example)
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
    return .None
}

“LinkAreaPopupView”是一个包含我想要显示的菜单的XIB文件。

我的问题是具有此代码的类是UIControl的子类,并且将由用户创建。它不知道“presentViewController()”函数。不允许在iPhone上调用“presentPopoverFromRect()”函数(抛出有关iPad的错误)。显然我也错过了一些论点(“???”部分)。

希望我没有忘记任何重要的事情。提前致谢

1 个答案:

答案 0 :(得分:0)

经过几个小时的尝试,我得到了它的工作。与this教程视频一起展示了如何使用XIB文件中的视图和来自@matt的评论,我实现了从UIControls显示弹出窗口。

为了实例化我的XIB文件,我创建了一个像这样的UIView sublcass:

import UIKit

class LinkAreaPopupView: UIView {

    // outlets
    @IBOutlet var view: UIView!

    @IBOutlet weak var btnDeleteArea: UIButton!
    @IBOutlet weak var btnLinkTo: UIButton!

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        NSBundle.mainBundle().loadNibNamed("LinkAreaPopupView", owner: self, options: nil)
        self.addSubview(self.view)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)

        NSBundle.mainBundle().loadNibNamed("LinkAreaPopupView", owner: self, options: nil)
        self.addSubview(self.view)
    }
}

然后在我的UIControl sublcass中创建弹出窗口的函数我添加了这个:

// long press gesture: show additional control elements
    func showLongPressMenu(recognizer: UILongPressGestureRecognizer) {

        if recognizer.state == UIGestureRecognizerState.Began {
            // approach 3 - https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch09p477popoversOnPhone/PopoverOnPhone/ViewController.swift
            let vc = UIViewController()
            vc.preferredContentSize = CGSizeMake(137.0, 28.0)
            vc.modalPresentationStyle = .Popover

            if let pres = vc.popoverPresentationController {
                pres.delegate = self
            }

            (self.delegate as! UIViewController).presentViewController(vc, animated: true, completion: nil)

            let popView = LinkAreaPopupView()
            vc.view.addSubview(popView)
            popView.frame = vc.view.bounds
            popView.autoresizingMask = .FlexibleWidth | .FlexibleHeight

            if let pop = vc.popoverPresentationController {
                pop.sourceView = (self as UIView)
                pop.sourceRect = (self as UIView).bounds
            }
        }
    }

缺少的拼图是将UIControl的委托设置为位于其下的UIViewController。最后我不得不施放(self.delegate as! UIViewController),因为我之前已经为该代表实现了自己的协议,这就是我无法在其上调用.presentViewController(vc, animated: true, completion: nil)的原因。

瞧。