Вопрос:

Как определить, какой NSTextField нажимается в Какао?

swift macos cocoa nstextfield

35 просмотра

2 ответа

498 Репутация автора

У меня есть два NSTextFieldобъекта, которые я хочу выделить, когда пользователь нажимает на него.

Исходное текстовое поле уже подсвечивается при NSWindowзагрузке. Я могу получить событие нажатия мыши для текстового поля, но не могу различить, какое текстовое поле пользователь нажал.

Я попытался использовать hitTest для текстового поля, используя NSPointполученный от NSEventобъекта, но NSViewвозвращенный ноль. Он возвращает вид окна, а не текстовое поле.

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)
    }
}
Автор: jsloop Источник Размещён: 10.08.2019 06:36

Ответы (2)


0 плюса

35965 Репутация автора

Метод, который вы переписали, mouseDown(with)не является членом NSTextFieldDelegateили NSTextDelegateпротоколами. Вы переписали NSViewController.mouseDown(with).

Всякий раз, когда вызывается этот метод, то, что щелкнуло, является вашим SettingsViewControllerвзглядом.

Чтобы реагировать на то, что ваше текстовое поле выбрано, вы используете то NSTextFieldDelegate .textField(_:textView:shouldSelectCandidateAt:), что у вас уже есть. Значением textViewпараметра является текстовое представление, которое было выбрано.

Автор: Alexander Размещён: 10.08.2019 07:07

0 плюса

498 Репутация автора

Я обновил 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 методы делегата не требуются.

Автор: jsloop Размещён: 11.08.2019 07:10
Вопросы из категории :
32x32