Search code examples
swiftuitextfieldtextfieldstyle

Type mismatch between SwiftUI textFieldStyle modifiers RoundedBorderTextFieldStyle and PlainTextFieldStyle


I'm attempting to change the .textFieldStyle modifier for a TextField based upon whether my View is editing. I declare var isEditing: Bool, set this in the parent View and check against this in the body. My code:

TextField("Type a Name", text: $name) {
    myManagedObjectObserved.attribute = name
}
.textFieldStyle(isEditing ? RoundedBorderTextFieldStyle() : PlainTextFieldStyle())

The compiler complains with the following build time error...

Result values in '? :' expression have mismatching types 'RoundedBorderTextFieldStyle' and 'PlainTextFieldStyle'

Don't understand why? Is anyone able to explain please?


Solution

  • They are different types, so swift type checking reports error.

    Here is possible solution (tested with Xcode 12)

    @ViewBuilder
    var body: some View {
        if isEditing {
            TextField("Type a Name", text: $name) {
                myManagedObjectObserved = name
            }
            .textFieldStyle(RoundedBorderTextFieldStyle())
        } else {
            TextField("Type a Name", text: $name) {
                myManagedObjectObserved = name
            }
            .textFieldStyle(PlainTextFieldStyle())
        }
    }
    

    Update: more convenient variant (with same idea)

    extension TextField {
        @ViewBuilder
        func editingStyle(if flag: Bool) -> some View {
            if flag {
                self.textFieldStyle(RoundedBorderTextFieldStyle())
            } else {
                self.textFieldStyle(PlainTextFieldStyle())
            }
        }
    }
    
    struct TestView: View {
        @State private var name = ""
        @State private var isEditing = false
    
        @ViewBuilder
        var body: some View {
            TextField("Type a Name", text: $name) {
                myManagedObjectObserved = name
            }
            .editingStyle(if: isEditing)
        }
    }