简体   繁体   中英

macOS: Correct way of exposing Swift properties to Cocoa Bindings

I'm working on an existing Swift/Objective-C project on the Mac and I'm creating some UI in code. I enable a button based on the selection in a NSTableView that I manage without using NSArrayController (for reasons).

I have a property selectionIndexes on MyController :

@objc var selectionIndexes : IndexSet = IndexSet()

I'm not sure whether the @objc is necessary to make it visible to the Cocoa Bindings system.

I connect the button's enabled binding using:

newButton.bind(NSBindingName.enabled, to: MyController.sharedInstance,
     withKeyPath: "selectionIndexes", 
     options: [NSBindingOption.valueTransformer : MyTransformer()])

This works fine, the transformer is called with the correct property and enabled is set correcty, but changes to the selection do not trigger the binding , so the button remains disabled.

I had to explicitly tell the system that I'm changing the value, eg

self.willChangeValue(for: \.selectionIndexes )
self.selectionIndexes = proposedSelectionIndexes
self.didChangeValue(for: \.selectionIndexes)

This seems pretty lame. Is there a better way of doing this?

@objc is necessary to expose the property to the Objective-C runtime.

To make the property key-value observing compliant you have to add the dynamic keyword

@objc dynamic var selectionIndexes = IndexSet()

and delete the ...ChangeValue(for lines

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM