WWDC Quick Look 💓 By SwiftGGTeam
Customize your app for Assistive Access

Customize your app for Assistive Access

观看原视频

Highlight

Assistive Access 是 Apple 在 iOS/iPadOS 17 中为认知障碍用户设计的精简系统体验,特点是大控件、简化流程、视觉化的信息呈现。此前,未优化的应用会以缩小的框架显示(为底部的返回按钮留出空间)。iOS 26 引入了 AssistiveAccess SwiftUI scene,让你可以为这个模式提供一个完全定制的界面。


核心内容

一个有认知障碍的用户打开你的画图 app,屏幕上塞着画笔、橡皮、撤销、画廊、收藏、调色盘、不透明度滑块。每多一个选项就多一份认知负担。在 iOS 17 推出 Assistive Access 之后,没有适配的 app 还会被压缩成一个更小的框,下方留出全局返回按钮的位置——视觉上更挤,体验上更糟。

iOS/iPadOS 26 引入了 AssistiveAccess SwiftUI scene,让你为这个模式单独提供一个界面。这个 scene 激活时,原生的 ButtonListNavigationLinknavigationTitle 会自动以 Assistive Access 的大号醒目样式渲染,并按用户在系统设置中选择的网格或行布局排列;底部的返回按钮负责回退导航栈,无需额外代码(09:00)。如果 app 本身就是为认知障碍用户设计的(如 AAC 辅助沟通 app),只需把 UISupportsFullScreenInAssistiveAccess 设为 true,即可在全屏中保留原界面;其他 app 则建议采用新的 scene 路径,把功能精简到核心。


详细内容

接入 Assistive Access scene 的第一步:在 Info.plist 中把 UISupportsAssistiveAccess 设为 true,让 app 出现在系统设置的 Optimized Apps 列表里,并以全屏而非缩框启动(04:54)。然后在 App 主体中追加一个 AssistiveAccess scene:

// Create a scene for Assistive Access

import SwiftUI
import SwiftData

@main
struct WWDCDrawApp: App {
  var body: some Scene {
    WindowGroup {
      ContentView()
        .modelContainer(for: [DrawingModel.self])
    }
    AssistiveAccess {
      AssistiveAccessContentView()
          .modelContainer(for: [DrawingModel.self])
    }
  }
}

关键点:

  • WindowGroup 是常规模式下的入口;AssistiveAccess { ... } 是新增的并列 scene,仅在 Assistive Access 激活时被创建并附加(05:55)。
  • 两个 scene 都挂上 modelContainer,让 SwiftData 模型在两种模式下都可用。
  • AssistiveAccessContentView 是你为这个模式专门设计的根视图,里面只放最核心的 1-2 个功能。

预览这个 scene 不需要装到设备上,只要给 #Preview.assistiveAccess trait(06:25):

// Display an Assistive Access preview

import SwiftUI

struct AssistiveAccessContentView: View {
  @Environment(\.modelContext) var context
  var body: some View {
    VStack {
      Image(systemName: "globe")
        .imageScale(.large)
        .foregroundStyle(.tint)
      Text("Hello, world!")
    }
    .padding()
  }
}

#Preview(traits: .assistiveAccess)
    AssistiveAccessContentView()
}

关键点:

  • traits: .assistiveAccess 告诉 Xcode Preview 把视图渲染成 scene 激活时的样式,省去反复进入 Assistive Access 模式调试的麻烦。

UIKit-lifecycle 的 app 也能宿主这个 SwiftUI scene。在 scene delegate 类的静态 rootScene 属性里声明它(06:35):

// Declare a SwiftUI scene with UIKit

import UIKit
import SwiftUI

class AssistiveAccessSceneDelegate: UIHostingSceneDelegate {

  static var rootScene: some Scene {
    AssistiveAccess {
      AssistiveAccessContentView()
    }
  }

    /* ... */
}

关键点:

  • UIHostingSceneDelegate 是 iOS 26 新增的 scene 桥接协议,让 UIKit app 可以托管 SwiftUI scene。
  • rootScene 必须是静态属性,返回 some Scene

