在Swift中按回车键切换文本字段

问题描述 投票:51回答:13

我正在设计一个iOS应用程序,我希望在我的iPhone中按下返回键时,它会将我引导到下一个文本字段。

我发现了几个类似的问题,并且有很好的答案,但它们恰好都在Objective-C中,我正在寻找Swift代码,现在这就是我现在所拥有的:

func textFieldShouldReturn(emaillabel: UITextField) -> Bool{
    return true
}

它被放置在连接的文件和包含文本字段的UIView的控制器中,但我不确定这是不是正确的地方。

我基本上是Swift的新手,所以解释每一个小步骤,否则我会设法弄乱它。此外,我正在使用最新版本的Xcode,如果这有任何区别。

好的,所以我尝试了这个并得到了这个错误: //could not find an overload for '!=' that accepts the supplied arguments

func textFieldShouldReturn(textField: UITextField) -> Bool {
    let nextTag: NSInteger = textField.tag + 1
    // Try to find next responder
    let nextResponder: UIResponder = textField.superview!.viewWithTag(nextTag)!
    if (nextResponder != nil) {
        // could not find an overload for '!=' that accepts the supplied arguments

        // Found next responder, so set it.
        nextResponder.becomeFirstResponder()
    } else {
        // Not found, so remove keyboard.
        textField.resignFirstResponder()
    }
    return false // We do not want UITextField to insert line-breaks.
}

在此先感谢好朋友!

ios iphone swift xcode6
13个回答
129
投票

确保您的UITextField代表已设置且标签正确递增。这也可以通过Interface Builder完成。

这是我发现的Obj-C帖子的链接:How to navigate through textfields (Next / Done Buttons)

class ViewController: UIViewController,UITextFieldDelegate {
   // Link each UITextField (Not necessary if delegate and tag are set in Interface Builder)
   @IBOutlet weak var someTextField: UITextField!

   override func viewDidLoad() {
      super.viewDidLoad()
      // Do the next two lines for each UITextField here or in the Interface Builder
      someTextField.delegate = self
      someTextField.tag = 0 //Increment accordingly
   }

   func textFieldShouldReturn(_ textField: UITextField) -> Bool {
      // Try to find next responder
      if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField {
         nextField.becomeFirstResponder()
      } else {
         // Not found, so remove keyboard.
         textField.resignFirstResponder()
      }
      // Do not add a line break
      return false
   }
}

1
投票

不喜欢使用标签的纯粹主义者的另一种方法,并希望UITextField委托成为保持组件分离或单向的单元格...

  1. 创建一个新协议来链接Cell和TableViewController。 here
  2. 将协议添加到您的单元格,其中TextField Delegate也是单元格(我在故事板中执行此操作)。 func textFieldShouldReturn(_ textField: UITextField) -> Bool { let txtTag:Int = textField.tag if let textFieldNxt = self.view.viewWithTag(txtTag+1) as? UITextField { textFieldNxt.becomeFirstResponder() }else{ textField.resignFirstResponder() } return true }
  3. 使您的TableViewController符合CellResponder协议(即protocol CellResponder { func setNextResponder(_ fromCell: UITableViewCell) } )并根据需要实现该方法。即如果你有不同的单元格类型,那么你可以这样做,同样你可以传入IndexPath,使用标签等。不要忘记在cellForRow中设置class MyTableViewCell: UITableViewCell, UITextFieldDelegate { var responder: CellResponder? func textFieldShouldReturn(_ textField: UITextField) -> Bool { responder?.setNextResponder(self) return true } } .. class MyTableViewController: UITableViewController, CellResponder

1
投票

没有什么特别的,这是我目前用来改变文字字段。 ViewController中的代码看起来不错:)。 #Swift4

cell.responder = self

1
投票

如果你有很多文本字段组件可能是最好使用插座集合,链接文本字段和从界面构建器设置返回键

func setNextResponder(_ fromCell: UITableViewCell) {
  if fromCell is MyTableViewCell, let nextCell = tableView.cellForRow(at: IndexPath(row: 1, section: 0)) as? MySecondTableViewCell {

    nextCell.aTextField?.becomeFirstResponder()

  } ....
}

0
投票

我对你的问题有一个很好的解决方案。

步:

1 - 从故事板中设置返回键。

final class SomeTextFiled: UITextField { public var actionKeyboardReturn: (() -> ())? override init(frame: CGRect) { super.init(frame: frame) super.delegate = self } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) fatalError("init(coder:) has not been implemented") } func textFieldShouldReturn(_ textField: UITextField) -> Bool { self.resignFirstResponder() actionKeyboardReturn?() return true } } extension SomeTextFiled: UITextFieldDelegate {} class MyViewController : UIViewController { var tfName: SomeTextFiled! var tfEmail: SomeTextFiled! var tfPassword: SomeTextFiled! override func viewDidLoad() { super.viewDidLoad() tfName = SomeTextFiled(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) tfName.actionKeyboardReturn = { [weak self] in self?.tfEmail.becomeFirstResponder() } tfEmail = SomeTextFiled(frame: CGRect(x: 100, y: 0, width: 100, height: 100)) tfEmail.actionKeyboardReturn = { [weak self] in self?.tfPassword.becomeFirstResponder() } tfPassword = SomeTextFiled(frame: CGRect(x: 200, y: 0, width: 100, height: 100)) tfPassword.actionKeyboardReturn = { /// Do some further code } } }

2 - 在你的swift文件中。

@IBOutlet var formTextFields: [UITextField]!

override func viewDidLoad() {
  for textField in formTextFields {
    textField.delegate = self
  }
}

extension RegisterViewController: UITextFieldDelegate {
  func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    if let componentIndex = formTextFields.firstIndex(of: textField) {
      if textField.returnKeyType == .next,
        componentIndex < (formTextFields.count - 1) {
        formTextFields[componentIndex + 1].becomeFirstResponder()
      } else {
        textField.resignFirstResponder()
      }
    }
    return true
  }
}

3 - 不要忘记设置Textfield的代理。

谢谢 :)


0
投票

Swift /编程

enter image description here

21
投票

斯威夫特5

在键盘上单击返回键时,可以轻松切换到另一个TextField。

