问题 在Swift中从UIButton创建一个popover


我希望创建一个小型的popover 50x50px 从一个 UIButton。我已经看过使用自适应segue的方法,但是我的大小类转向因此意味着我不能使用这个功能!

我怎么能创建这个popover?我可以使用我的按钮内的代码创建它 IBACtion?或者我还能用故事板做到这一点吗?


7555
2018-03-18 21:21


起源



答案:


您可以执行以下两个选项之一:

  • 为...创建一个动作 UIButton 在你的 UIViewController 在里面呈现 ViewController 你想要像一个Popover和你的 UIViewController 必须实施该协议 UIPopoverPresentationControllerDelegate,看看下面的代码:

    @IBAction func showPopover(sender: AnyObject) {
    
        var popoverContent = self.storyboard?.instantiateViewControllerWithIdentifier("StoryboardIdentifier") as! UIViewController
    
        popoverContent.modalPresentationStyle = .Popover
        var popover = popoverContent.popoverPresentationController
    
        if let popover = popoverContent.popoverPresentationController {
    
           let viewForSource = sender as! UIView
           popover.sourceView = viewForSource
    
           // the position of the popover where it's showed
           popover.sourceRect = viewForSource.bounds
    
           // the size you want to display
           popoverContent.preferredContentSize = CGSizeMake(200,500)
           popover.delegate = self
        }            
    
        self.presentViewController(popoverContent, animated: true, completion: nil)
    }
    
    func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
       return .None
    }
    

    根据@matt的书 iOS 8编程

    iOS 8中的弹出窗口控制器是一个演示控制器(UIPresentationController),演示控制器是自适应的。这意味着,默认情况下,在水平紧凑的环境中(即在iPhone上), .Popover 模态演示风格将被视为 .FullScreen。在iPad上显示为popover的内容将在iPhone上显示为全屏显示视图,完全取代界面。

    要避免在iPhone中出现这种情况,您需要实现委托方法 adaptivePresentationStyleForPresentationController 你的内心 UIViewController 正确显示Popover。

  • 在我看来,另一种方式更容易做,并且正在使用Interface Builder,只需从中进行排列 UIButton 创造一个segue到 ViewController 你想要并在segue中选择 Popover Segue公司。

我希望这对你有帮助。


10
2018-03-18 22:16



谢谢你!第一个例子有效,但它看起来似乎是大小。 popover只是全屏显示。我认为你解释的第二种方式将是一种更好的方式..但我再一次得到一个错误无法遵守连接IBCocoaTouchoutlet锚视图。你能给我一些符合你解释的第二种方式的代码吗? - user4671001
@ user4671001我不明白,在seconde方式中你不需要设置anchoView - Victor Sigler
popover在iphone上显示为全屏模式,您可以通过添加此功能来禁用此功能:func adaptivePresentationStyleForPresentationController(PC: UIPresentationController!) -> UIModalPresentationStyle { // This *forces* a popover to be displayed on the iPhone return .None } - user1076813
在Swift2中也是如此。 Xcode显示有关锚点的错误。有解决方案? - lukaivicev
@lukesIvi您不必在上面的代码中设置锚点,代码可以在iOS 9和Swift2中运行。 - Victor Sigler


答案:


您可以执行以下两个选项之一:

  • 为...创建一个动作 UIButton 在你的 UIViewController 在里面呈现 ViewController 你想要像一个Popover和你的 UIViewController 必须实施该协议 UIPopoverPresentationControllerDelegate,看看下面的代码:

    @IBAction func showPopover(sender: AnyObject) {
    
        var popoverContent = self.storyboard?.instantiateViewControllerWithIdentifier("StoryboardIdentifier") as! UIViewController
    
        popoverContent.modalPresentationStyle = .Popover
        var popover = popoverContent.popoverPresentationController
    
        if let popover = popoverContent.popoverPresentationController {
    
           let viewForSource = sender as! UIView
           popover.sourceView = viewForSource
    
           // the position of the popover where it's showed
           popover.sourceRect = viewForSource.bounds
    
           // the size you want to display
           popoverContent.preferredContentSize = CGSizeMake(200,500)
           popover.delegate = self
        }            
    
        self.presentViewController(popoverContent, animated: true, completion: nil)
    }
    
    func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
       return .None
    }
    

    根据@matt的书 iOS 8编程

    iOS 8中的弹出窗口控制器是一个演示控制器(UIPresentationController),演示控制器是自适应的。这意味着,默认情况下,在水平紧凑的环境中(即在iPhone上), .Popover 模态演示风格将被视为 .FullScreen。在iPad上显示为popover的内容将在iPhone上显示为全屏显示视图,完全取代界面。

    要避免在iPhone中出现这种情况,您需要实现委托方法 adaptivePresentationStyleForPresentationController 你的内心 UIViewController 正确显示Popover。

  • 在我看来,另一种方式更容易做,并且正在使用Interface Builder,只需从中进行排列 UIButton 创造一个segue到 ViewController 你想要并在segue中选择 Popover Segue公司。

