【问题标题】:How to present a UIViewController as a popover in Swift programmatically on iPhone如何在 iPhone 上以编程方式在 Swift 中将 UIViewController 呈现为弹出框
【发布时间】:2016-04-05 06:33:44
【问题描述】:

通常我遵循此处的说明:https://stackoverflow.com/a/24687152/3741933

但是,正如其 cmets 中所讨论的,无论preferredContentSizesourceRect 是什么,弹出框始终是全屏的。

显示弹出框的按钮:

func buttonClicked(sender: UIButton!) {
    let ac = EmptyViewController() as UIViewController
    ac.modalPresentationStyle = .Popover
    ac.preferredContentSize = CGSizeMake(200, 200)
    let popover = ac.popoverPresentationController
    popover?.delegate = self
    popover?.permittedArrowDirections = .Any
    popover?.sourceView = self.view
    popover?.sourceRect = CGRect(x: 100, y: 100, width: 100, height: 100)

    presentViewController(ac, animated: true, completion: nil)
}

UIViewController:

import UIKit

class EmptyViewController : UIViewController {
    override func viewDidLoad() {
        view.backgroundColor = UIColor.redColor()
    }
}

我想知道如何使它成为一个真正的弹出框(不是全屏尺寸)。顺便说一句,正如@EI Captain 所说,它在 iPad 上完美运行,但在 iPhone 上总是全屏。

【问题讨论】:

  • 在 iPhone 中具有纵向模式,此代码弹出框始终全屏显示...在 iPad 中完美运行...仍然检查此richardallen.me/2014/11/28/popovers.html
  • @EICaptain 你说得对,它在 iPad 上完美运行。但是本教程正在使用 IB。我想知道如何使它以编程方式工作。
  • 可能您需要为此制作自定义视图或使用任何库
  • 可能对你有帮助...github.com/corin8823/Popover

标签: ios swift uiviewcontroller popover


【解决方案1】:

对于那些正在寻找如何不使用 segue 的人 ?

import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .systemBackground
        
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.setImage(UIImage(systemName: "square.grid.2x2.fill"), for: .normal)
        button.addTarget(self, action: #selector(displayPopover), for: .touchUpInside)
        self.view.addSubview(button)
        
        NSLayoutConstraint.activate([
            button.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 100),
            button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            button.widthAnchor.constraint(equalToConstant: 40),
            button.heightAnchor.constraint(equalToConstant: 40),
        ])
        
    }
    
    @IBAction func displayPopover(sender: UIButton!) {
        let popoverVC = PopoverViewController()
        popoverVC.modalPresentationStyle = .popover
        popoverVC.popoverPresentationController?.sourceView = sender
        popoverVC.popoverPresentationController?.permittedArrowDirections = .up
        popoverVC.popoverPresentationController?.delegate = self
        self.present(popoverVC, animated: true, completion: nil)
    }
}

extension UIViewController: UIPopoverPresentationControllerDelegate {
    public func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
        return .none
    }
}

class PopoverViewController: UIViewController {
    override func viewDidLoad() {
        self.view.backgroundColor = .systemGray
        self.preferredContentSize = CGSize(width: 300, height: 200)
    }
}

iPhone 11 Pro Max 的结果@?

【讨论】:

    【解决方案2】:

    有可能!我不知道从什么时候开始......

    在您的UIViewControllerviewDidLoad 中显示为弹出框:

        self.preferredContentSize = CGSize(width: myWidth, height: myHeight)
    

    在显示弹出框的UIViewController 中,将类设置为UIPopoverPresentationControllerDelegate 并且:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    
        if segue.identifier == "Identifier" {
            let vc: UIViewController = segue.destination
    
            let pvc = vc.popoverPresentationController
            pvc?.delegate = self
            return
        }
    
    }
    
    func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
        return .none
    }
    

    PS:在storyboard中,不要忘记将segue kind设置为“Present As Popover”

    就是这样!

    【讨论】:

    • 没有segue怎么办?
    【解决方案3】:

    您不能在 iPhone 中使用此代码在纵向模式下执行此操作...您可以查看popover section in apple doc here..

    这表明:

    在 iOS 8 及更高版本中,您使用 UIPopoverPresentationController 来呈现弹出框。 UIPopoverPresentationController 定义了一个委托,允许您调整弹出内容的显示样式以适应当前的显示环境。例如,在水平规则的环境中,您的内容可以显示在弹出框内; 在水平紧凑的环境中,您的内容可以在全屏模式视图中显示。

    正如我所说,如果您可以签入 iPad,您的内容可以显示在弹出框内。

    【讨论】:

      【解决方案4】:

      你只需要实现UIPopoverPresentationControllerDelegate协议的下一个方法:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-02-17
        • 1970-01-01
        • 2016-03-19
        • 1970-01-01
        • 2015-08-02
        • 2015-10-20
        • 2015-01-24
        相关资源
        最近更新 更多