2017-04-23 2 views
1

나는 사용자가 동사의 과거 시제를 입력해야하는 게임을하고 있습니다. 내보기에는 한 문자 만 허용하는 작은 텍스트 상자가 있습니다. 지금 나는 전자가 편지를 포함하고있을 때 자동으로 다음 텍스트 필드로 건너 뛰려고합니다.Swift - 비어 있지 않으면 자동으로 다음 텍스트 필드로 이동합니다.

모든 상자가 채워질 때까지 계속하고 싶습니다. 사용자는 키보드의 반환 버튼을 사용하여 하나의 상자로 돌아갈 수 있어야합니다.

아래 코드는 현재 사용하고 있지만 다음 텍스트 필드로 점프하지 않습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

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

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

대답 다음에 textField로 이동하려고 할 때 반환 nil을 :

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

답변

3

내가 제안 제어 이벤트에 대상을 추가해야합니다. .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() 
    } 
} 
+0

를하지만, 전혀의 TextChanged 함수를 호출 아니에요. Swift 3.0과 일치하기는하지만 조금 업데이트되었습니다. –

+0

'func textChanged (보낸 사람 : UITextField) { if (sender.text? .characters.count)! > 0 { print ("Test") nextField = textField.superview? .viewWithTag (textField.tag +1)을? UITextField nextField? .FirstResponder() } }' –

+0

@DennisvanMazijk 어디에서'addTarget' 호출을 했습니까? 'addTarget' 호출이 실행되는지 확인하십시오. – Sweeper

1

코드에 따라 : 나는 당신의 접근 방식을 시도

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


    } 


}