繁体   English   中英

如何检测可可中单击哪个NSTextField?

[英]How to detect which NSTextField is clicked in Cocoa?

我有两个要在用户单击时突出显示的NSTextField对象。

初始文本字段已在NSWindow加载中突出显示。 我能够获得鼠标按下事件来单击文本字段,但是无法区分用户点击了哪个文本字段。

我尝试使用从NSEvent对象获得的NSPoint在文本字段上使用hitTest,但返回的NSView为nil。 它返回的视图是窗口视图的视图,而不是文本字段。

class SettingsViewController: NSViewController {
    private var sview: SettingsView?

    override func viewDidLoad() {
        initEvents()
    }

    override func loadView() {
        if let settingsView = SettingsView.createFromNib() {
            self.view = settingsView
            self.sview = settingsView as? SettingsView
        }
    }

    func initEvents() {
        self.sview!.emailTextField.delegate = self
    }

}

extension SettingsViewController: NSTextFieldDelegate, NSTextDelegate {
    override func mouseDown(with event: NSEvent) {
        self.log.debug("mouse down: \(event.buttonNumber), \(event.eventNumber), \(event.locationInWindow)")
        // How to know which text field triggered this?
    }

    func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {
        self.log.debug("control delegate")
        return false
    }

    func textField(_ textField: NSTextField, textView: NSTextView, shouldSelectCandidateAt index: Int) -> Bool {
        self.log.debug("text field should select")
        return true
    }

    func textShouldBeginEditing(_ textObject: NSText) -> Bool {
        self.log.debug("text field should being editing")
        return true
    }
}

class SettingsView: NSView {
    private let log = Logger()
    private static var topLevelObjects: NSArray?
    @IBOutlet weak var emailTextField: ASTextField!
    @IBOutlet weak var passwordTextField: NSSecureTextField!

    // ...
}

我将委托添加到仅一个文本字段。

self.sview!.emailTextField.delegate = self

但是,当我单击passwordTextField ,我也得到了鼠标单击事件。 为什么会这样呢?

如何区分NSTextField鼠标单击并突出显示文本字段?


我尝试将NSTextField子类化并添加单击处理程序,但是它不起作用。

class ASTextField: NSTextField {
    private let log = Logger()

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        bootstrap()
    }

    override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        bootstrap()
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        bootstrap()
    }

    func bootstrap() {
        self.delegate = self
    }
}

extension ASTextField: NSTextFieldDelegate {
    override func mouseDown(with event: NSEvent) {
        // This is not working
        self.log.debug("mouse down")
        super.mouseDown(with: event)
    }
}

您改写的方法mouseDown(with)不是NSTextFieldDelegateNSTextDelegate协议的成员。 NSViewController.mouseDown(with)

每当调用该方法时,单击的对象就是SettingsViewController的视图。

要对您选择的文本字段做出反应,请使用已经具有的NSTextFieldDelegate .textField(_:textView:shouldSelectCandidateAt:) textView参数的值是所选的文本视图。

我更新了ASTextField如下。

class ASTextField: NSTextField {

    // ...

    override func mouseDown(with event: NSEvent) {
        self.sendAction(#selector(didClick(_:)), to: self)
        super.mouseDown(with: event)
    }

    @objc func didClick(_ event: NSEvent) {
        self.log.debug("did click")
    }
}

SettingsView ,我错过了调用super.layout() ,如果没有该调用,单击将无法进行,单击时其他文本字段也不会获得焦点。

class SettingsView: NSView {
    // ...

    override func layout() {
        self.log.debug("layout method")
        super.layout()  // This is important
    }
}

不需要NSTextField委托方法。

如果您要查找的是单击(聚焦)文本字段时能够选择文本,则可以重写该类以简化您的任务,而不必担心从委托中找到被单击的字段。

对于一个NSView对象,当它获得焦点(即单击或制表)时,它将调用becomeFirstResponder以便我们可以将其挂接到那里。

当NSTextField变为可编辑(或可选)时,它将获取可重用的“字段编辑器”,并在编辑期间将其覆盖在文本字段的顶部。 如果您的NSTextField具有焦点,则可以使用视图上的currentEditor()调用获取此字段编辑器。

因此,一旦有了字段编辑器,就可以在编辑器上执行selectAll以选择文本。

示例类:-

class AutoselectOnFocusTextField: NSTextField {
    override func becomeFirstResponder() -> Bool {
        guard super.becomeFirstResponder() else {
            return false
        }
        if let editor = self.currentEditor() {
            editor.perform(#selector(selectAll(_:)), with: self, afterDelay: 0)
        }
        return true
    }
}

希望这可以帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM