Peter Shaw
Peter Shaw

Reputation: 1907

NSButton with popover programmatically

I have a question regarding dynamic button creation with popovers. First let me show you a Storyboard version of a PoC to demonstrate what I want to do:

enter image description here

If i press the button, the new ViewController show up upon the button that is pressed:

enter image description here

Ok so far. That is the task. But now I have to add the buttons programmatically and add them into a stackView.

The prototype code:

class ViewController: NSViewController {

    @IBOutlet weak var stackView: NSStackView!

    override func viewDidLoad() {
        super.viewDidLoad()
        for i in (1...5) {
            addButton(i)
        }
    }

    func addButton(_ i: Int){
        let button = NSButton(title: "TAG Button \(i)", target: nil,     action: nil)
        stackView.addArrangedSubview(button)
    }

}

It looks good:

enter image description here

My question is: how would you do the popover over each button. Should I add it programmatically too, or should i use some sort of Storyboard and reuse a view? How would you solve the issue that it is nice and smooth and refactorable?

If you have a minute, can you please consider the pro and cons with a short introduction how to implement it?

The buttons I add will be tags I have to made clickable for further information and actions.

+++++UPDATE++++

I've made up the popup view controller in SB. My button has a click target and calls a function. That's fine and seams very usable. But how can I segue the popup from the button?

@objc func click(_ sender: NSButton?){
    let sb = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil)
    if let vc: NSViewController = sb.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("TagPopupViewController")) as? NSViewController {

         // how to set the vc as popover over the button?
    }
}

sender does not have a presentViewController-function.

Upvotes: 1

Views: 2293

Answers (1)

Peter Shaw
Peter Shaw

Reputation: 1907

Ah, ok, I can use: presentViewController(vc, asPopoverRelativeTo: (sender?.bounds)!, of: sender!, preferredEdge: NSRectEdge.maxX, behavior: NSPopover.Behavior.transient)

so the whole code:

class ViewController: NSViewController {

@IBOutlet weak var stackView: NSStackView!

override func viewDidLoad() {
    super.viewDidLoad()
    for i in (1...5) {
        addButton(i)
    }
}

func addButton(_ i: Int){
    let button = NSButton(title: "TAG Button \(i)", target: nil, action: nil)
    button.target = self
    button.action = #selector(self.click)
    stackView.addArrangedSubview(button)

}

@objc func click(_ sender: NSButton?){
    let sb = NSStoryboard(name: NSStoryboard.Name("Main"), bundle: nil)
    if let vc: NSViewController = sb.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("TagPopupViewController")) as? NSViewController {

        presentViewController(vc, asPopoverRelativeTo: (sender?.bounds)!, of: sender!, preferredEdge: NSRectEdge.maxX, behavior: NSPopover.Behavior.transient)
    }
}

}

Thanks

What Willeke!.

Upvotes: 1

Related Questions