Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI - Mutable @FocusState for child view?

I have a parent view with a @FocusState variable that I want to pass into a child view that contains a TextField. I want to be able to change the FocusState from within the child view, but I get the errors Cannot assign to property: 'self' is immutable and Cannot assign value of type 'Bool' to type 'FocusState<Bool>.Binding'.

Parent view:

struct ParentView: View {
    @State private var text: String
    @FocusState private var isEditing: Bool
    
    var body: some View {
        ChildView($text, $isEditing)
    }
}

struct ChildView: View {
    @Binding var text: String
    var isEditing: FocusState<Bool>.Binding
    
    init(_ text: Binding<String>, _ isEditing: FocusState<Bool>.Binding) {
        self._text = text
        self.isEditing = isEditing
    }
    
    var body: some View {
        TextField("Username", text: $text)
            .focused(isEditing)
        
        Button("Click me!") {
            isEditing = false  // Error here
        }
    }
}
like image 727
Kyle Horkley Avatar asked Sep 05 '25 01:09

Kyle Horkley


2 Answers

Just assign via binding to wrapped value, like

Button("Click me!") {
    isEditing.wrappedValue = false  // << here !!
}
like image 128
Asperi Avatar answered Sep 07 '25 13:09

Asperi


With iOS 15.0+, you can use FocusState.Binding in order to pass your focus state to your child view.

The code snippet below shows how to implement it:

struct ParentView: View {
    @State private var text = ""
    @FocusState private var isEditing: Bool

    var body: some View {
        ChildView(text: $text, isEditing: $isEditing)
            .onChange(of: isEditing) { oldValue, newValue in
                print(newValue) // Track the changes of focus state
            }
    }
}

struct ChildView: View {
    @Binding var text: String
    @FocusState.Binding var isEditing: Bool

    var body: some View {
        TextField("Username", text: $text)
            .focused($isEditing)

        Button("Click me!") {
            isEditing = false
        }
    }
}
like image 36
Imanou Petit Avatar answered Sep 07 '25 11:09

Imanou Petit