当 TextField 在 ToolbarItem 中时,SwiftUI FocusState 不工作

SwiftUI FocusState not working when TextField is in ToolbarItem

我的目的是自动对焦和移焦。

第一次启动的页面可以自动获取焦点,但是如果推到下一页,会自动失败

这样工作


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)
        }
    }
}

无法推送到下一页


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)
    }
}

是不是我的使用方式有问题?还是bug。

似乎 NavigationView 使 FocusState 远离主视图。但是您可以将它传递给子视图:

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)
    }
}