在 SwiftUI 中,@FocusState 是一个属性包装器,用于管理和跟踪视图中的焦点状态,通常用于控制 TextField、TextEditor 或按钮等可聚焦组件的键盘焦点。它可以帮助你实现以下功能:
- 控制键盘的弹出和收起
- 在多个输入框之间切换焦点(例如登录表单的“下一步”跳转)
- 结合
onSubmit实现表单提交逻辑
基本用法
1. 控制单个 TextField 的焦点
import SwiftUI
struct ContentView: View {
@State private var text: String = ""
@FocusState private var isFocused: Bool // 表示是否获得焦点
var body: some View {
VStack {
TextField("请输入内容", text: $text)
.focused($isFocused) // 绑定焦点状态
.textFieldStyle(.roundedBorder)
.padding()
Button("切换焦点") {
isFocused.toggle() // 手动控制焦点
}
}
.padding()
}
}
@FocusState定义了一个布尔值isFocused,表示TextField是否获得焦点。.focused($isFocused)绑定焦点状态。- 点击按钮可以切换
TextField的焦点状态(键盘弹出/收起)。
2. 多个 TextField 之间切换焦点
struct ContentView: View {
@State private var username: String = ""
@State private var password: String = ""
// 定义焦点状态,使用枚举管理不同输入框
enum FocusField: Hashable {
case username, password
}
@FocusState private var focusedField: FocusField?
var body: some View {
VStack {
TextField("用户名", text: $username)
.focused($focusedField, equals: .username)
.textFieldStyle(.roundedBorder)
.submitLabel(.next) // 键盘右下角显示“下一步”
.onSubmit {
focusedField = .password // 按下“下一步”跳转到密码输入框
}
TextField("密码", text: $password)
.focused($focusedField, equals: .password)
.textFieldStyle(.roundedBorder)
.submitLabel(.done) // 键盘右下角显示“完成”
.onSubmit {
focusedField = nil // 收起键盘
}
Button("登录") {
if username.isEmpty {
focusedField = .username
} else if password.isEmpty {
focusedField = .password
} else {
focusedField = nil // 收起键盘
// 处理登录逻辑...
}
}
}
.padding()
.onAppear {
// 页面加载时自动聚焦用户名输入框
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
focusedField = .username
}
}
}
}
- 使用
enum管理多个输入框的焦点,避免硬编码。 .submitLabel(.next)修改键盘右下角按钮为“下一步”,方便用户跳转。.onSubmit监听键盘的“提交”操作,自动切换焦点或提交表单。
进阶用法
1. 结合 onAppear 自动聚焦
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
focusedField = .username
}
}
- 页面加载后自动聚焦第一个输入框(
DispatchQueue延迟确保动画流畅)。
2. 检测键盘是否弹出
@FocusState private var isKeyboardVisible: Bool
- 可以用
isKeyboardVisible判断键盘是否弹出,并调整布局(例如上移输入框避免遮挡)。
3. 结合 ScrollView 优化输入体验
ScrollView {
VStack {
// 多个输入框...
}
}
- 当键盘弹出时,
ScrollView可以滚动,确保输入框可见。
总结
| 场景 | 代码示例 |
|---|---|
| 单个输入框焦点控制 | @FocusState var isFocused + .focused($isFocused) |
| 多个输入框切换 | enum FocusField + @FocusState var focusedField |
| 键盘“下一步”跳转 | .submitLabel(.next) + .onSubmit |
| 自动聚焦 | .onAppear { focusedField = .username } |
| 手动收起键盘 | focusedField = nil |
@FocusState 是 SwiftUI 中管理键盘焦点的推荐方式,比传统的 UIResponder(becomeFirstResponder)更简洁高效。适用于表单、搜索框、登录页等场景。