code

Swift에서 Return 키를 누르면 텍스트 필드 간 전환

codestyles 2020. 12. 6. 21:34
반응형

Swift에서 Return 키를 누르면 텍스트 필드 간 전환


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

미리 감사드립니다!


UITextField대리자가 설정되어 있고 태그가 제대로 증가 하는지 확인하십시오 . 이 작업은 Interface Builder를 통해서도 수행 할 수 있습니다.

다음은 내가 찾은 Obj-C 게시물에 대한 링크입니다. 텍스트 필드를 탐색하는 방법 (다음 / 완료 버튼)

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

스위프트 5

키보드에서 Return 키를 클릭하면 다른 TextField로 쉽게 전환 할 수 있습니다.

  • 첫째, 뷰 컨트롤러 ViewController에 위임 메서드를 준수 UITextFieldDelegate하고 추가합니다.textFieldShouldReturn(_:)
  • Interface Builder 에서 TextField 에서 ViewController드래그합니다 . 그런 다음 옵션을 선택하십시오 . 참고 : 모든 TextField에 대해이 작업을 수행합니다.delegate
  • IBOutlet모든 TextField에 대한 만들기

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

에서 switch 문을 사용하는 것이 좋습니다 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
}

이 접근 방식은 테이블 뷰와 컬렉션 뷰에서 약간의 변경이 필요하지만 간단한 양식에는 괜찮습니다.

textFields하나에 연결 IBOutletCollection하고 y 좌표로 정렬 textFieldShouldReturn(_:)한 다음 끝에 도달 할 때까지 다음 텍스트 필드로 이동합니다.

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

또는 샘플 프로젝트 (xcode 7 베타 4)를 살펴보십시오.


나는 많은 코드를 시도했고 마침내 이것은 Swift 3.0 Latest [2017 년 3 월] 에서 나를 위해 일했습니다 .

"ViewController"클래스는이 코드를 작동시키기 위해 "UITextFieldDelegate"를 상속 받아야합니다.

class ViewController: UIViewController,UITextFieldDelegate  

적절한 태그 번호가있는 텍스트 필드를 추가하면이 태그 번호가 할당 된 증분 태그 번호를 기반으로 적절한 텍스트 필드로 제어를 가져 오는 데 사용됩니다.

override func viewDidLoad() {

 userNameTextField.delegate = self

        userNameTextField.tag = 0

        userNameTextField.returnKeyType = UIReturnKeyType.next

        passwordTextField.delegate = self

        passwordTextField.tag = 1


        passwordTextField.returnKeyType = UIReturnKeyType.go

}

위의 코드에서 "returnKeyType = UIReturnKeyType.next"는 키패드 리턴 키가 "Next"로 표시되도록합니다. 또한 응용 프로그램에 따라 "Join / Go"등의 다른 옵션이 값을 변경합니다.

이 "textFieldShouldReturn"은 제어되는 UITextFieldDelegate의 메소드이며 여기에서 태그 값 증분에 따라 다음 필드 선택이 있습니다.

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
    }

Swift 4.0 의 Caleb 버전

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    if let nextField = self.view.viewWithTag(textField.tag + 1) as? UITextField {
        nextField.becomeFirstResponder()
    } else {
        textField.resignFirstResponder()
    }
    return false
}

textField.superview?나를 위해 작동하지 않는 PS


becomeFirstResponder()메서드에서 UIResponder 클래스의 메서드를 사용 하십시오 textFieldShouldReturn. 모든 UIView객체는 UIResponder의 하위 클래스입니다.

if self.emaillabel.isEqual(self.anotherTextField)
{
    self.anotherTextField.becomeFirstResponder()
}

becomeFirstResponder()방법에 대한 자세한 내용은 여기 의 Apple Doc에서 찾을 수 있습니다 .


스위프트 4.2

이것은 보다 일반적이고 가장 쉬운 솔루션입니다.이 코드를 원하는 양의 TextField와 함께 사용할 수 있습니다. UITextFieldDelegate를 상속 하고 순서에 따라 Textfield 태그를 업데이트 하고이 함수를 복사합니다.

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
}

스위프트 / 프로그래밍 방식

class MyViewController: UIViewController, UITextFieldDelegate {

    let textFieldA = UITextField()
    let textFieldB = UITextField()
    let textFieldC = UITextField()
    let textFieldD = UITextField()

    var textFields: [UITextField] {
        return [textFieldA, textFieldB, textFieldC, textFieldD]
    }

    override func viewDidLoad() {
        // layout textfields somewhere 
        // then set delegate
        textFields.forEach { $0.delegate = self }
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        if let selectedTextFieldIndex = textFields.firstIndex(of: textField), selectedTextFieldIndex < textFields.count - 1 {
            textFields[selectedTextFieldIndex + 1].becomeFirstResponder()
        } else {
            view.endEditing(true) // last textfield, dismiss keyboard directly
        }
        return true
    }
}

태그 사용을 좋아하지 않고 UITextField 대리자가 구성 요소를 분리하거나 단방향으로 유지하는 셀이되기를 원하는 순수 주의자를위한 대체 방법입니다.

  1. Cell과 TableViewController를 연결하는 새 프로토콜을 만듭니다.

    protocol CellResponder {
      func setNextResponder(_ fromCell: UITableViewCell)
    }
    
  2. 프로토콜을 셀에 추가합니다. 여기서 TextField Delegate는 셀이기도합니다 (스토리 보드에서 수행합니다).

    class MyTableViewCell: UITableViewCell, UITextFieldDelegate {
      var responder: CellResponder?
    
      func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        responder?.setNextResponder(self)
        return true
      }
    }
    
  3. TableViewController가 CellResponder 프로토콜 (예 :)을 준수하도록 만들고 class MyTableViewController: UITableViewController, CellResponder원하는대로 메서드를 구현합니다. 즉, 다른 셀 유형이있는 경우이를 수행 할 수 있습니다. 마찬가지로 IndexPath를 전달하고 태그를 사용할 수 있습니다. cell.responder = selfcellForRow 에서 설정하는 것을 잊지 마십시오 .

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

특별한 것은 없습니다. 현재 textFiled를 변경하는 데 사용하고 있습니다. 따라서 ViewController의 코드는 좋아 보입니다. :). # Swift4

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

텍스트 필드 구성 요소가 많으면 콘센트 컬렉션을 사용하고 텍스트 필드를 연결하고 인터페이스 빌더에서 Return 키를 설정하는 것이 더 나을 수 있습니다.

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

귀하의 질문에 대한 좋은 해결책이 있습니다.

단계:

1-스토리 보드에서 리턴 키를 설정하십시오.

enter image description here

2-신속한 파일에서.

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        if textField.returnKeyType == .next {
            Email.resignFirstResponder()
            Password.becomeFirstResponder()
        } else if textField.returnKeyType == .go {
            Password.resignFirstResponder()
            self.Login_Action()
        }
        return true
    }

3-Textfield의 대리자를 설정하는 것을 잊지 마십시오.

감사합니다 :)

참고URL : https://stackoverflow.com/questions/31766896/switching-between-text-fields-on-pressing-return-key-in-swift

반응형