前语

SwiftUI Release 引进了强壮的新功用,其间之一是辅佐焦点办理。

这个新功用使得在SwiftUI中处理辅佐技能(如 VoiceOver 和 Switch Control)的焦点状况变得更加轻松。本文将介绍怎么运用 @FocusState 特点包装器来在SwiftUI中办理和移动辅佐焦点。

运用 @FocusState 特点包装器

在 SwiftUI Release 中,咱们获得了一整套特殊东西来更有效地处理辅佐焦点。其间包括 @FocusState 特点包装器和 focused 视图修饰符。经过运用这些东西,咱们能够以与无辅佐技能相同的方式处理辅佐焦点。

中心代码如下:

import SwiftUI
struct SignInView: View {
    @FocusState
    private var isEmailFocused: Bool
    @State private var email = ""
    var body: some View {
        NavigationView {
            Form {
                TextField("Email", text: $email, prompt: Text("Enter your email"))
                    .focused($isEmailFocused)
            }
            .navigationTitle("Sign In")
            .onChange(of: isEmailFocused) { newValue in
                print(newValue)
            }
        }
    }
}

如上例所示,咱们运用 @FocusState 特点包装器界说一个变量,表明 email 字段是否聚集。SwiftUI 默许运用 false初始化该变量,由于用户能够聚集屏幕的任何其他区域。咱们还运用 focused 视图修饰符将特定视图的焦点状况绑定到保存其值的变量。

请记住,您能够声明尽需求的变量,以运用 @FocusState 特点包装器涵盖辅佐焦点逻辑。

高档技巧:专用辅佐技能

中心代码如下:

import SwiftUI
struct SignInView: View {
    @FocusState
    private var isEmailFocused: Bool
    @FocusState
    private var isPasswordFocused: Bool
    @State private var email = ""
    @State private var password = ""
    var body: some View {
        NavigationView {
            Form {
                TextField("Email", text: $email, prompt: Text("Enter your email"))
                    .focused($isEmailFocused)
                SecureField("Password", text: $password, prompt: Text("Enter your password"))
                    .focused($isPasswordFocused)
            }
            .navigationTitle("Sign In")
        }
    }
}

@FocusState 特点包装器的优点之一是您能够将其行为限制为专用辅佐技能。例如,您能够仅为VoiceOver或Switch Control激活 @FocusState 特点包装器。默许情况下,SwiftUI 会将设备上可用的一切辅佐技能的值进行聚合。

可聚集字段的高档用法

中心代码如下:

import SwiftUI
struct SignInView: View {
    @FocusState(for: .switchControl)
    private var isEmailFocused: Bool
    @State private var email = ""
    var body: some View {
        NavigationView {
            Form {
                TextField("Email", text: $email, prompt: Text("Enter your email"))
                    .focused($isEmailFocused)
            }
            .navigationTitle("Sign In")
            .onChange(of: isEmailFocused) { newValue in
                print(newValue)
            }
        }
    }
}

如上例所示,咱们运用 @FocusState 特点包装器为 Switch Control 界说了可选变量 isEmailFocused,以便在用户在视图之间移动焦点时进行切换。

通常,屏幕上有多个元素,您或许期望在它们之间移动焦点。为了支撑这种情况,SwiftUI 提供了一种经过枚举界说可聚集字段并在它们之间切换的办法。这种办法是运用 @FocusState 特点包装器,并为其提供一个用于标识焦点类型的参数(在此例中是 .switchControl)。

优化体验

全部代码如下:

import SwiftUI
enum FocusableField: Hashable {
    case email
    case password
}
struct ContentView: View {
    @State private var email = ""
    @State private var password = ""
    @FocusState
    private var focus: FocusableField?
    var body: some View {
        NavigationView {
            Form {
                TextField("email", text: $email, prompt: Text("email"))
                    .focused($focus, equals: .email)
                SecureField("password", text: $password, prompt: Text("password"))
                    .focused($focus, equals: .password)
                Button("login", action: login)
            }
            .toolbar {
                ToolbarItem(placement: .keyboard) {
                    Button("next") {
                        if email.isEmpty {
                            focus = .email
                        } else if password.isEmpty {
                            focus = .password
                        } else {
                            focus = nil
                        }
                    }
                }
            }
            .navigationTitle("Sign in")
            .onAppear {
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                    focus = .email
                }
            }
        }
    }
    private func login() {
        // your logic here
    }
}

运行截图

SwiftUI Release 引进的辅佐焦点办理

如上例所示,咱们运用了 @FocusState 特点包装器与咱们的新 FocusableField 枚举一同运用。该枚举界说了屏幕上一切可聚集视图,应确保 FocusableField 枚举是可散列的。

运用 @FocusState 特点包装器界说了可选变量 focus,以便在用户将焦点从您界说的视图移动时将其值设置为 nil

咱们还运用了 focused 修饰符的一个版别,将一个视图绑定到可散列枚举的特定情况。请记住,您能够经过更改 @FocusState 包装的变量的值来以编程方式移动 VoiceOver 或 Switch Control 的焦点。

总结

在这篇文章中,咱们深化探讨了 SwiftUI Release 引进的辅佐焦点办理功用,使得处理辅佐技能(如 VoiceOver 和 Switch Control)的焦点状况变得更加轻松。经过 @FocusState 特点包装器,咱们学习了怎么灵活地办理焦点状况,以进步用户体验。经过具体的示例代码,咱们演示了怎么在 SwiftUI 中运用 @FocusState,以及怎么经过 focused 视图修饰符将焦点状况绑定到特定的视图。此外,咱们介绍了一种高档用法,经过枚举界说可聚集字段并在它们之间切换,以更好地支撑屏幕上多个元素的焦点移动。最终,咱们提供了一些优化 SwiftUI 应用的建议,以更好地整合焦点办理,并经过最佳实践和总结使读者更深化地了解了在 SwiftUI Release 中运用 @FocusState 办理焦点的办法。