SwiftUI:排除TextField点击避免键盘抖动,实现点击别处隐藏键盘
解决SwiftUI点击TextField时键盘抖动的问题
要实现点击页面其他区域隐藏键盘,同时点击TextField时避免键盘隐藏/显示的抖动,核心是让TextField的点击手势优先于父视图的隐藏键盘手势,阻止手势传递。以下是具体修改方案:
修改步骤
- 给每个TextField添加
highPriorityGesture(TapGesture()),确保点击TextField时优先响应自身的手势,不会触发父视图(List)的隐藏键盘逻辑。 - 保留原有的
onTapGesture用于点击其他区域隐藏键盘,保留FocusState和键盘隐藏方法不变。
修改后的完整代码
import SwiftUI struct ContentView: View { @FocusState var focus: FocusedField? @State var name = "" @State var email = "" @State var phoneNumber = "" var body: some View { List { TextField("Name:", text: $name) .focused($focus, equals: .name) .onSubmit { focus = .email } .highPriorityGesture(TapGesture()) // 添加高优先级点击手势 TextField("Email:", text: $email) .focused($focus, equals: .email) .onSubmit { focus = .phone } .highPriorityGesture(TapGesture()) // 添加高优先级点击手势 TextField("PhoneNumber:", text: $phoneNumber) .focused($focus, equals: .phone) .onSubmit { if !name.isEmpty && !email.isEmpty && !phoneNumber.isEmpty { submit() } } .highPriorityGesture(TapGesture()) // 添加高优先级点击手势 } .onTapGesture { if focus != nil { hideKeyboard() } } } private func submit() { print("submit") } enum FocusedField: Hashable { case name, email, phone } } extension View { func hideKeyboard() { let resign = #selector(UIResponder.resignFirstResponder) UIApplication.shared.sendAction(resign, to: nil, from: nil, for: nil) } }
原理说明
highPriorityGesture会让TextField的点击手势优先级高于父视图的onTapGesture,当点击TextField时,只会触发TextField本身的焦点获取逻辑,不会触发List的隐藏键盘操作,从而避免键盘先隐藏再弹出的抖动。- 点击List的空白区域或其他非TextField区域时,依然会触发
onTapGesture中的隐藏键盘逻辑,满足需求。
内容的提问来源于stack exchange,提问作者Shrikant Phadke
相关产品推荐
相关产品推荐

