Implementing custom modifier with state logic

Inspired by the answer in this post I've been trying to implement the same idea with the addition of state handling inside the modifier.

ViewModifier supports this, but the custom implementation does not trigger the state change.

I wonder what would be missing from the custom implementation below to make it work with local state.

An example:
Here the tap is triggered, however, the view does not update.

protocol TextModifier {
  associatedtype Body: View

  func body(text: Text) -> Body
}
extension Text {
  func modifier<TM: TextModifier>(_ _modifier: TM) -> some View {
    return _modifier.body(text: self)
  }
}

struct HulkSmash: TextModifier {
  @State var isHulk: Bool = false

  func body(text: Text) -> some View {
    text.bold()
      .font(isHulk ? .system(.largeTitle, design: .rounded) : .body)
      .foregroundColor(isHulk ? .init(.systemGreen) : .init(.systemFill))
      .onTapGesture {
        print("tap triggered")
        isHulk.toggle()
      }
  }
}

struct ViewModifierTestView: View {
  var body: some View {
    Text("Test")
      .modifier(HulkSmash())
  }
}

Working example with ViewModifier:

struct TapToTitle: ViewModifier {
  @State private var isTitle: Bool = false
  func body(content: Content) -> some View {
    VStack {
      content
        .font(isTitle ? .title : .body)
    }.onTapGesture {
      isTitle.toggle()
    }
  }
}

struct ViewModifierTestView: View {
  var body: some View {
    Text("Test")
      .modifier(TapToTitle())
  }
}
Post not yet marked as solved Up vote post of MartinP7r Down vote post of MartinP7r
974 views