You'll want your view controller to have some explicit model/state of what the value of these sliders have. e.g.
class ViewController : NSViewController {
var value: Double
}
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:
@IBAction func sliderValueChanged(_ sender: NSSlider) {
value = sender.doubleValue
}
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:
@IBOutlet weak var touchBarSlider: NSSlider!
@IBOutlet weak var windowSlider: NSSlider!
@IBOutlet weak var windowTextField: NSTextField!
var value: Double {
didSet {
touchBarSlider.doubleValue = value
windowSlider.doubleValue = value
windowTextField.doubleValue = value
}
}
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:
class ViewController: NSViewController {
@objc dynamic var value: Double
}
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's value
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 the didSet
observer for value
to make other changes that you can't do with bindings)