【问题标题】:Swift - Automatically jump to next text field when not emptySwift - 不为空时自动跳转到下一个文本字段
【发布时间】:2017-04-23 16:06:08
【问题描述】:

我正在开发一个游戏,用户必须输入动词的过去时。我的视图包含只接受一个字符的小文本框。截至目前,当前者包含一个字母时,我正试图自动跳转到下一个文本字段。

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

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

 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
}

更新代码 (24-04-2017) - 尝试跳转到下一个文本字段时返回 nil

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.addTarget(self, action: #selector(textChanged), for: .editingChanged)
                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 textChanged(sender: UITextField) {
    if (sender.text?.characters.count)! > 0 {
        print("Entered")
        let nextField = textField?.superview?.viewWithTag(textField.tag + 1) as UIResponder!

        if (nextField != nil) {
            nextField?.becomeFirstResponder()
        } else {
            print("Error: nil found")
        }
    } else {
        print("Removed")
        textField?.resignFirstResponder()
    }
}

答案:

var index: NSInteger = 0
for textField in views {
    textField.backgroundColor = UIColor.white
    textField.textColor = Constants.MAIN_THEME_COLOR
    textField.textAlignment = NSTextAlignment.center
    textField.autocapitalizationType = UITextAutocapitalizationType.none
    textField.delegate = self
    textField.addTarget(self, action: #selector(textChanged), for: .editingChanged)
    textField.tag = index
    self.container.addArrangedSubview(textField)

    index+=1
}

func textChanged(sender: UITextField) {
    if (sender.text?.characters.count)! > 0 {
        let nextField = sender.superview?.viewWithTag(sender.tag + 1) as UIResponder!
        nextField?.becomeFirstResponder()
    } else {
        sender.resignFirstResponder()
    }
}

【问题讨论】:

    标签: swift uitextfield


    【解决方案1】:

    我建议你应该在控制事件.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()
        }
    }
    

    【讨论】:

    • 我已经尝试过你的方法,但它根本没有调用 textChanged 函数。稍微更新了一下,以符合 Swift 3.0。
    • func textChanged(sender: UITextField) { if (sender.text?.characters.count)! &gt; 0 { print("Test") let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField nextField?.becomeFirstResponder() } }
    • @DennisvanMazijk 你把addTarget 电话放在哪里了?检查addTarget 调用是否被执行。
    • 在委托下的for循环中。
    • @DennisvanMazijk 那么执行了吗?您是否设置了game 属性?
    【解决方案2】:

    关注代码:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-15
        • 1970-01-01
        • 2022-07-31
        • 2017-12-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-07
        • 2016-03-21
        相关资源
        最近更新 更多