onmyway133 / blog

🍁 What you don't know is what you haven't learned
https://onmyway133.com/
MIT License
669 stars 33 forks source link

How to pass FocusState binding in SwiftUI #896

Open onmyway133 opened 1 year ago

onmyway133 commented 1 year ago

Use underscore _focus we get access to underlying FocusState object, but underscore _ is private to a View hence can't be used in extension

If we want to pass FocusState to another View or in extension, we can pass its Binding

enum FocusElement: Hashable {
    case name
    case email
}

struct ParentView: View {
    @FocusState var focus: FocusElement?

    var body: some View {
        ChildView1(focus: _focus)
        ChildView2(focus: $focus)
    }
}

struct ChildView1: View {
    @FocusState var focus: FocusElement?

    var body: some View {
        TextField("Name", text: .constant(""))
            .focused($focus, equals: .name)
    }
}

struct ChildView2: View {
    var focus: FocusState<FocusElement?>.Binding

    var body: some View {
        TextField("Email", text: .constant(""))
            .focused(focus, equals: .name)
            .onAppear {
                focus.wrappedValue = .email
            }
    }
}