DEV Community

Andrey Plotnikov
Andrey Plotnikov

Posted on

SwiftUI Custom Style

In this post I would like to share my approach to style different views.

Some time ago, I wanted to customize SwiftUI Textfield, but TextFieldStyle API is not exposed to public and looks like this:

struct MyTextFieldStyle: TextFieldStyle {
    func _body(configuration: TextField<Self._Label>) -> some View {
        VStack(spacing: 0) {
            configuration
            .font(font)
            Rectangle().frame(maxWidth: .infinity, maxHeight: 2)
        }
    }

    let font = Font.system(size: 37, weight: .bold)
}
Enter fullscreen mode Exit fullscreen mode

But I think, Apple won't allow to use that, and I came up with new approach.

Firstly, let's create typealias to ViewModifier

typealias CustomTextFieldStyle = ViewModifier

extension View {
  func customTextFieldStyle<S>(_ style: S) -> some View where S: CustomTextFieldStyle {
    modifier(style)
  }
}

Enter fullscreen mode Exit fullscreen mode

Now, all I need is just create struct, that will implement CustomTextFieldStyle.

struct LargeTextFieldStyle: CustomTextFieldStyle {

   func body(content: Content) -> some View {
      VStack(spacing: 2) {
         content
            .font(font)
            .disableAutocorrection(true)
            .autocapitalization(.words)
         Rectangle().foregroundColor(Color.blue).frame(maxWidth: .infinity, maxHeight: 2)
      }
   }

   let font: Font = Font.system(size: 26, weight: .bold)
}
Enter fullscreen mode Exit fullscreen mode

Also with Swift 5.5 new feature, that allow to extend generics, thus we can extend our CustomTextFieldStyle type and use it even more simpler

extension CustomTextFieldStyle where Self == LargeTextFieldStyle {
  static var large: LargeTextFieldStyle { LargeTextFieldStyle() }
}
Enter fullscreen mode Exit fullscreen mode

You can checkout full code in this gist

Discussion (0)