简体   繁体   English

为什么#selector不为iPad的键盘快捷方式调用处理程序方法?

[英]Why #selector doesn't call handler method for iPad's keyboard shortcuts?

I have a class for constructing UIBarButtonItems: 我有一个用于构造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)
    }
}

Class for constructing KeyboardToolbar from KeyboardToolbarButton: 从KeyboardToolbarButton构造KeyboardToolbar的类:

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)
        }
    }

}

And delegate: 并委托:

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

Here's how I use 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)")


    }
}

Here's how it works (this feature available only on iPad) 工作原理如下(此功能仅在iPad上可用)

在此处输入图片说明

So, the problem is that @objc func buttonTapped(sender: UIBarButtonItem) never calls. 因此,问题在于@objc func buttonTapped(sender:UIBarButtonItem)永远不会调用。 So, #selector(self.buttonTapped(sender:) does not connect to handler. How to fix it? 因此,#selector(self.buttonTapped(sender :)不连接到处理程序。如何解决?

Update: 更新:

According to the answer of Taras Chernyshenko, I added KeyboardToolbar as a member of ViewController: 根据Taras Chernyshenko的回答,我将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)
    }

}

Problem is in you design. 问题出在您的设计中。 In KeyboardToolbar class in func setup(leftButtons:, rightButtons:) function you doing next: func setup(leftButtons:, rightButtons:)函数的KeyboardToolbar类中func setup(leftButtons:, rightButtons:)要做的是:

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

here you are setting action target to KeyboardToolbar class. 在这里,您将action target设置为KeyboardToolbar类。

Next in addButtons(for textField:, setLeftButtons leftButtons:, andRightButtons rightButtons:) of ViewController you setup your buttons like 接下来,在ViewController addButtons(for textField:, setLeftButtons leftButtons:, andRightButtons rightButtons:) ,您可以像设置按钮一样

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

but after this function toolbar is dealocated, so actions can't reach their target. 但在取消分配此功能toolbar后,操作将无法达到其目标。

To simple fix, store toolbar into class property 要简单修复,请将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
    }

}

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

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