SwiftUI.searchableの各項目の色を個別に変更する

に公開

SwiftUI.searchable

searchable(text:placement:prompt:)で検索フィールドを設定できるのですが、検索フィールドの各部品の色を変更するAPIが存在しません。
promptにTextが入るので、foregroundColor(.white)をつけてみるのですが、効きません。
なのでUIKitを触れるSwiftUI Introspectを使って色を変えていきます。

  • 虫眼鏡の色
  • プレースホルダーの文字色
  • 入力中の文字色
  • クリア(X)ボタンの色
  • キャンセルボタンの文字色

SwiftUI Introspecで実装

struct ContentView: View {
  @State var text = ""
  var body: some View {
    NavigationStack {
      List {
        Section("Items") {
          ForEach(0..<20) { i in
            Text("item \(i)")
          }
        }
      }
      .navigationTitle("Home")
      .toolbarBackground(Color.slack, for: .navigationBar)
      .toolbarBackground(.visible, for: .navigationBar)
      .searchable(
        text: $text,
        prompt: Text("Seach products...")
      )
    }
    .introspect(.searchField, on: .iOS(.v18)) {
      // プレースホルダーの文字色
      $0.searchTextField.attributedPlaceholder = NSAttributedString(
        string: "Seach products...",
        attributes: [.foregroundColor: UIColor.red]
      )
      // 虫眼鏡の色
      $0.searchTextField.leftView?.tintColor = .green
      // クリア(X)ボタンの色
      let clearButton = $0.searchTextField.value(forKey: "clearButton") as! UIButton
      clearButton.setImage(
        clearButton.imageView?.image?.withRenderingMode(.alwaysTemplate),
        for: .normal
      )
      clearButton.tintColor = UIColor.blue
      // キャンセルボタンの文字色
      $0.tintColor = .yellow
      // 入力中の文字色
      $0.searchTextField.textColor = .brown
    }
  }
}

extension Color {
  static let slack = Color(red: 60/255, green: 16/255, blue: 66/255)
}

Discussion