为啥#selector 不为 iPad 的键盘快捷键调用处理程序方法?
Posted
技术标签:
【中文标题】为啥#selector 不为 iPad 的键盘快捷键调用处理程序方法?【英文标题】:Why #selector doesn't call handler method for iPad's keyboard shortcuts?为什么#selector 不为 iPad 的键盘快捷键调用处理程序方法? 【发布时间】:2018-10-29 15:09:18 【问题描述】:我有一个用于构造 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)
从 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)
和委托:
protocol KeyboardToolbarDelegate: class
func keyboardToolbar(button: UIBarButtonItem, type: KeyboardToolbarButton, tappedIn toolbar: 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 上可用)
所以,问题在于 @objc func buttonTapped(sender: UIBarButtonItem) 从不调用。那么,#selector(self.buttonTapped(sender:) 没有连接到处理程序。如何解决?
更新:
根据 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)
【问题讨论】:
【参考方案1】:问题在于您的设计。在func setup(leftButtons:, rightButtons:)
函数中的KeyboardToolbar
类中你接下来要做的:
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 toolbar: KeyboardToolbar!。然后在 private func addButtons(for textField: UITextField, setLeftButtons leftButtons: 我们需要使用相同的变量。以上是关于为啥#selector 不为 iPad 的键盘快捷键调用处理程序方法?的主要内容,如果未能解决你的问题,请参考以下文章
resignFirstResponder 无法关闭我在 iPad 上的自定义键盘。为啥?