I'm new to Swift/macOS dev, plenty of dev experience otherwise though. Just trying to make something rudimentary.
Here's my app storyboard:
I'm trying to get:
- the Touch Bar slider to change when the slider on the main window changes
- vice versa
- update the Touch Bar Label button with the Int value of the slider.
Q) How do I achieve this?
Note: The main window slider control is wired up and working when I manipulate it e.g.
@IBOutlet weak var mySlider: NSSlider!
@IBAction func mySlider_Changed(_ sender: NSSlider) {
//... stuff happens here.
}
You'll want your view controller to have some explicit model/state of what the value of these sliders have. e.g.
Then you can connect the sliders and textfield to update or display this value.
Approach 1: Target/Action/SetValue
This follows the use of explicit IBActions that you had started. In response to that action, we'll pull the doubleValue from the slider and update the ViewController's model from that:
The second piece is updating everything to reflect that new value. With Swift, we can just use the
didSet
observer on the ViewController's value property to know when it changes and update all of the controls, e.g:And that's it. You can add a number formatter to the textfield so it nicely displays the value, which you can do in Interface Builder or programmatically. And any other time you change the value, all of the controls will still get updated since they are updated in the
didSet
observer instead of just the slider action methods.Approach 2: Bindings
Bindings can eliminate a lot of this boiler plate code when it comes to connecting model data to your views.
With bindings you can get rid of the outlets and the action methods, and have the only thing left in the view controller be:
The
@objc dynamic
makes the property be KVO compliant, which is required when using bindings.The other piece is establishing bindings from the controls to our ViewController's
value
property. For all of the controls this is done by through the bindings inspector pane, binding the 'Value' of the control to the View Controller'svalue
key path:And that's it. Again, you could add a number formatter to the textfield, and any other changes to the
value
property will still update your controls since it will trigger the bindings to it. (you can also still use thedidSet
observer forvalue
to make other changes that you can't do with bindings)