我对Swift MacOS编程非常陌生,并且通过编写小型测试应用程序来学习。
此应用程序的目的是在第二个文本字段具有焦点时启用按钮,而在未聚焦时禁用按钮。
我发现通过子类化NSTextField可以覆盖becomeFirstResponder()
,但是不知道如何从子类中设置要禁用的按钮。
ViewController:
class ViewController: NSViewController {
@IBOutlet public weak var pushButton: NSButton!
@IBOutlet weak var textField3: NSTextField!
@IBOutlet weak var textField2: GSTextField!
@IBOutlet weak var textField1: NSTextField!
override func viewDidLoad() {
super.viewDidLoad()
textField2.delegate = self
// Do any additional setup after loading the view.
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
func chgButton(onoff: Bool){
pushButton.isEnabled = onoff
}
}
// When the field completes editing make the pushbutton disabled.
extension ViewController: NSTextFieldDelegate {
override func controlTextDidEndEditing(_ obj: Notification) {
print("did end")
chgButton(onoff: false)
}
}
GSTextField.Swift
class GSTextField: NSTextField {
override func becomeFirstResponder() -> Bool {
print("GSTextField Firstresponder")
////*** I need to set the button to be enabled here
return super.becomeFirstResponder()
}
}
答案 0 :(得分:0)
您的NSTextField子类需要能够与按钮通信。最简单的方法是将对按钮的引用传递到您的文本字段,然后从那里更新按钮。
像这样更新您的ViewController:
override func viewDidLoad() {
super.viewDidLoad()
textField2.delegate = self
textField2.pushButton = pushButton
// Do any additional setup after loading the view.
}
您的GSTextField如下:
class GSTextField: NSTextField {
weak var pushButton: NSButton?
override func becomeFirstResponder() -> Bool {
print("GSTextField Firstresponder")
pushButton?.isEnabled = true
return super.becomeFirstResponder()
}
override func resignFirstResponder() -> Bool {
pushButton?.isEnabled = false
return super.resignFirstResponder()
}
}
应该注意的是,尽管在这个玩具示例中可以很好地工作,但这不是此问题的次佳解决方案,因为它紧密地结合了pushButton和GSTextField。更好的解决方案是使用委托将焦点更改传达给ViewController,然后让ViewController处理更新。
您的GSTextField看起来像这样:
protocol FocusObservable: class {
func didGainFocus(sender: Any)
func didLoseFocus(sender: Any)
}
class GSTextField: NSTextField {
weak var focusDelegate: FocusObservable?
override func becomeFirstResponder() -> Bool {
print("GSTextField Firstresponder")
focusDelegate?.didGainFocus(sender: self)
return super.becomeFirstResponder()
}
override func resignFirstResponder() -> Bool {
focusDelegate?.didLoseFocus(sender: self)
return super.resignFirstResponder()
}
}
然后将协议一致性添加到ViewController:
extension ViewController: FocusObservable {
func didGainFocus(sender: Any) {
pushButton.isEnabled = true
}
func didLoseFocus(sender: Any) {
pushButton.isEnabled = false
}
}
并设置文本字段的focusDelegate:
override func viewDidLoad() {
super.viewDidLoad()
textField2.delegate = self
textField2.focusDelegate = self
// Do any additional setup after loading the view.
}