接下来在 AppDelegate 中根据 scene 角色挂上这个 delegate(06:55):

// Activate a SwiftUI scene with UIKit

import UIKit

@main
class AppDelegate: UIApplicationDelegate {
  func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
    let role = connectingSceneSession.role
    let sceneConfiguration = UISceneConfiguration(name: nil, sessionRole: role)
    if role == .windowAssistiveAccessApplication {
      sceneConfiguration.delegateClass = AssistiveAccessSceneDelegate.self
    }
    return sceneConfiguration
  }
}

关键点:

  • 当系统在 Assistive Access 中启动 app 时,role 会是 .windowAssistiveAccessApplication
  • 仅在这种角色下替换 delegateClass,常规模式仍走原 delegate,互不干扰。

视觉层面,认知障碍用户对图标的理解优于纯文字,所以导航标题也要带上图标。assistiveAccessNavigationIcon(systemImage:) 会在 scene 激活时把图标显示到导航栏里(14:36):

// Display an icon alongside a navigation title

import SwiftUI

struct ColorSelectionView: View {
  var body: some View {
    Group {
      List {
        ForEach(ColorMode.allCases) { color in
          NavigationLink(destination: DrawingView(color: color)) {
            ColorThumbnail(color: color)
          }
        }
      }
      .navigationTitle("Draw")
      .assistiveAccessNavigationIcon(systemImage: "hand.draw.fill")
    }
  }
}

关键点:

  • assistiveAccessNavigationIcon 修饰符只在 Assistive Access scene 中生效,常规模式不受影响。
  • 也支持传入自定义 Image 而非 SF Symbol 名称。
  • 建议每个有 navigationTitle 的页面都配一个图标。

设计原则方面,session 给出了五条具体建议(09:39 起):精简到 1-2 个核心功能;减少同屏选项数量;避免隐藏手势和嵌套 UI;不使用计时交互(自动消失或自动切换的视图);构建分步选择流程,把决策拆开做。讲者以画图 app 为例,把”选颜色”从画布内的选项改成进入画布前的独立步骤——决策分离,认知负荷降低(13:01)。同时移除了”撤销笔画”和”删除画作”这类难以恢复的操作,对必须保留的破坏性操作要求二次确认(11:33)。


核心启发

  • 为现有 app 加一个 AssistiveAccess scene:为什么值得做——相比把整个 app 直接全屏化,scene 路径让原生控件自动获得 Assistive Access 的大号样式和网格/行布局,几乎零成本拿到一致的视觉风格。怎么开始——在 Info.plist 加 UISupportsAssistiveAccess,在 App 主体并列声明 AssistiveAccess { ... } scene,里面写一个只有 1-2 个核心功能的根视图。

  • #Preview(traits: .assistiveAccess) 加速调试:为什么值得做——在 Xcode 里直接预览 scene 激活时的样式,省掉反复打开系统设置切换模式的时间。怎么开始——给每个 Assistive Access 视图加一条 #Preview(traits: .assistiveAccess) { MyView() },跟普通 SwiftUI 预览一样使用。

  • 把”多选项并列”改写成”分步引导”:为什么值得做——同屏选项越少,决策越容易完成;分步流程让每一步只承担一个决策,认知负荷线性下降。怎么开始——盘点当前页面有几个独立决策(颜色、笔刷、画布尺寸……),把它们拆成前置的若干个独立页面,每页只问一件事,进入主功能前已完成所有选择。

  • 给所有 navigationTitle 配图标:为什么值得做——图文双通道对认知障碍用户更易理解,且不影响常规模式视觉。怎么开始——在每个有 navigationTitle 的视图后追加 .assistiveAccessNavigationIcon(systemImage: "..."),挑选与功能强相关的 SF Symbol。

  • 审视 app 中的破坏性操作:为什么值得做——误删、误改在认知障碍场景下后果更重。怎么开始——列出 app 内所有不可逆操作(删除、清空、提交订单),在 Assistive Access scene 中考虑直接移除非必要项;保留的操作加二次确认弹窗。


关联 Session

评论

GitHub Issues · utterances