How do I control popover invoked by segue?

In IB I connect a button to a VC and set the segue kind to 'Popover'. Now I have a problem. How do I get the NSPopover and its delegate?

-(void)prepareForSegue:(NSStoryboardSegue *)segue sender:(id)sender {

    NSLog(@"%s: %@", __func__, segue.destinationController);

    NSViewController* vc = segue.destinationController;

}

Accepted Reply

I tested this:

  • In the calling VC (class is InitialViewController), create a func:
    func handleClosePopover() {
        print("Popover was closed")
    }
  • Implement the delegate func popoverDidClose in the popoverController
class SeguedViewController: NSViewController, NSPopoverDelegate {

    @IBOutlet weak var label: NSTextField!
    
    var labelContent : String?
    var delegate: InitialViewController?  // Must be InitialViewController
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
        label.stringValue = labelContent ?? "empty"
    }
    
    func popoverDidClose(_ notification: Notification) {
        delegate?.handleClosePopover()
    }
    
}

Hope that helps.

  • This sure works. I thought I could get the instance of NSPopover somehow and set its delegate property instead.

Add a Comment

Replies

Could you explain precisely what you mean by "getting" the NSPopover and its delegate ? Which delegate ?

If I understand what you want, I would define a class for the popover and declare a delegate there (that's Swift, but easy to adapt to objC):

class SeguedViewController: NSViewController {

    @IBOutlet weak var label: NSTextField!
    
    var labelContent : String?
    var delegate: NSViewController?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
        label.stringValue = labelContent ?? "empty"
    }
    
}

And define them in tha calling VC

    override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
        if let dest = segue.destinationController as? SeguedViewController {
            dest.labelContent = "I passed text"
            dest.delegate = self // For instance
        }
    }

Sorry for not stating my question clear enough. What I want is NSPopoverDelegate so that I know when the popover is closed so that I can perform some work accordingly.

I tested this:

  • In the calling VC (class is InitialViewController), create a func:
    func handleClosePopover() {
        print("Popover was closed")
    }
  • Implement the delegate func popoverDidClose in the popoverController
class SeguedViewController: NSViewController, NSPopoverDelegate {

    @IBOutlet weak var label: NSTextField!
    
    var labelContent : String?
    var delegate: InitialViewController?  // Must be InitialViewController
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do view setup here.
        label.stringValue = labelContent ?? "empty"
    }
    
    func popoverDidClose(_ notification: Notification) {
        delegate?.handleClosePopover()
    }
    
}

Hope that helps.

  • This sure works. I thought I could get the instance of NSPopover somehow and set its delegate property instead.

Add a Comment