Search code examples
swiftmacosswift-playgroundappkit

NSPopUpButton Grayed Out in Swift Playground


In the Swift playground view controller I have the following code:

var jsonSelector = NSPopUpButton(title: "Path", target: self, action: #selector(updatePointFile))

override public func loadView() {
    let frame = CGRect(origin: CGPoint.zero, size: CGSize(width: 900, height: 600))
    let view = NSView(frame: frame)

    let array = // gets array of items
    for item in array {
        jsonSelector.addItem(withTitle: item)
    }

    view.addSubview(jsonSelector)
    self.view = view
}

@objc func updatePointFile() {
    let file = jsonSelector.selectedItem?.title ?? "swiftLogo"
    ...
}

When it runs it initially looks normal:
normal

But then once it is clicked it looks like:
broken

And when you click away it stays unclickable:
still broken

When I copy the exact same code into a full mac app it works like normal, and to make things even weirder, one time when I was taking those screenshots it worked for once selection and returned to it's grayed out state.

Any assistance would be greatly appreciated.


Solution

  • So the solution to this is kinda weird. It just requires defining the target later.

    That means either

    var jsonSelector = NSPopUpButton(frame: NSRect(origin: CGPoint.zero, size: CGSize(width: 100, height: 50)))
    
    override public func loadView() {
        jsonSelector.target = self
            jsonSelector.action = #selector(updatePointFile)
    
        let array = // gets array of items
        for item in array {
            jsonSelector.addItem(withTitle: item)
        }
    
        view.addSubview(jsonSelector)
        self.view = view
    }
    
    @objc func updatePointFile() {
        let file = jsonSelector.selectedItem?.title ?? "swiftLogo"
        ...
    }
    

    or

    var jsonSelector = NSPopUpButton(title: "Path", target: self, action: #selector(updatePointFile))
    
    override public func loadView() {
        let frame = CGRect(origin: CGPoint.zero, size: CGSize(width: 900, height: 600))
        let view = NSView(frame: frame)
    
        jsonSelector.target = self
    
        let array = // gets array of items
        for item in array {
            jsonSelector.addItem(withTitle: item)
        }
    
        view.addSubview(jsonSelector)
        self.view = view
    }
    
    @objc func updatePointFile() {
        let file = jsonSelector.selectedItem?.title ?? "swiftLogo"
        ...
    }
    

    works