我已經創建了一個子類,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
...建議使用委托,這當然是一種解決方案,但我仍然對如何在自定義 NSControl 中實作目標動作模式感興趣。
uj5u.com熱心網友回復:
public typealias Handler = (StepperWithNumberField) -> Void
private var handler: Handler?
@objc func stepperClicked(sender: NSStepper) {
numberField.intValue = stepper.intValue
self.handler?(self)
}
利用
let stepper = StepperWithNumberField(....)
stepper.target = self
stepper.handler = stepperChanged(sender:)
func stepperChanged(sender: StepperWithNumberField) {
}
uj5u.com熱心網友回復:
受 Leo Chen 回答的啟發,我做了更多的實驗,得出以下結論: 只需添加:
self.sendAction(action, to: target)
到我班的stepperClicked和方法。controlTextDidEndEditingStepperWithNumberField
那么用法:
let stepper = StepperWithNumberField(...)
stepper.target = self
stepper.action = #selector(self.stepperChanged)
@objc func stepperChanged(sender: StepperWithNumberField) {
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/416822.html
標籤:
上一篇:如何在Swift中使用二維陣列?
