Search code examples
iosswiftuitextfieldstrikethrough

SwiftUI - Strikethrough on TextField


Does anyone know how to achieve strikethrough effect that is constantly displayed in pure TextField ?

Sample code:

@State var textFieldText: String

var body: some View {
    TextField("some_prompt", text: $textFieldText)
        .strikethrough()
}

This compiles without problems, but it looks like this modifier is completely ignored, both in Previews and if you run the "app".


Solution

  • You could try this simple all SwiftUI approach, drawing a line through the TextField, such as:

    struct ContentView: View {
        @State private var text: String = "Strikethrough TextField"
    
        var body: some View {
            StrikethroughTextField(text: $text)
            .border(.blue)
            .padding()
        }
    }
    
    struct StrikethroughTextField: View {
        @Binding var text: String
        
        var body: some View {
            TextField("", text: $text)
                .padding(5)
                .background(
                    GeometryReader { geometry in
                        Path { path in
                            let lineY = geometry.size.height / 2
                            path.move(to: CGPoint(x: 0, y: lineY))
                            path.addLine(to: CGPoint(x: geometry.size.width, y: lineY))
                        }
                        .stroke(Color.black, lineWidth: 1)
                    }
                )
        }
    }
    

    EDIT-1

    Another approach is to use a simple AttributedString in an overlay, such as:

    struct ContentView: View {
        @State private var textFieldText: String = ""
        
        var striker: AttributedString {
            var result = AttributedString(textFieldText)
            result.font = .body
            result.strikethroughStyle = .single
            return result
        }
        
        var body: some View {
            TextField("prompt", text: $textFieldText)
                .foregroundColor(.clear)
                .overlay(Text(striker).foregroundColor(.black), alignment: .leading)
                .border(.red)
        }
    }