如何从子类 NSTextField 设置 NSButton.isEnabled
How to set NSButton.isEnabled from subclassed NSTextField
我对 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()
}
}
您的 NSTextField 子类需要能够与按钮通信。最简单的方法是将对 pushButton 的引用传递给您的文本字段,然后从那里更新按钮。
像这样更新您的 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.
}
我对 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()
}
}
您的 NSTextField 子类需要能够与按钮通信。最简单的方法是将对 pushButton 的引用传递给您的文本字段,然后从那里更新按钮。
像这样更新您的 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.
}