Swift:如何 link Touch Bar 控件为主 window 控件
Swift: How to link Touch Bar controls to main window controls
我是 Swift/macOS 开发的新手,但在其他方面有很多开发经验。只是想做一些基本的东西。
这是我的应用故事板:
我正在尝试获取:
- 当主 window 上的滑块发生变化时,Touch Bar 滑块也会发生变化
- 反之亦然
- 使用滑块的 Int 值更新 Touch Bar Label 按钮。
问)如何实现?
注意:主要的 window 滑块控件已连接并在我操作时工作,例如
@IBOutlet weak var mySlider: NSSlider!
@IBAction func mySlider_Changed(_ sender: NSSlider) {
//... stuff happens here.
}
您会希望您的视图控制器明确 model/state 这些滑块的值。例如
class ViewController : NSViewController {
var value: Double
}
然后您可以连接滑块和文本框来更新或显示这个值。
方法一:Target/Action/SetValue
这是在使用您已启动的显式 IBAction 之后。作为对该动作的响应,我们将从滑块中拉出 doubleValue 并从中更新 ViewController 的模型:
@IBAction func sliderValueChanged(_ sender: NSSlider) {
value = sender.doubleValue
}
第二部分是更新所有内容以反映新值。使用 Swift,我们可以仅在 ViewController 的值 属性 上使用 didSet
观察器来了解它何时更改并更新所有控件,例如:
@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
}
}
就是这样。您可以将数字格式化程序添加到文本字段,以便它很好地显示值,您可以在 Interface Builder 中或以编程方式执行此操作。任何其他时间您更改该值,所有控件仍会更新,因为它们是在 didSet
观察器中更新的,而不仅仅是滑块操作方法。
方法 2:绑定
在将模型数据连接到视图时,Bindings 可以消除很多样板代码。
使用绑定,您可以摆脱 outlets 和 action 方法,视图控制器中唯一剩下的就是:
class ViewController: NSViewController {
@objc dynamic var value: Double
}
@objc dynamic
makes the property be KVO compliant,使用绑定时需要
另一部分是建立从控件到我们 ViewController 的 value
属性 的绑定。对于所有控件,这是通过绑定检查器窗格完成的,将控件的 'Value' 绑定到视图控制器的 value
键路径:
就是这样。同样,您可以向文本字段添加一个数字格式化程序,并且对 value
属性 的任何其他更改仍将更新您的控件,因为它会触发对其的绑定。 (您仍然可以使用 value
的 didSet
观察器来进行绑定无法进行的其他更改)
我是 Swift/macOS 开发的新手,但在其他方面有很多开发经验。只是想做一些基本的东西。
这是我的应用故事板:
我正在尝试获取:
- 当主 window 上的滑块发生变化时,Touch Bar 滑块也会发生变化
- 反之亦然
- 使用滑块的 Int 值更新 Touch Bar Label 按钮。
问)如何实现?
注意:主要的 window 滑块控件已连接并在我操作时工作,例如
@IBOutlet weak var mySlider: NSSlider!
@IBAction func mySlider_Changed(_ sender: NSSlider) {
//... stuff happens here.
}
您会希望您的视图控制器明确 model/state 这些滑块的值。例如
class ViewController : NSViewController {
var value: Double
}
然后您可以连接滑块和文本框来更新或显示这个值。
方法一:Target/Action/SetValue
这是在使用您已启动的显式 IBAction 之后。作为对该动作的响应,我们将从滑块中拉出 doubleValue 并从中更新 ViewController 的模型:
@IBAction func sliderValueChanged(_ sender: NSSlider) {
value = sender.doubleValue
}
第二部分是更新所有内容以反映新值。使用 Swift,我们可以仅在 ViewController 的值 属性 上使用 didSet
观察器来了解它何时更改并更新所有控件,例如:
@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
}
}
就是这样。您可以将数字格式化程序添加到文本字段,以便它很好地显示值,您可以在 Interface Builder 中或以编程方式执行此操作。任何其他时间您更改该值,所有控件仍会更新,因为它们是在 didSet
观察器中更新的,而不仅仅是滑块操作方法。
方法 2:绑定
在将模型数据连接到视图时,Bindings 可以消除很多样板代码。
使用绑定,您可以摆脱 outlets 和 action 方法,视图控制器中唯一剩下的就是:
class ViewController: NSViewController {
@objc dynamic var value: Double
}
@objc dynamic
makes the property be KVO compliant,使用绑定时需要
另一部分是建立从控件到我们 ViewController 的 value
属性 的绑定。对于所有控件,这是通过绑定检查器窗格完成的,将控件的 'Value' 绑定到视图控制器的 value
键路径:
就是这样。同样,您可以向文本字段添加一个数字格式化程序,并且对 value
属性 的任何其他更改仍将更新您的控件,因为它会触发对其的绑定。 (您仍然可以使用 value
的 didSet
观察器来进行绑定无法进行的其他更改)