在Swift中从UIButton创建一个弹出窗口

16

我希望创建一个从UIButton弹出的小型弹出窗口,大小约为50x50px。我看到过使用自适应转场的方法,但我的尺寸类已关闭,意味着我无法使用此功能!

除此之外,我还能用其他方式创建这个弹出窗口吗?我能否在IBACtion中使用代码创建它?或者还有其他使用storyboards的方法吗?

4个回答

15
你可以选择以下两个选项:
  • Create an action for the UIButton in your UIViewController and inside present the ViewController you want like a Popover and your UIViewController has 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 .Popover modal 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 adaptivePresentationStyleForPresentationController inside your UIViewController to display the Popover correctly.

  • The other way in my opinion is more easy to do, and is using Interface Builder, just arrange from the UIButton to create a segue to the ViewController you want and in the segue select the Popover segue.

我希望这能帮助你。

谢谢!第一个示例可以工作,但大小似乎没有改变。气泡窗口只是全屏出现。我认为你解释的第二种方式会更好。但我又一次收到错误,“无法符合连接IBCocoaTouchoutlet锚定视图”。您能给我一些与您解释的第二种方式相配套的代码吗? - user4671001
4
在iPhone上,弹出框会显示为全屏模态窗口,你可以通过添加以下函数来禁用它:func adaptivePresentationStyleForPresentationController(PC: UIPresentationController!) -> UIModalPresentationStyle { // This *forces* a popover to be displayed on the iPhone return .None }。请注意,此函数将强制在iPhone上显示弹出框。 - user1076813
@lukesIvi 你不需要在上面的代码中设置锚点,这段代码适用于iOS 9和Swift2。 - Victor Sigler
你能在Github上发送一个代码库吗?我正在尝试从viewControllerOne传递URL到url VC并在不传递数据的情况下从viewControllerOne转到另一个viewController。相反,我只想发送到URL VC,然后立即返回而无需重新加载VCOne的数据。有什么想法吗? - Lukesivi
请稍等,我将上传一个代码库并更新我的回答中的一些主题。 - Victor Sigler
显示剩余5条评论

11

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

请注意,您需要为要作为弹出窗口呈现的一个视图控制器提供popVC标识符。
希望这能帮到您!

你能提供这段代码的Objective-C版本吗?请查看我的问题:https://stackoverflow.com/questions/51308025/how-to-create-popover-clicked-on-button - Chandan Jee

2

在此您可以通过按钮点击展示一个弹出窗口。

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)

    }

1

Swift 4版本

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

我添加了一个ViewController,转到其属性检查器并选中“使用首选显式大小”。然后,我将宽度和高度值更改为50。

完成这一步骤后,我通过Ctrl单击并从按钮拖动到我添加的ViewController,选择“作为弹出窗口呈现”并将segue标识符命名为“pop”

转到我有按钮的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()
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接