【SwiftUI】TextField の角を丸くして背景色を付けるもっとも簡単な方法は

これ簡単に作る方法ありませんかね。

角の丸い背景に色を付けた TextField。

なんか簡単にできないんですが、

いい方法ありませんか。

 

🧑‍💻 やってみる

「角を丸く」

「背景色を黄色に」

が同時にできません。


TextField("Search", text: $text)
  .frame(width: 200)
  .background(.yellow)

TextField("Search", text: $text)
  .frame(width: 200)
  .textFieldStyle(.roundedBorder)
  .background(.yellow) // NG
  .backgroundStyle(.yellow) // NG
  .tint(.yellow) // NG

👉 roundedBorder | Apple Developer Documentation hatena-bookmark

 

🧑‍💻 Chain Modifiers

一度、スタイルを plain にして、

padding を付けて、

背景に黄色い角丸四角を置きます。


// chain view modifiers
TextField("Search", text: $text)
  .textFieldStyle(.plain)
  .padding(6)
  .background(.yellow, in: .rect(cornerRadius: 6))
  .frame(width: 200)

しかし、数行続くと View 全体の見通しが悪くなるのがいやだ。

 

🧑‍💻 Create TextFieldStyle

TextField 専用のスタイルを作ってそれを適用します。


struct RoundedBordertFieldStyle: TextFieldStyle {
  var cornerRadius: CGFloat
  var color: Color

  func _body(configuration: TextField<Self._Label>) -> some View {
    configuration
      .textFieldStyle(.plain) // macOS
      .padding(cornerRadius)
      .background(color, in: .rect(cornerRadius: cornerRadius))
  }
}

extension TextFieldStyle where Self == RoundedBordertFieldStyle {
  static var roundedBorderYellow: Self {
    Self(cornerRadius: 6, color: .yellow)
  }
}


TextField("Search", text: $text)
  .textFieldStyle(RoundedBordertFieldStyle(cornerRadius: 6, color: .yellow)) // OK
  //.textFieldStyle(.roundedBorderYellow) // OK
  .frame(width: 200)

しかし、いちいちここまで書くのがいやだ。

_ (アンダースコア) もなんかいや。

👉 TextFieldStyle Protocol "makeBody" method hidden | Apple Developer Forums hatena-bookmark

 

🧑‍💻 Create View extension

ViewModifier を作ろうかと思ったが、

View の extension まででいいですよね。


extension View {
  func roundedBorder(cornerRadius: CGFloat, color: Color) -> some View {
    self
      .textFieldStyle(.plain)
      .padding(cornerRadius)
      .background(color, in: .rect(cornerRadius: cornerRadius))
  }
}


// create view extension (or view modifier)
TextField("Search", text: $text)
  .roundedBorder(cornerRadius: 6, color: .yellow)
  .frame(width: 200)

これぐらいがいいのかな。

 

🧑‍💻 Create Child View

新しく View を作って、それに押し込んじゃいます。


struct RoundedBorderTextField: View {
  var label: String
  @Binding var text: String
  var cornerRadius: CGFloat
  var color: Color

  var body: some View {
    TextField(label, text: $text)
      .textFieldStyle(.plain)
      .padding(cornerRadius)
      .background(color, in: .rect(cornerRadius: cornerRadius))
  }
}


// create child view
RoundedBorderTextField(label: "Search", text: $text, cornerRadius: 6, color: .yellow)
  .frame(width: 200)

最初からこれで良かったのでは。

 

🧑‍💻 まとめ

どれが一番いいんすかね。

macOS に切り替えなが思ったのは、

実際、TextField って、

「フォーカス」とかも

取り扱ってますよね。

それを考えると、

「@State を考慮してるやつ」

のがいいのかもしれません。

👉 【SwiftUI】市松模様を背景にする - Checkered Pattern Background 🏁 hatena-bookmark
👉 【SwiftUI】枠線付き角丸ボタンを簡単に作りたい hatena-bookmark