Support Full Keyboard Access in your iOS app
Accessibility 进阶 20m

在你的 iOS App 中支持全键盘访问

Support Full Keyboard Access in your iOS app

2021年6月11日

在 Apple 官方观看视频

一句话判断

iOS 15 正式支持 Full Keyboard Access(全键盘操作)—— iPad 键盘用户可以不用触摸屏就完成所有操作,这对 motor impairment 用户是刚需,对效率型用户是加分项,但你需要在代码中正确处理焦点(Focus)和键盘快捷键。

这场 Session 讲了什么

iOS 15 引入了 Full Keyboard Access 模式,用户可以通过外接键盘(Smart Keyboard、Magic Keyboard、第三方蓝牙键盘)完全控制 iPad 和 iPhone,不需要触摸屏幕。

Session 讲解了:

  1. 焦点系统(Focus System):键盘焦点(Keyboard Focus)和 VoiceOver 焦点是两套独立的系统。Tab 键移动键盘焦点,VoiceOver 的手势移动 VoiceOver 焦点。
  2. 焦点环(Focus Ring):获得焦点的控件会显示蓝色的焦点环,系统自动管理大部分 UIKit 控件的焦点行为。
  3. 自定义焦点顺序:默认按从左到右、从上到下的顺序,但可以通过 shouldUpdateFocusdidUpdateFocus 自定义。
  4. 键盘快捷键(Key Commands)UIKeyCommand 让你添加自定义快捷键(如 Cmd+N 新建、Cmd+S 保存)。

值得深挖的点

键盘焦点 vs VoiceOver 焦点的区别。这是最容易混淆的部分。键盘焦点由 Tab/Shift+Tab 移动,只响应键盘事件。VoiceOver 焦点由 VoiceOver 手势控制(左右滑动)。两者可以同时指向不同元素。当 VoiceOver 开启时,键盘焦点跟随 VoiceOver 焦点;VoiceOver 关闭时,只有键盘焦点。你的 app 需要正确处理这两种焦点状态的 UI 反馈。

SwiftUI 的焦点管理。SwiftUI 在 iOS 15 中新增了 @FocusState 属性包装器,可以编程控制焦点。配合 focused(_:) 修饰符,你可以指定哪个元素获得焦点,也可以响应焦点变更。这对表单场景特别有用 —— 按 Tab 键在输入框之间移动、提交后自动聚焦到下一个字段。

代码片段

SwiftUI 的焦点管理

import SwiftUI

struct LoginFormView: View {
    @State private var username = ""
    @State private var password = ""
    // 控制焦点位置
    @FocusState private var focusedField: Field?

    enum Field: Hashable {
        case username, password, submitButton
    }

    var body: some View {
        Form {
            TextField("用户名", text: $username)
                .focused($focusedField, equals: .username)
                .onSubmit {
                    // 按 Enter 跳转到密码框
                    focusedField = .password
                }

            SecureField("密码", text: $password)
                .focused($focusedField, equals: .password)
                .onSubmit {
                    // 按 Enter 提交
                    focusedField = .submitButton
                    performLogin()
                }

            Button("登录") {
                performLogin()
            }
            .focused($focusedField, equals: .submitButton)
        }
        // 页面出现时自动聚焦到用户名
        .onAppear {
            focusedField = .username
        }
    }
}

UIKit 中自定义焦点行为

import UIKit

class FormViewController: UIViewController {
    var usernameField: UITextField!
    var passwordField: UITextField!
    var loginButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        setupKeyCommands()
    }

    // 添加键盘快捷键
    override var keyCommands: [UIKeyCommand]? {
        return [
            UIKeyCommand(
                input: "\r",  // Enter 键
                modifierFlags: .command,
                action: #selector(handleLoginShortcut),
                title: "登录"
            ),
            UIKeyCommand(
                input: "n",
                modifierFlags: [.command, .shift],
                action: #selector(handleNewAccountShortcut),
                title: "创建新账号"
            )
        ]
    }

    // 自定义焦点移动顺序
    override func shouldUpdateFocus(in context: UIFocusUpdateContext) -> Bool {
        // 不允许焦点回到已禁用的控件
        if context.nextFocusedView == loginButton, !loginButton.isEnabled {
            return false
        }
        return true
    }

    @objc func handleLoginShortcut() {
        performLogin()
    }

    @objc func handleNewAccountShortcut() {
        showRegistrationFlow()
    }
}

全局键盘快捷键

import SwiftUI

struct ContentView: View {
    @State private var showSearch = false

    var body: some View {
        NavigationView {
            List {
                // 内容...
            }
            .searchable(text: .constant(""), isPresented: $showSearch)
            // Cmd+F 打开搜索
            .keyboardShortcut("f", modifiers: .command)
        }
        .onKeyPress(.returnKeyPress) {
            print("Enter 被按下")
            return .handled
        }
    }
}

最佳实践

  1. 所有可交互控件都要能通过键盘访问。自定义视图(如卡片式 UI)需要手动添加 isAccessibilityElementcanBecomeFocused 支持。
  2. 焦点环不要隐藏。有些设计师觉得蓝色焦点环不好看,要求去掉。这是无障碍的硬性需求,不能为了美观牺牲可用性。
  3. 添加 Cmd+, 快捷键打开设置Cmd+W 关闭面板、Cmd+N 新建。遵循 macOS 的键盘快捷键惯例,iPad 用户已经有这些肌肉记忆。

还有什么值得关注

  • iOS 15 的 Full Keyboard Access 支持 Tab 导航、Space 激活、Esc 取消等标准键盘操作。
  • UIFocusSystem 在 UIKit 中提供了完整的焦点查询和编程控制 API。
  • 键盘快捷键会在 Menu Bar(iPadOS 15 新增)中自动展示。
WWDC 2021