У меня есть класс для создания 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)
Итак, проблема в том, что @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)
}
}
Проблема в вашем дизайне. В классе 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: нам нужно использовать ту же переменную.