【问题标题】:Real popover view programmatically on iPhone在 iPhone 上以编程方式的真实弹出视图
【发布时间】:2015-08-02 20:16:54
【问题描述】:

编辑: 添加了方法 3(参见下面的 cmets)。

我想在我的应用程序中创建小弹出框,但我无法使用情节提要,因为这些弹出框的锚点将是用户创建的 UIControls。

我想创建像here 所述的真实 弹出框(不是全屏弹出框)。使用故事板效果很好,但在这种情况下,我需要它在没有转场的情况下工作。

我还发现this post 那里的人试图做一些非常相似的事情。我尝试在 //approach 1 中使用该帖子中的解决方案。在 //approach 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 的错误)。显然我也遗漏了一些论点(“???”部分)。

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

【问题讨论】:

  • 在 iOS 8 中,iPhone 上的真实弹窗是合法的、正常的、内置的。示例代码:github.com/mattneub/Programming-iOS-Book-Examples/blob/master/…
  • 感谢@matt!还有几个问题:我需要用什么替换let f = NSBundle.mainBundle().pathForResource("linkhelp", ofType: "html") let s = String(contentsOfFile: f!, encoding: NSUTF8StringEncoding, error: nil) wv.loadHTMLString(s, baseURL: nil)?我认为这是我加载我的 XIB 文件的地方?那么我将如何在我的项目中使用这个类呢?
  • 当然,但这无关紧要。我只是向你展示它是有效的。
  • 也许我在这里有点失明,但仍然无法让它工作。我在上面的帖子中将您的代码添加为 //approach 3。问题是 UIControls 不能调用 presentViewController()。我必须在哪里执行此操作?我尝试在 self.superview 上调用它,但是它说“不能使用 [..] 类型的参数列表调用 [..]。

标签: ios iphone swift uipopovercontroller popover


【解决方案1】:

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

为了实例化我的 XIB 文件,我创建了一个 UIView 子类,如下所示:

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 子类中创建弹出窗口的函数中我添加了这个:

// 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)。

瞧。

【讨论】:

    猜你喜欢
    • 2016-07-22
    • 1970-01-01
    • 2018-06-25
    • 2019-10-24
    • 2023-03-20
    • 2012-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多