web-dev-qa-db-ja.com

Swiftでリターンキーを押すとテキストフィールドを切り替える

IOSアプリを設計していますが、iPhoneでReturnキーを押すと、次のテキストフィールドに移動するようになります。

私はいくつかの同様の質問を見つけましたが、周りには優れた答えがありますが、それらはすべて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.
}

事前の仲間に感謝します!

57
lucas rodriguez

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

Swift 5

キーボードのReturnキーをクリックすると、別のTextFieldに簡単に切り替えることができます。

  • まず、View ControllerはUITextFieldDelegateに準拠し、ViewControllertextFieldShouldReturn(_:)デリゲートメソッドを追加します
  • TextFieldからViewController in Interface Builderにドラッグします。次に、delegateオプションを選択します。 :すべてのTextFieldに対してこれを行います
  • すべてのIBOutletを作成しますTextFields

    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
      }
    }
    
22
Vinoth Vino

textFieldShouldReturn(_:)でswitchステートメントを使用することをお勧めします。

// 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
}
11
kubacizek

このアプローチでは、テーブルビューとコレクションビューを多少変更する必要がありますが、単純なフォームでは問題ありません。

textFieldsを1つの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 beta 4)を見てください

8
libec

私は多くのコードを試してみましたが、最終的にこれはSwift 3.0 Latest [March 2017]

このコードを機能させるために、「ViewController」クラスは「UITextFieldDelegate」を継承する必要があります。

class ViewController: UIViewController,UITextFieldDelegate  

適切なタグnuberでテキストフィールドを追加し、このタグ番号を使用して、割り当てられた増分タグ番号に基づいて適切なテキストフィールドにコントロールを取得します。

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

カレブバージョンSwift 4.

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?が機能していません

3
coldembrace

Swift 4.2

これはより一般的で最も簡単なソリューションであり、このコードは任意の量のTextFieldで使用できます。 ITextFieldDelegateを継承し、順序に従ってTextfield Tagを更新して、この関数をコピーするだけです。

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
}
2
Lahiru Pinto

textFieldShouldReturnメソッドでUIResponderクラスのbecomeFirstResponder()メソッドを使用するだけです。すべてのUIViewオブジェクトはUIResponderのサブクラスです。

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

becomeFirstResponder()メソッドの詳細については、[ here のApple Docにあります。

2

スイフト/プログラム

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
    }
}
1
T. Wei

テキストフィールドコンポーネントがたくさんある場合は、アウトレットコレクションを使用して、テキストフィールドをリンクし、インターフェイスビルダーからリターンキーを設定する方が良いかもしれません

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

特別なことはありません。ここでは、テキストフィールドを変更するために現在使用しています。 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
        }
    }
}
1
Stephen Chen

タグの使用を好まない純粋主義者向けの代替メソッドであり、UITextFieldデリゲートをコンポーネントに分離または単方向に保つためのセルにしたい...

  1. CellとTableViewControllerをリンクする新しいプロトコルを作成します。

    protocol CellResponder {
      func setNextResponder(_ fromCell: UITableViewCell)
    }
    
  2. TextFieldデリゲートがセルでもあるプロトコルをセルに追加します(これはストーリーボードで行います)。

    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を渡したり、タグを使用したりすることができます。cellForRowにcell.responder = selfを設定することを忘れないでください。

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

あなたの質問には良い解決策があります。

STEP:

1-ストーリーボードからリターンキーを設定します。

enter image description here

2-Swiftファイル内。

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のデリゲートを設定することを忘れないでください。

ありがとうございました :)

0
Parth Patel