我已经创建了一个子类,NSControl
它是格式化数字NSTextField
和NSStepper
. 这是基本代码:
class StepperWithNumberField: NSControl, NSTextFieldDelegate {
let numberField: NSTextField
let stepper: NSStepper
override var intValue: Int32 {
get {
return stepper.intValue
}
set {
stepper.intValue = newValue
numberField.intValue = newValue
}
}
init(frame: NSRect, numberFieldWidth: CGFloat, minValue: Int32, maxValue: Int32) {
let numberFieldFrame = NSRect(x: 0, y: 0, width: numberFieldWidth, height: frame.height)
let numberField = NSTextField(frame: numberFieldFrame)
numberField.isEditable = true
numberField.alignment = .right
let formatter = NumberFormatter()
formatter.allowsFloats = false
formatter.minimum = minValue as NSNumber
formatter.maximum = maxValue as NSNumber
numberField.formatter = formatter
self.numberField = numberField
let stepper = NSStepper(frame: NSRect(x: numberFieldWidth, y: 0, width: 15, height: frame.height))
stepper.minValue = Double(minValue)
stepper.maxValue = Double(maxValue)
stepper.increment = 1
stepper.valueWraps = false
self.stepper = stepper
super.init(frame: frame)
self.numberField.delegate = self
self.stepper.target = self
self.stepper.action = #selector(self.stepperClicked)
self.addSubview(numberField)
self.addSubview(stepper)
intValue = minValue
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func controlTextDidEndEditing(_ notification: Notification) {
if let nobj = notification.object as? NSTextField {
stepper.intValue = nobj.intValue
}
}
@objc func stepperClicked(sender: NSStepper) {
numberField.intValue = stepper.intValue
}
}
如果我创建一个实例并将其作为子视图添加到我的主视图中,这将按预期工作:我可以单击步进按钮来更改值,我可以直接输入一个数字。
但是,我不知道如何定义将通知我的目标(超级视图)任何更改的操作。
我创建了一个这样的实例:
let stepper = StepperWithNumberField(....)
stepper.target = self
stepper.action = #selector(self.stepperChanged)
并定义这样的方法:
@objc func stepperChanged(sender: StepperWithNumberField) {
...
}
但是该方法永远不会被调用,因为 StepperWithNumberField 不知道何时将任何操作发送到目标。
我希望每当 intValue 发生变化时,通过使用步进按钮或直接用户输入将操作发送到目标。
我在哪里——如果可能的话——告诉班级发送动作的条件?我已经搜索了 Apple 的文档以及这个社区,但是关于该主题的大多数问题和示例代码都已有 10 多年的历史,并且无法快速处理。
在这个线程...
...建议使用委托,这当然是一种解决方案,但我仍然对如何在自定义 NSControl 中实现目标动作模式感兴趣。