ios 在 Swift 中从 UIButton 创建弹出框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29132940/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 05:15:32  来源:igfitidea点击:

Creating a popover from a UIButton in Swift

iosswiftuibuttonpopover

提问by user4671001

I wish to create a small popover about 50x50pxfrom a UIButton. I have seen methods using adaptive segue's but I have my size classes turn of thus meaning I can not use this features!

我希望50x50pxUIButton. 我见过使用自适应 segue 的方法,但我的尺寸类变成了这样,这意味着我无法使用此功能!

How else can I create this popover? Can I create it with code inside my button IBACtion? Or is there still a way I can do this with storyboards?

我还能如何创建这个弹出窗口?我可以使用按钮内的代码创建它IBACtion吗?或者我还有办法用故事板来做到这一点吗?

回答by Victor Sigler

You can do one of the following two options :

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

  • Create an action for the UIButtonin your UIViewControllerand inside present the ViewControlleryou want like a Popover and your UIViewControllerhas to implement the protocol UIPopoverPresentationControllerDelegate, take a look in the following code :

    @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
    }
    

    According to the book of @matt Programming iOS 8:

    A popover presentation controller, in iOS 8, is a presentation controller (UIPresentationController), and presentation controllers are adaptive. This means that, by default, in a horizontally compact environment (i.e. on an iPhone), the .Popovermodal presentation style will be treated as .FullScreen. What appears as a popover on the iPad will appear as a fullscreen presented view on the iPhone, completely replacing the interface.

    To avoid this behavior in the iPhone you need to implement the delegate method adaptivePresentationStyleForPresentationControllerinside your UIViewControllerto display the Popover correctly.

  • The other way in my opinion is more easy to do, and is using Interface Builder, just arrange from the UIButtonto create a segue to the ViewControlleryou want and in the segue select the Popoversegue.

  • UIButtonUIViewControllerViewController您想要的 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 Programming iOS 8的书:

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

    为了避免在 iPhone 中出现这种行为,您需要adaptivePresentationStyleForPresentationController在您的内部实现委托方法 UIViewController以正确显示 Popover。

  • 在我看来,另一种方法更容易做到,并且是使用 Interface Builder,只需安排从UIButton创建转场到ViewController您想要的转场,然后在转场中选择转场Popover

I hope this help you.

我希望这对你有帮助。

回答by wm.p1us

Swift 4Here is fully working code. So here you will see popup window with size of 250x250:

Swift 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
        }
    }

Take into attention that you have to provide popVC identifier to one viewController you want to present as a popup.

请注意,您必须向要显示为弹出窗口的视图控制器提供 popVC 标识符。

Hope that helps!

希望有帮助!

回答by Usman Javed

Here you can present a popover on button click.

在这里,您可以在单击按钮时显示一个弹出窗口。

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)

    }

回答by Korpel

Swift 4 Version

斯威夫特 4 版本

Doing most work from the storyboard

从故事板中完成大部分工作

I added a ViewController, went to it's attribute inspector and ticked the "Use Preferred Explicit size". After that I changed the Width and Height values to 50 each.

我添加了一个ViewController,转到它的属性检查器并勾选“使用首选显式大小”。之后,我将 Width 和 Height 值分别更改为 50。

Once this was done I ctrl clicked and dragged from the Button to the ViewControllerI added choosing "Present as Popover" and naming the segue Identifier as "pop"

完成此操作后,我按 ctrl 单击并从 Button 拖动到ViewController我添加的选择“Present as Popover”并将 segue 标识符命名为“pop”

Went to the ViewControllerwhere I had my Button and added the following code:

去了ViewController我有我的按钮的地方并添加了以下代码:

class FirstViewController: UIViewController, UIPopoverPresentationControllerDelegate {
    @IBOutlet weak var popoverButton: UIButton! // the button

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "pop" {
            let popoverViewController = segue.destination
            popoverViewController.modalPresentationStyle = .popover
            popoverViewController.presentationController?.delegate = self
            popoverViewController.popoverPresentationController?.sourceView = popoverButton
            popoverViewController.popoverPresentationController?.sourceRect  = CGRect(x: 0, y: 0, width: popoverButton.frame.size.width, height: popoverButton.frame.size.height)
        }
    }
    func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
        return UIModalPresentationStyle.none
    }



    override func viewDidLoad() {
        super.viewDidLoad()
    }

}