如何在 iPhone 上以编程方式在 Swift 中将 UIViewController 呈现为弹出框
Posted
技术标签:
【中文标题】如何在 iPhone 上以编程方式在 Swift 中将 UIViewController 呈现为弹出框【英文标题】:How to present a UIViewController as a popover in Swift programmatically on iPhone 【发布时间】:2016-04-05 06:33:44 【问题描述】:通常我遵循此处的说明:https://***.com/a/24687152/3741933。
但是,正如其 cmets 中所讨论的,无论preferredContentSize
或sourceRect
是什么,弹出框始终是全屏的。
显示弹出框的按钮:
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 【参考方案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】:有可能!我不知道从什么时候开始......
在您的UIViewController
的viewDidLoad
中显示为弹出框:
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
【讨论】:
以上是关于如何在 iPhone 上以编程方式在 Swift 中将 UIViewController 呈现为弹出框的主要内容,如果未能解决你的问题,请参考以下文章
如何在 macOS 上以编程方式在 Swift 中添加 NSView [重复]