Swift-不为空时自动跳转到下一个文本字段

Swift-不为空时自动跳转到下一个文本字段,swift,uitextfield,Swift,Uitextfield,我正在做一个游戏,在这个游戏中,用户必须键入动词的过去式。我的视图包含只接受一个字符的小文本框。现在,当前一个文本字段包含一个字母时,我试图自动跳转到下一个文本字段 我想一直这样做,直到所有的盒子都装满为止。用户还应该能够使用键盘上的返回按钮返回一个框 下面是我当前使用的代码,但它不会跳到下一个文本字段。我做错了什么 var game: Game? { didSet { if var answerContent = game?.answer {

我正在做一个游戏,在这个游戏中,用户必须键入动词的过去式。我的视图包含只接受一个字符的小文本框。现在,当前一个文本字段包含一个字母时,我试图自动跳转到下一个文本字段

我想一直这样做,直到所有的盒子都装满为止。用户还应该能够使用键盘上的返回按钮返回一个框

下面是我当前使用的代码,但它不会跳到下一个文本字段。我做错了什么

 var game: Game? {
    didSet {

        if var answerContent = game?.answer {

            let views = (0..<answerContent.characters.count).map { _ in UITextField(frame: CGRect(x: 0, y: 0, width: 40, height: 40)) }

            for textField in views {
                textField.backgroundColor = UIColor.white
                textField.textColor = Constants.MAIN_THEME_COLOR
                textField.textAlignment = NSTextAlignment.center
                textField.delegate = self
                textField.returnKeyType = .next
                textField.tag = views.index(of: textField)! + 1
                self.container.addArrangedSubview(textField)

                views.first?.becomeFirstResponder()
            }
        }
    }
}

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard let text = textField.text else { return true }
    let textLength = text.characters.count + string.characters.count - range.length

    return textLength <= 1
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField {
            print("Test")
            nextField.becomeFirstResponder()
        } else {
            print("Test2")
            textField.resignFirstResponder()
        }

    return false
}

我建议您向控件事件添加一个目标
。valueChanged

// for each text field
textField.addTarget(self, action: #selector(textChanged), for: .valueChanged)
执行
textChanged
,如下所示:

func textChanged(sender: UITextField) {
    if sender.text.characters.length > 0 {
        let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField
        nextField?.becomeFistResponder()
    }
}
请遵循以下代码:

import UIKit

// used this to set max characters of UITextField in the storyboard
private var __maxLengths = [UITextField: Int]()
extension UITextField {
    @IBInspectable var maxLength: Int {
        get {
            guard let l = __maxLengths[self] else {
                return 150 // (global default-limit. or just, Int.max)
            }
            return l
        }
        set {
            __maxLengths[self] = newValue
            addTarget(self, action: #selector(fix), for: .editingChanged)
        }
    }
    func fix(textField: UITextField) {
        let t = textField.text
        textField.text = t?.safelyLimitedTo(length: maxLength)
    }
}

extension String
{
    func safelyLimitedTo(length n: Int)->String {
        let c = self.characters
        if (c.count <= n) { return self }
        return String( Array(c).prefix(upTo: n) )
    }
}


class ViewController: UIViewController {

  @IBOutlet var input1: UITextField!
  @IBOutlet var input2: UITextField!
  @IBOutlet var input3: UITextField!
  @IBOutlet var input4: UITextField!
  @IBOutlet var input5: UITextField!
  @IBOutlet var input6: UITextField!

  override func viewDidLoad() {
        super.viewDidLoad()

        setup()
        // Do any additional setup after loading the view.
  }

  func setup() {
        input1.tag = 1
        input2.tag = 2
        input3.tag = 3
        input4.tag = 4
        input5.tag = 5
        input6.tag = 6

        input1.addTarget(self, action: #selector(textChanged), for: .editingChanged)
        input2.addTarget(self, action: #selector(textChanged), for: .editingChanged)
        input3.addTarget(self, action: #selector(textChanged), for: .editingChanged)
        input4.addTarget(self, action: #selector(textChanged), for: .editingChanged)
        input5.addTarget(self, action: #selector(textChanged), for: .editingChanged)
        input6.addTarget(self, action: #selector(textChanged), for: .editingChanged)
  }

  func textChanged(sender: UITextField) {
        if (sender.text?.characters.count)! ==  1 {

            let nextField = sender.superview?.viewWithTag(sender.tag + 1) as UIResponder!
            nextField?.becomeFirstResponder()
        } else if (sender.text?.characters.count)! ==  0 {
            let nextField = sender.superview?.viewWithTag(sender.tag - 1) as UIResponder!
            nextField?.becomeFirstResponder()
        }


    }


}
导入UIKit
//用于设置情节提要中UITextField的最大字符数
私有变量\uuuMaxLength=[UITextField:Int]()
扩展UITextField{
@IBInspectable变量maxLength:Int{
得到{
guard let l=uu MaxLength[self]else{
返回150/(全局默认限制或仅限Int.max)
}
返回l
}
设置{
__MaxLength[self]=新值
addTarget(自我,操作:#选择器(修复),用于:。编辑已更改)
}
}
func修复(文本字段:UITextField){
设t=textField.text
textField.text=t?.safelyLimitedTo(长度:maxLength)
}
}
扩展字符串
{
func安全限制为(长度n:Int)->字符串{
设c=self.characters

如果(c.count)为Swift 4更新

在每个文本字段的
viewDidLoad()

textField.addTarget(self, action: #selector(textChanged), for: .editingChanged)
然后加上这个函数,

@objc func textChanged(sender: UITextField) {
    if (sender.text?.count)! > 0 {
        let nextField = self.view.viewWithTag(sender.tag + 1) as? UITextField
        nextField?.becomeFirstResponder()
    }
}

我尝试过你的方法,但它根本没有调用textChanged函数。不过为了与Swift 3.0保持一致,对它进行了一点更新。
func textChanged(sender:UITextField){if(sender.text?.characters.count)!>0{print(“Test”)let nextField=textField.superview?.viewWithTag(textField.tag+1)as?UITextField nextField?.becomeFirstResponder()}
@DennisvanMazijk你把
addTarget
调用放在哪里了?检查
addTarget
调用是否被执行。在委托下的for循环中。@DennisvanMazijk那是执行的吗?你设置了
game
属性了吗?
textField.addTarget(self, action: #selector(textChanged), for: .editingChanged)
@objc func textChanged(sender: UITextField) {
    if (sender.text?.count)! > 0 {
        let nextField = self.view.viewWithTag(sender.tag + 1) as? UITextField
        nextField?.becomeFirstResponder()
    }
}