带有"上一页"的工具栏和"下一步"键盘

时间:2018-05-12 05:33:35

标签: ios swift uibarbuttonitem uitoolbar

我一直在尝试实施这个工具栏,其中只有' Next'当顶部textField是firstResponder并且只有' Previous'当底部textField是firstResponder时启用按钮。

它有点工作,但我需要通过访问其他类(如委托)中的previous,next和done按钮操作方法来执行我自己的代码

提前感谢您的建议..

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

我从其他班级称呼这个:

let field1 = UITextField()
let field2 = UITextField()
addInputAccessoryForTextFields([field1, field2], dismissable: true, previousNextable: true)

1 个答案:

答案 0 :(得分:0)

虽然我并不是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 SOthis SO。所以你可以,例如,&#34;附加&#34; textField到您的previousButton,以便您可以通过添加到扩展名的handlePreviousButton()方法访问它。你也可以将previousButton作为参数(发送者)传递给handlePreviousButton()。

更新2

另一种需要考虑的方法是使用按钮的标记属性来存储相关textField的标记值。 (即每个按钮及其相关的textField将具有相同的标记值)。因此,在handlePreviousButton(sender:UIBarButtonItem)中,您遍历self.view的所有UITextField子项,并找到其标记与sender.tag匹配的子项。然后,您可以执行UITextField所需的操作。