Home > Back-end >  SwiftUI FocusState not working when TextField is in ToolbarItem
SwiftUI FocusState not working when TextField is in ToolbarItem

Time:03-30

My purpose is to auto focus and remove focus.

The page that is launched for the first time can automatically get the focus, but if you push to the next page, it will automatically fail.

works this way


struct SearchTextFieldView: View {
    
    @FocusState var focused: Field?
    @State var username: String = ""
    
    enum Field: Int, Hashable {
        case name
    }
    
    var body: some View {
        NavigationView {
            VStack {
                Button {
                    focused = nil
                } label: {
                    Text("Remove Focuse")
                }
                .onAppear {
                    DispatchQueue.main.asyncAfter(deadline: .now()   1) {
                        focused = .name
                    }
                }
            }
            .toolbar {
                ToolbarItem(placement: .principal) {
                    TextField("user name", text: $username)
                        .focused($focused, equals: .name)
                        .disableAutocorrection(true)
                        .padding(4)
                        .border(.secondary)
                }
            }
            .navigationBarTitleDisplayMode(.inline)
        }
    }
}

push to the next page doesn't work


struct SearchRootView: View {
    
    var body: some View {
        NavigationView {
            NavigationLink {
                SearchTextFieldPushView()
            } label: {
                Text("Search")
            }
        }
    }
}

struct SearchTextFieldPushView: View {
    
    @FocusState var focused: Field?
    @State var username: String = ""
    
    enum Field: Int, Hashable {
        case name
    }
    
    var body: some View {
        VStack {
            Button {
                focused = nil
            } label: {
                Text("Remove Focuse")
            }
            .onAppear {
                DispatchQueue.main.asyncAfter(deadline: .now()   1) {
                    focused = .name
                }
            }
        }
        .toolbar {
            ToolbarItem(placement: .principal) {
                TextField("user name", text: $username)
                    .focused($focused, equals: .name)
                    .disableAutocorrection(true)
                    .padding(4)
                    .border(.secondary)
            }
        }
        .navigationBarTitleDisplayMode(.inline)
    }
}

Is there something wrong with the way I use it? still bug.

CodePudding user response:

It seems like NavigationView keeps the FocusState from the main view. But you can pass it down to the child view:

struct SearchRootView: View {
    
    @FocusState var focused: Field? // define here

    var body: some View {
        NavigationView {
            NavigationLink {
                SearchTextFieldPushView(focused: _focused) // pass down here
            } label: {
                Text("Search")
            }
        }
    }
}

enum Field {
    case name
}

struct SearchTextFieldPushView: View {
    
    @FocusState var focused: Field?
    
    @State var username: String = ""

    
    var body: some View {
        VStack {
            Button {
                focused = nil
            } label: {
                Text("Remove Focus")
            }

            .onAppear {
                DispatchQueue.main.asyncAfter(deadline: .now()   1) {
                    focused = .name
                }
            }
        }
        .toolbar {
            ToolbarItem(placement: .principal) {
                TextField("user name", text: $username)
                    .focused($focused, equals: Field.name)
                    .disableAutocorrection(true)
                    .padding(4)
                    .border(.secondary)
            }
        }
        .navigationBarTitleDisplayMode(.inline)
    }
}
  • Related