我一直在尝试实现此工具栏,当顶部文本字段是第一个响应者时,仅启用“下一步”按钮,而当底部文本字段是第一个响应者时,仅启用“上一个”按钮。
它确实有效,但我需要通过访问其他类(如委托(delegate))中的上一个、下一个和完成按钮操作方法来执行我自己的代码
提前感谢您的建议..
extension UIViewController {
func addInputAccessoryForTextFields(textFields: [UITextField], dismissable: Bool = true, previousNextable: Bool = false) {
for (index, textField) in textFields.enumerated() {
let toolbar: UIToolbar = UIToolbar()
toolbar.sizeToFit()
var items = [UIBarButtonItem]()
if previousNextable {
let previousButton = UIBarButtonItem(image: UIImage(named: "Backward Arrow"), style: .plain, target: nil, action: nil)
previousButton.width = 30
if textField == textFields.first {
previousButton.isEnabled = false
} else {
previousButton.target = textFields[index - 1]
previousButton.action = #selector(UITextField.becomeFirstResponder)
}
let nextButton = UIBarButtonItem(image: UIImage(named: "Forward Arrow"), style: .plain, target: nil, action: nil)
nextButton.width = 30
if textField == textFields.last {
nextButton.isEnabled = false
} else {
nextButton.target = textFields[index + 1]
nextButton.action = #selector(UITextField.becomeFirstResponder)
}
items.append(contentsOf: [previousButton, nextButton])
}
let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: view, action: #selector(UIView.endEditing))
items.append(contentsOf: [spacer, doneButton])
toolbar.setItems(items, animated: false)
textField.inputAccessoryView = toolbar
}
}
}
我从其他类(class)调用它:
let field1 = UITextField()
let field2 = UITextField()
addInputAccessoryForTextFields([field1, field2], dismissable: true, previousNextable: true)
最佳答案
虽然我不是 100% 相信我理解你的问题,但这里是:
从其他类中,您想要调用按钮的操作,但您的操作设置为 UITextField.becomeFirstResponder 和 UIView.endEditing。
不要直接调用这些方法,而是创建操作应调用的您自己的方法,并将这些调用放入这些方法中。
在 addInputAccessoryForTextFields(...) 中,将 previousButton 的目标和操作更改为:
previousButton.target = self
previousButton.action = #selector(handlePreviousButton)
现在添加新方法:
@objc func handlePreviousButton()
{
// you'll need to associate the previous button to a specific text field
// and hang onto that association in your class, such as in a property named textFieldRelatedToPreviousButton.
self.textFieldRelatedToPreviousButton.becomeFirstResponder()
}
现在,如果您愿意,您可以直接从类中的其他位置甚至其他类中调用handlePreviousButton()。
更新
我刚刚注意到您正在扩展 UIViewController。所以你不能通过添加属性来添加存储。但是,您可以通过 objc_setAssociatedObject 添加存储,然后通过 objc_getAssociatedObject 获取它,以解决此问题。请参阅this SO或this SO详细信息。例如,您可以将 textField“附加”到 previousButton,以便您可以通过添加到扩展中的 handlePreviousButton() 方法访问它。您也可以将 previousButton 作为参数(发送者)传递给handlePreviousButton()。
更新2
另一种需要考虑的方法是使用按钮的标签属性来存储相关文本字段的标签值。 (即每个按钮及其相关的文本字段将具有相同的标签值)。因此,在 handlePreviousButton(sender:UIBarButtonItem) 中,您循环遍历 self.view 的所有 UITextField 子级,并找到标签与 sender.tag 匹配的那个。然后您可以对该 UITextField 执行您需要的操作。
关于ios - 带有 "Previous"和键盘 "Next"的工具栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50303175/