Search code examples
swiftuifontsswiftui-buttonswiftui-text

Is there a way to set font tracking (i.e. spacing) inside a custom SwiftUI ButtonStyle?


In SwiftUI you can set font tracking (spacing between letters) on a Text View using the tracking View modifier:

Text("Hello, World!")
  .tracking(10)

If you have a Button and apply your custom ButtonStyle you can do all kinds of modifications to the style of the button, but since the configuration.label is not an instance of Text but rather ButtonStyleConfiguration.Label, I don't have direct access to apply tracking. Is there a way to do this without having to set it on the Button's label View directly? It seems like something you ought to be able to do since it's a style-related thing but I don't see how to accomplish it.

public struct MyStyle: ButtonStyle {
    public func makeBody(configuration: Configuration) -> some View {
        configuration.label
          // (if I tried to put `.tracking` here it wouldn't work because it isn't Text)
          .foregroundColor(Color.red)
          .clipShape(Capsule())
          // … etc.
    }
}

ViewModifier to change both font and tracking looks ~ related but no relevant answer.


Solution

  • Yes, ButtonStyleConfiguration.Label is not matched to Text, but it is your style you can ignore standard label, and request own by interface contract, exactly which you need (Text in this case), like in below demo

    public struct MyStyle: ButtonStyle {
        let label: Text                   // << here !!
    
        public func makeBody(configuration: Configuration) -> some View {
            label               // << here !!
                .tracking(10)
                .foregroundColor(configuration.isPressed ? .black : .red)
                .clipShape(Capsule())
        }
    }
    

    and use it as (or create own button extension with button builder to hide those unneeded curls)

    Button(action: {
            // action here
        }){}
        .buttonStyle(MyStyle(label: Text("Hello")))
    

    Tested with Xcode 13.2 / iOS 15.2

    enter image description here