Daniel Kubicek
Daniel Kubicek

Reputation: 331

How to change SwiftUI TextField style after tapping on it?

I changed TextField style like this:

TextField("Test", text: $name).textFieldStyle(CustomTextFieldStyle())

now I want it to change style when user taps on it.

My CustomTextFieldStyle is defined as:

  public struct CustomTextFieldStyle : TextFieldStyle {
    public func _body(configuration: TextField<Self._Label>) -> some View {
        configuration
            .font(.callout)
            .padding(10)
            .background(
                RoundedRectangle(cornerRadius: 4)
                    .strokeBorder(SBGreen, lineWidth: 2))
    }
}

Upvotes: 11

Views: 13830

Answers (3)

Leszek Szary
Leszek Szary

Reputation: 10336

While implementing custom TextFieldStyle with func _body(configuration: TextField<Self._Label>) as proposed in other answers works fine and has some pros it is worth noticing that this method is not mentioned anywhere in the documentation unlike for example func makeBody(configuration: Configuration) functions in ButtonStyle or ToggleStyle which are mentioned in the documentation. Also _ prefix in the method name suggest that this isn't a final/official method yet so it might be a better idea to create a ViewModifier instead as below:

struct CustomTextFieldStyle: ViewModifier {
    @FocusState private var focused: Bool
    func body(content: Content) -> some View {
        content
            .font(.callout)
            .padding(10)
            .background(RoundedRectangle(cornerRadius: 4).strokeBorder(focused ? .green : .black, lineWidth: 2))
            .focused($focused)
    }
}

extension View {
    func customTextFieldStyle() -> some View {
        modifier(CustomTextFieldStyle())
    }
}

and then use it like this:

TextField("Name", text: $name)
    .customTextFieldStyle()

As you can see you also do not need to create a separate FocusState for each text field if you only want to use it for styling as it is included in the ViewModifier.

Upvotes: 0

headstream
headstream

Reputation: 226

Actual variant is

import SwiftUI

struct CustomInput: View {
   @Binding var input: String
   @FocusState private var editing

   let width: CGFloat
   let placeholder: String

  var body: some View {
      TextField(
          "",
          text: $input,
          prompt: Text(placeholder)
      )
      .frame(width: width, height: 37)
      .textFieldStyle(BorderedStyle(focused: editing))
      .focused($editing)
      .multilineTextAlignment(.center)
      .keyboardType(.numberPad)
    }
 }


struct BorderedStyle: TextFieldStyle {
  var focused: Bool

  func _body(configuration: TextField<Self._Label>) -> some View {
      configuration
      .padding(10)
      .background(
          Rectangle()
              .stroke(
                  focused ? Color.red : Color.grey, lineWidth: 2
              )
      )
  }}

Upvotes: 4

user3441734
user3441734

Reputation: 17544

TextField("Test", text: $name).textFieldStyle(tapflag ? CustomTextFieldStyle1() : CustomTextStyle2())

do you have an example of your own TextStyle? Please, share it!

UPDATE

you are better to use some parameter with your style and bind it to "parent" View

import SwiftUI

struct ContentView: View {

    @State private var email = ""
    @State private var editing = false
    var body: some View {
        TextField("Email", text: self.$email, onEditingChanged: { edit in
            self.editing = edit
        })
            .textFieldStyle(MyTextFieldStyle(focused: $editing)).font(.title).border(Color.blue)
    }
}

struct MyTextFieldStyle: TextFieldStyle {
    @Binding var focused: Bool
    func _body(configuration: TextField<Self._Label>) -> some View {
        configuration
        .padding(10)
        .background(
            RoundedRectangle(cornerRadius: 10, style: .continuous)
                .stroke(focused ? Color.red : Color.gray, lineWidth: 3)
        ).padding()
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

the result looks like enter image description here

Upvotes: 24

Related Questions