我希望这对你有帮助。


10
2018-03-18 22:16



谢谢你!第一个例子有效,但它看起来似乎是大小。 popover只是全屏显示。我认为你解释的第二种方式将是一种更好的方式..但我再一次得到一个错误无法遵守连接IBCocoaTouchoutlet锚视图。你能给我一些符合你解释的第二种方式的代码吗? - user4671001
@ user4671001我不明白,在seconde方式中你不需要设置anchoView - Victor Sigler
popover在iphone上显示为全屏模式,您可以通过添加此功能来禁用此功能:func adaptivePresentationStyleForPresentationController(PC: UIPresentationController!) -> UIModalPresentationStyle { // This *forces* a popover to be displayed on the iPhone return .None } - user1076813
在Swift2中也是如此。 Xcode显示有关锚点的错误。有解决方案? - lukaivicev
@lukesIvi您不必在上面的代码中设置锚点,代码可以在iOS 9和Swift2中运行。 - Victor Sigler


斯威夫特4 这是完全有效的代码。所以在这里你会看到大小为250x250的弹出窗口:

    import UIKit

    class ViewController: UIViewController {

        @IBOutlet weak var button: UIButton!

        override func viewDidLoad() {
            super.viewDidLoad()

// in case if you don't want to make it via IBAction
            button.addTarget(self, action: #selector(tapped), for: .touchUpInside)
        }

        @objc
        private func tapped() {

            guard let popVC = storyboard?.instantiateViewController(withIdentifier: "popVC") else { return }

            popVC.modalPresentationStyle = .popover

            let popOverVC = popVC.popoverPresentationController
            popOverVC?.delegate = self
            popOverVC?.sourceView = self.button
            popOverVC?.sourceRect = CGRect(x: self.button.bounds.midX, y: self.button.bounds.minY, width: 0, height: 0)
            popVC.preferredContentSize = CGSize(width: 250, height: 250)

            self.present(popVC, animated: true)
        }
    }


// This is we need to make it looks as a popup window on iPhone
    extension ViewController: UIPopoverPresentationControllerDelegate {

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

请注意,您必须为要作为弹出窗口呈现的一个viewController提供popVC标识符。

希望有所帮助!


4
2018-01-26 03:23



你能在objective-c中提供这段代码吗?请检查我的问题 stackoverflow.com/questions/51308025/... - Chandan Jee


在这里,您可以在按钮单击时显示弹出框。

func addCategory( _ sender : UIButton) {

        var popoverContent = self.storyboard?.instantiateViewControllerWithIdentifier("NewCategory") as UIViewController
        var nav = UINavigationController(rootViewController: popoverContent)
        nav.modalPresentationStyle = UIModalPresentationStyle.Popover
        var popover = nav.popoverPresentationController
        popoverContent.preferredContentSize = CGSizeMake(50,50)
        popover.delegate = self
        popover.sourceView = sender
        popover.sourceRect = sender.bounds

        self.presentViewController(nav, animated: true, completion: nil)

    }

2
2017-12-08 06:37