1
2

More than 1 year has passed since last update.

[SwiftUI] デフォルトでfocusが当てられたTextFieldにするために頑張った

Posted at

はじめに

SwiftUIにはTextFieldというテキストを入力するためのViewがデフォルトで準備されているのですが、viewをロードした段階ですでにTextFieldにフォーカスが当てられているような方法が見つからなかったので、今回はその実装をしてみました。

したいこと

下の画像のように、viewが読み込まれた時にデフォルトでTextFieldにフォーカスが当てられているようにしました。

また、本記事では説明しませんが、今回はクロスワードアプリを作っていたので、文字入力がされると、次のブロックへ移動して新たなTextFieldにフォーカスが当たるようにしました。

スクリーンショット 2023-08-06 23.20.36.png

スクリーンショット 2023-08-06 23.20.45.png

実装

import SwiftUI

struct FocusableTextField: UIViewRepresentable {
    
    class Corrdinator: NSObject, UITextFieldDelegate {
        
        @Binding var text: String
        var didBecomeFirstResponder = false
        
        init(text: Binding<String>) {
            _text = text
        }
        
        func textFieldDidChangeSelection(_ textField: UITextField) {
            text = textField.text ?? ""
        }
    }
    
    @Binding var text: String
    var isFirstResponder: Bool = false
    
    func makeUIView(context: UIViewRepresentableContext<FocusableTextField>) -> UITextField {
        let textField = UITextField(frame: .zero)
        textField.delegate = context.coordinator
        return textField
    }
    
    func makeCoordinator() -> FocusableTextField.Corrdinator {
        return Coordinator(text: $text)
    }
    
    func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<FocusableTextField>) {
        uiView.text = text
        if isFirstResponder && !context.coordinator.didBecomeFirstResponder {
            uiView.becomeFirstResponder()
            context.coordinator.didBecomeFirstResponder = true
        }
    }
}

上の処理の流れとしては以下の感じです。

  • FocusableTextFieldというUIViewRepresentableプロトコルを継承したstructを作成します。このUIViewRepresentableというのはSwift UIとUIKitの橋渡しを行なってくれます。
  • makeUIViewというメソッドで新しいUITextFieldを生成し。UITextFieldDelegateをCoordinatorに割り当てることでテキストフィールドの状態を監視しています。
  • updateUIViewでフォーカスの処理を行っています。ここではisFirstResponderやdidBecomeFirstResponderの状態を監視して、必要に応じてuiView.becomeFirstResponder()を呼び出します。ここで使用しているbecomeFirstResponder()はUILitのメソッドで、呼び出されるとそのviewが一番はじめに入力操作を受け付けるようになるため、今回したかったことが実現されます。

最後に

色々調べてみても、フォーカスの検知などの記事しか見つからなかったため、今回は自作でデフォルトでフォーカスが当てられるTextFieldの実装を行なってみました。もしSwift UIでそのようなViewがデフォルトで用意されていたり、良い方法をご存知の方いれば教えていただけると幸いです。
ではここまで読んでくれてありがとうございました^^

参考文献

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2