  • 首先,您的视图控制器符合UITextFieldDelegate并在ViewController中添加textFieldShouldReturn(_:)委托方法
  • 在Interface Builder中从TextField拖动到ViewController。然后选择delegate选项。注意:对所有TextField执行此操作
  • 为所有文本字段创建qazxsw poi qazxsw poi

11
投票

我建议你应该在IBOutlet中使用switch语句。

class ViewController: UIViewController, UITextFieldDelegate {

  @IBOutlet weak var txtFieldName: UITextField!
  @IBOutlet weak var txtFieldEmail: UITextField!
  @IBOutlet weak var txtFieldPassword: UITextField!

  override func viewDidLoad() {
    super.viewDidLoad()

  }

  func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    if textField == txtFieldName {
       textField.resignFirstResponder()
       txtFieldEmail.becomeFirstResponder()
    } else if textField == txtFieldEmail {
       textField.resignFirstResponder()
       txtFieldPassword.becomeFirstResponder()
    } else if textField == txtFieldPassword {
       textField.resignFirstResponder()
    }
   return true
  }
}

8
投票

这种方法需要在表视图和集合视图中进行一些更改,但我认为它对于简单的表单是可以的。

将你的textFieldShouldReturn(_:)连接到一个// MARK: UITextFieldDelegate func textFieldShouldReturn(_ textField: UITextField) -> Bool { switch textField { case nameTextField: phoneTextField.becomeFirstResponder() case phoneTextField: emailTextField.becomeFirstResponder() case emailTextField: descriptionTextField.becomeFirstResponder() default: textField.resignFirstResponder() } return false } ,按y坐标排序,然后在textFields中跳转到下一个文本域,直到你到达结尾:

IBOutletCollection

或者只看一下textFieldShouldReturn(_:)(xcode 7 beta 4)


4
投票

我尝试过很多代码,最后这个在Swift 3.0中为我工作最新[2017年3月]

“ViewController”类应继承“UITextFieldDelegate”以使此代码正常工作。

@IBOutlet var textFields: [UITextField]!

...

textFields.sortInPlace { $0.frame.origin.y < $1.frame.origin.y }

...

func textFieldShouldReturn(textField: UITextField) -> Bool {
    if let currentIndex = textFields.indexOf(textField) where currentIndex < textFields.count-1 {
        textFields[currentIndex+1].becomeFirstResponder()
    } else {
        textField.resignFirstResponder()
    }
    return true
}    

添加带有正确标记号的文本字段,此标记号用于根据分配给它的增量标记号将控件转移到适当的文本字段。

sample project

在上面的代码中,“returnKeyType = UIReturnKeyType.next”将使键盘返回键显示为“Next”,您还可以根据应用程序更改值等其他选项“Join / Go”等。

这个“textFieldShouldReturn”是一个UITextFieldDelegate控制的方法,这里我们根据Tag值增量进行下一个字段选择

class ViewController: UIViewController,UITextFieldDelegate  

3
投票

更改为下一个文本的最简单方法字段是不需要长代码

override func viewDidLoad() {

 userNameTextField.delegate = self

        userNameTextField.tag = 0

        userNameTextField.returnKeyType = UIReturnKeyType.next

        passwordTextField.delegate = self

        passwordTextField.tag = 1


        passwordTextField.returnKeyType = UIReturnKeyType.go

}

3
投票

Caleb在Swift 4.0中的版本

func textFieldShouldReturn(_ textField: UITextField) -> Bool

    {

        if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField {

            nextField.becomeFirstResponder()

        } else {

            textField.resignFirstResponder()

            return true;

        }

        return false

    }

附: override func viewDidLoad() { super.viewDidLoad() emailTextField.delegate = self passwordTextField.delegate = self } func textFieldShouldReturn(_ textField: UITextField) -> Bool { if textField == emailTextField { passwordTextField.becomeFirstResponder() }else { passwordTextField.resignFirstResponder() } return true } 不适合我


2
投票

只需在func textFieldShouldReturn(_ textField: UITextField) -> Bool { if let nextField = self.view.viewWithTag(textField.tag + 1) as? UITextField { nextField.becomeFirstResponder() } else { textField.resignFirstResponder() } return false } 方法中使用UIResponder类的textField.superview?方法。每个becomeFirstResponder()对象都是textFieldShouldReturn的子类。

UIView

您可以在UIResponder的Apple Doc's找到有关if self.emaillabel.isEqual(self.anotherTextField) { self.anotherTextField.becomeFirstResponder() } 方法的更多信息。


2
投票

Swift 4.2

这是一个更通用,最简单的解决方案,您可以将此代码与任意数量的TextFields一起使用。只需继承UITextFieldDelegate并根据顺序更新Textfield标签并复制此功能

becomeFirstResponder()
© www.soinside.com 2019 - 2024. All rights reserved.