简体   繁体   English

带有“上一个”和“下一个”的键盘工具栏

[英]Toolbar with “Previous” and “Next” for keyboard

I've been trying to implement this toolbar, where only the 'Next' button is enabled when the top textField is the firstResponder and only the 'Previous' button is enabled when the bottom textField is the firstResponder. 我一直在尝试实现此工具栏,当顶部文本字段是firstResponder时,仅启用“下一步”按钮,而底部文本字段是firstResponder时,仅启用“上一步”按钮。

It kind of works, but i need to execute my own code by accessing previous, next and done buttons action methods in other classes(like delegates) 这是可行的,但是我需要通过访问其他类(例如委托)中的上一个,下一个和完成按钮的操作方法来执行自己的代码。

Thanks in advance for your suggestions.. 预先感谢您的建议。

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

I am calling this from other class as : 我从其他班级将此称为:

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

Although I'm not 100% convinced I understand your question, here goes: 尽管我不是100%确信我理解您的问题,但是这里有:

From other classes, you want to call the actions of your buttons, but your actions are set to UITextField.becomeFirstResponder and UIView.endEditing. 从其他类中,您想调用按钮的操作,但是您的操作设置为UITextField.becomeFirstResponder和UIView.endEditing。

Rather than call these methods directly, create your own methods the actions should call, and put these calls into those methods. 与其直接调用这些方法,不如创建动作应调用的自己的方法,并将这些调用放入这些方法中。

In addInputAccessoryForTextFields(...) change the previousButton's target and action to: 在addInputAccessoryForTextFields(...)中,将previousButton的目标和操作更改为:

previousButton.target = self
previousButton.action = #selector(handlePreviousButton)

Now add the new method: 现在添加新方法:

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

Now you can call handlePreviousButton() directly from elsewhere in your class, if you wish, or even from other classes. 现在,您可以根据需要直接从类中的其他位置甚至从其他类中调用handlePreviousButton()。

Update 更新资料

I just noticed you're extending UIViewController. 我只是注意到您正在扩展UIViewController。 So you can't add storage by adding a property. 因此,您无法通过添加属性来添加存储。 You can add storage via objc_setAssociatedObject and then get it via objc_getAssociatedObject, however, to get around this. 您可以通过objc_setAssociatedObject添加存储,然后通过objc_getAssociatedObject获取存储,以解决此问题。 See this SO or this SO for details on that. 有关详细信息,请参见此SO此SO So you can, for example, "attach" the textField to your previousButton so that you can access it via the handlePreviousButton() method you add to your extension. 因此,例如,您可以将textField“附加”到previousButton,以便可以通过添加到扩展中的handlePreviousButton()方法访问它。 And you can pass in the previousButton as a parameter (the sender) to handlePreviousButton() too. 您也可以将previousButton作为参数(发送者)传递给handlePreviousButton()。

Update 2 更新2

Another approach to consider is to use the button's tag property to store the tag value of the related textField. 考虑的另一种方法是使用按钮的tag属性存储相关textField的标签值。 (ie each button and its related textField would have the same tag value). (即,每个按钮及其相关的textField都具有相同的标签值)。 So in handlePreviousButton(sender:UIBarButtonItem) you loop through all the UITextField children of your self.view and locate the one whose tag matches sender.tag . 因此,在handlePreviousButton(sender:UIBarButtonItem)中,您遍历self.view的所有UITextField子级,并找到其标签与sender.tag匹配的子级。 Then you can do what you need to that UITextField. 然后,您可以对该UITextField执行所需的操作。

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

相关问题 带有键盘输入的“上一个”和“下一个”的工具栏AccessoryView - Toolbar with “Previous” and “Next” for Keyboard inputAccessoryView 下一个/上一个键盘工具栏iOS7 - Next/Previous Keyboard Toolbar iOS7 iOS 8-UIWebView键盘-上一个/下一个/完成附件栏-如何删除工具栏? - iOS 8 - UIWebView Keyboard - Previous/Next/Done Accessory Bar - How can I remove the toolbar? 在iOS中的“下一个”或“上一个”虚拟键盘上 - On 'next' or 'previous' virtual keyboard in iOS Swift:在工具栏中添加已完成,下一个,上一个功能 - Swift: Add done, next, previous functions in toolbar 如何删除Eureka表单中的&lt;&gt;(下一个/上一个)Done工具栏? - How do you remove the < > (next / previous) Done toolbar in Eureka forms? 处理iOS虚拟键盘的“上一个”,“下一个”,“执行/进入”按钮 - Handling iOS virtual keyboard “previous”, “next”, “Go/Enter” buttons UItableview和键盘有上一个和下一个按钮滚动问题-iPhone - UItableview and Keyboard with previous and next button scrolling issue - iPhone 带有下一个,上一个和完成按钮的iOS键盘,用于UITableView中的文本字段 - iOS keyboard with next, previous and done buttons, for text fields in UITableView 在静态UITableView上使用UITextfields的上一个和下一个键盘按钮 - Previous and Next keyboard buttons using UITextfields on Static UITableView
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM