Почему #selector не вызывает метод обработчика для сочетаний клавиш iPad?

У меня есть класс для создания UIBarButtonItems:

enum KeyboardToolbarButton: Int {

    case done = 0
    case cancel
    case back, backDisabled
    case forward, forwardDisabled

    func createButton(target: Any?, action: Selector?) -> UIBarButtonItem {
        var button: UIBarButtonItem!

        switch self {
        case .back:
            button = UIBarButtonItem(title: "< = ", style: .plain, target: target, action: action)
        case .backDisabled:
            button = UIBarButtonItem(title: "< = ", style: .plain, target: target, action: action)
            button.isEnabled = false
        case .forward:
            button = UIBarButtonItem(title: "=>", style: .plain, target: target, action: action)
        case .forwardDisabled:
            button = UIBarButtonItem(title: "=>", style: .plain, target: target, action: action)
            button.isEnabled = false
        case .done:
            button = UIBarButtonItem(title: "DONE", style: .plain, target: target, action: action)
        case .cancel:
            button = UIBarButtonItem(title: "CANCEL", style: .plain, target: target, action: action)
        }
        button.tag = rawValue
        return button
    }

    static func detectType(barButton: UIBarButtonItem) -> KeyboardToolbarButton? {
        return KeyboardToolbarButton(rawValue: barButton.tag)
    }
}

Класс для построения KeyboardToolbar из KeyboardToolbarButton:

class KeyboardToolbar {

    weak var toolBarDelegate: KeyboardToolbarDelegate?
    var textField: UITextField!

    init(textField: UITextField) {

        self.textField = textField
        self.textField.autocorrectionType = .no
        self.textField.inputAssistantItem.leadingBarButtonGroups = []
        self.textField.inputAssistantItem.trailingBarButtonGroups = []
    }

    func setup(leftButtons: [KeyboardToolbarButton], rightButtons: [KeyboardToolbarButton]) {

        let leftBarButtons = leftButtons.map { (item) -> UIBarButtonItem in
            return item.createButton(target: self, action: #selector(self.buttonTapped(sender:)))
        }

        let rightBarButtons = rightButtons.map { (item) -> UIBarButtonItem in
            return item.createButton(target: self, action: #selector(self.buttonTapped(sender:)))
        }

        let groupLeading: UIBarButtonItemGroup = UIBarButtonItemGroup.init(barButtonItems: leftBarButtons, representativeItem: nil)
        let groupTrailing: UIBarButtonItemGroup = UIBarButtonItemGroup.init(barButtonItems: rightBarButtons, representativeItem: nil)

        textField.inputAssistantItem.leadingBarButtonGroups.append(groupLeading)
        textField.inputAssistantItem.trailingBarButtonGroups.append(groupTrailing)
    }


    @objc func buttonTapped(sender: UIBarButtonItem) {
        if let type = KeyboardToolbarButton.detectType(barButton: sender) {
            print(type)
            toolBarDelegate?.keyboardToolbar(button: sender, type: type, tappedIn: self)
        }
    }

}

И делегируйте:

protocol KeyboardToolbarDelegate: class {
    func keyboardToolbar(button: UIBarButtonItem, type: KeyboardToolbarButton, tappedIn toolbar: KeyboardToolbar)
}

Вот как я использую KeyboardToolbar:

class ViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()


        addButtons(for: textField, setLeftButtons: [.back, .forward], andRightButtons: [.done])
    }


    private func addButtons(for textField: UITextField, setLeftButtons leftButtons: [KeyboardToolbarButton] = [], andRightButtons rightButtons: [KeyboardToolbarButton] = []) {
        let toolbar = KeyboardToolbar(textField: textField)
        toolbar.toolBarDelegate = self
        toolbar.setup(leftButtons: leftButtons, rightButtons: rightButtons)
    }

}

extension ViewController: KeyboardToolbarDelegate {
    func keyboardToolbar(button: UIBarButtonItem, type: KeyboardToolbarButton, tappedIn toolbar: KeyboardToolbar) {

        print("Tapped button type: \(type)")


    }
}

Вот как это работает (эта функция доступна только на iPad)

Почему #selector не вызывает метод обработчика для сочетаний клавиш iPad?

Итак, проблема в том, что @objc func buttonTapped (отправитель: UIBarButtonItem) никогда не вызывает. Итак, #selector (self.buttonTapped (sender :) не подключается к обработчику. Как это исправить?

Обновлять:

Согласно ответу Тараса Чернышенко, я добавил KeyboardToolbar в качестве члена ViewController:

class ViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!
    var toolbar: KeyboardToolbar!

    override func viewDidLoad() {
        super.viewDidLoad()

        addButtons(for: textField, setLeftButtons: [.back, .forward], andRightButtons: [.done])
    }


    private func addButtons(for textField: UITextField, setLeftButtons leftButtons: [KeyboardToolbarButton] = [], andRightButtons rightButtons: [KeyboardToolbarButton] = []) {
        toolbar = KeyboardToolbar(textField: textField)
        toolbar.toolBarDelegate = self
        toolbar.setup(leftButtons: leftButtons, rightButtons: rightButtons)
    }

}
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
66
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в вашем дизайне. В классе KeyboardToolbar в функции func setup(leftButtons:, rightButtons:) вы делаете следующее:

let leftBarButtons = leftButtons.map { (item) -> UIBarButtonItem in
    return item.createButton(target: self, action: #selector(self.buttonTapped(sender:)))
}

здесь вы устанавливаете action target в класс KeyboardToolbar.

Затем в addButtons(for textField:, setLeftButtons leftButtons:, andRightButtons rightButtons:) из ViewController вы настраиваете свои кнопки, например

let toolbar = KeyboardToolbar(textField: textField)
toolbar.toolBarDelegate = self
toolbar.setup(leftButtons: leftButtons, rightButtons: rightButtons)

но после этого функция toolbar отключается, поэтому действия не могут достичь своей цели.

Для простого исправления сохраните toolbar в свойстве класса

class ViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!

    var toolbar = KeyboardToolbar?
    override func viewDidLoad() {
        super.viewDidLoad()


        addButtons(for: textField, setLeftButtons: [.back, .forward], andRightButtons: [.done])
    }


    private func addButtons(for textField: UITextField, setLeftButtons leftButtons: [KeyboardToolbarButton] = [], andRightButtons rightButtons: [KeyboardToolbarButton] = []) {
        let toolbar = KeyboardToolbar(textField: textField)
        toolbar.toolBarDelegate = self
        toolbar.setup(leftButtons: leftButtons, rightButtons: rightButtons)
        self.toolbar = toolbar
    }

}

Спасибо. В настоящее время работает. Но в отправленном вами коде есть небольшие ошибки. Необходимо объявить KeyboardToolbar как панель инструментов var: KeyboardToolbar !. А затем в private func addButtons (для textField: UITextField, setLeftButtons leftButtons: нам нужно использовать ту же переменную.

Degtiarev Aleksei 29.10.2018 16:57

Другие вопросы по теме