🙄
【SwiftUI】TextFieldのタップエリアが狭すぎる
SwiftUI Tipsです。
問題
このようなデザインのSwiftUIの入力フィールドを実装しました。
TextFieldの範囲に対して、ちょっとマージンがあって、枠線があるデザインです。
コードは↓こんな実装です。
struct MailInputView: View {
@State var email: String = ""
@FocusState private var focusedField: Field?
enum Field: Hashable {
case email
}
var body: some View {
TextField("メールアドレス", text: $email)
.font(.body)
.keyboardType(.emailAddress)
.padding(.horizontal, 8)
.frame(height: 48)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(.gray, lineWidth: 1)
)
.padding()
.focused($focusedField, equals: .email)
}
}
これで最低限の機能は実現できるんですが、実機で触ってみると
「なんかタップ範囲やたら狭いな」という感覚がありました。
なぜそう感じたのかというと、タップ範囲が↓このエリアになるためです。
視覚的にはグレー線の中が全てタップ可能と感じますが、
実際はTextField
がタップ範囲なので、実際は赤線の中になります。
対策
SwiftUIのタップ範囲について調べると、だいたい.contentShape
つけて、.onTapGesture
をつけろというアドバイスが出てきます。
今回のケースでもこのアプローチしかなさそうです。
本当はTextFieldにタップ範囲広くできる何かがあると良かったのですが。
struct MailInputView: View {
var body: some View {
TextField("メールアドレス", text: $email)
.font(.body)
.keyboardType(.emailAddress)
.padding(.horizontal, 8)
.frame(height: 48)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(.gray, lineWidth: 1)
)
+ .contentShape(.rect)
+ .onTapGesture {
+ focusedField = .email
+ }
.padding()
.focused($focusedField, equals: .email)
}
}
これで直感的にTextFieldが反応するようになりました。
おまけ
加えてですが、TextFieldの外をタップしたら、フォーカスを外すというのも欲しい動作です。
これはSwiftUIだとサラッと実現できました。
var body: some View {
VStack {
// …
}
.onTapGesture {
focusedField = nil
}
}
このようにonTapGestureを指定してあげると、いい感じにフォーカスが外れました。
(了)
Discussion