当 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)
}
}
我的目的是自动对焦和移焦。
第一次启动的页面可以自动获取焦点,但是如果推到下一页,会自动失败
这样工作
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)
}
}