View in English

  • Apple 开发者
    • 入门汇总

    探索“入门汇总”

    • 概览
    • 学习
    • Apple Developer Program

    及时了解最新动态

    • 最新动态
    • 开发者你好
    • 平台

    探索“平台”

    • Apple 平台
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    • App Store

    精选

    • 设计
    • 分发
    • 游戏
    • 配件
    • 网页
    • Home
    • CarPlay 车载
    • 技术

    探索“技术”

    • 概览
    • Xcode
    • Swift
    • SwiftUI

    精选

    • 辅助功能
    • App Intents
    • Apple 智能
    • 游戏
    • 机器学习与 AI
    • 安全性
    • Xcode Cloud
    • 社区

    探索“社区”

    • 概览
    • “与 Apple 会面交流”活动
    • 社区主导的活动
    • 开发者论坛
    • 开源

    精选

    • WWDC
    • Swift Student Challenge
    • 开发者故事
    • App Store 大奖
    • Apple 设计大奖
    • Apple Developer Centers
    • 文档

    探索“文档”

    • 文档库
    • 技术概述
    • 示例代码
    • 《人机界面指南》
    • 视频

    发布说明

    • 精选更新
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • Apple tvOS
    • Xcode
    • 下载

    探索“下载”

    • 所有下载
    • 操作系统
    • 应用程序
    • 设计资源

    精选

    • Xcode
    • TestFlight
    • 字体
    • SF Symbols
    • Icon Composer
    • 支持

    探索“支持”

    • 概览
    • 帮助指南
    • 开发者论坛
    • “反馈助理”
    • 联系我们

    精选

    • 《开发者账户帮助》
    • 《App 审核指南》
    • 《App Store Connect 帮助》
    • 即将实行的要求
    • 协议和准则
    • 系统状态
  • 快速链接

    • 活动
    • 新闻
    • 论坛
    • 示例代码
    • 视频
 

视频

打开菜单 关闭菜单
  • 专题
  • 所有视频
  • 关于

更多视频

  • 简介
  • 概要
  • 代码
  • 提升阅读 App 的辅助功能体验

    了解如何为旁白、朗读屏幕等功能打造出色的阅读体验。探索如何实现直观的文本选择、清晰的行段导航,以及连贯的跨元素和跨页阅读体验。

    章节

    • 0:01 - Introduction
    • 1:26 - Characteristics
    • 3:45 - Standard views
    • 14:05 - Custom text

    资源

    • accessibilityNextTextNavigationElement
    • editCategory
    • accessibilityLinkedGroup(id:in:)
    • causesPageTurn
    • UITextInput
    • Accessibility for UIKit
      • 高清视频
      • 标清视频

    相关视频

    WWDC19

    • 打造辅助阅读体验
  • 搜索此视频…
    • 7:29 - Link text elements together with navigation APIs

      // Link text elements together with navigation APIs
      
      import UIKit
      
      class TravelGuidePageController: UIViewController {
      
          var paragraphs: [TravelGuideParagraph]
      
          func configureNavigationElements() {
              for (index, paragraph) in paragraphs.enumerated() {
                  if index + 1 < paragraphs.count {
                      paragraph.accessibilityNextTextNavigationElement = paragraphs[index + 1]
                  }
                  if index - 1 >= 0 {
                      paragraph.accessibilityPreviousTextNavigationElement = paragraphs[index - 1]
                  }
              }
          }
      }
    • 7:59 - Link text elements together with a linked group

      // Link text elements together with a linked group
      
      import SwiftUI
      
      struct PageView : View {
          @Namespace private var pageNamespace
          var paragraphs: [String
          var pageNumber: Int
      
          var body: some View {
              Text(paragraphs[0])
                  .textSelection(.enabled)
                  .accessibilityLinkedGroup(id: pageNumber, in: pageNamespace)
      
              Text(paragraphs[1])
                  .textSelection(.enabled)
                  .accessibilityLinkedGroup(id: pageNumber, in: pageNamespace)
          }
      }
    • 9:50 - Turn pages automatically after reading

      // Turn pages automatically after reading
      
      import UIKit
      
      class TravelGuidePageController: UIViewController {
      
          override func viewDidLoad() {
              super.viewDidLoad()
              self.lastParagraphView.accessibilityTraits.insert(.causesPageTurn)
          }
      
          override func accessibilityScroll(_ direction: UIAccessibilityScrollDirection) -> Bool {
              moveToPage(direction)
              var scrollString = "Page \(currentPage) of \(pages.count)"
              UIAccessibility.post(notification: .pageScrolled, argument: scrollString)
              return true
          }
      }
    • 11:45 - Add actions to the editor rotor

      // Add actions to the editor rotor
      
      import UIKit
      
      class TravelGuideParagraph: UITextView {
      
          override var accessibilityCustomActions: [UIAccessibilityCustomAction]? {
              get {
                  let saveAction = UIAccessibilityCustomAction(name: "Save Recommendation") { _ in
                      self.saveRecommendation()
                  }
                  saveAction.category = UIAccessibilityCustomAction.editCategory
                  return (super.accessibilityCustomActions ?? []) + [saveAction]
              }
              set { }
          }
      
          private func saveRecommendation() -> Bool {
              ...
              return true
          }
      }
    • 16:10 - Adopt UITextInput

      // Adopt UITextInput
      
      import UIKit
      
      class ScannedPage: UIView, UITextInput {
      
          override init(frame: CGRect) {
              super.init(frame: frame)
              let interaction = UITextInteraction(for: .nonEditable)
              interaction.textInput = self
              addInteraction(interaction)
          }
         
          func selectionRects(for range: UITextRange) -> [UITextSelectionRect] {
              var rects: [UITextSelectionRect] = []
      
              let startLine = lineIndex(for: range.start)
              let endLine = lineIndex(for: range.end)
      
              for line in startLine...endLine {
                  let rect = selectionRectFromImage(for: range, in: line)
                  rects.append(rect)
              }
      
              return rects
          }
        
          func text(in range: UITextRange) -> String? {
              let nsRange = nsRange(from: range)
              guard let range = Range(nsRange, in: scannedText) else {
                  return nil
              }
              return String(scannedText[range])
          }
      
          var tokenizer: any UITextInputTokenizer { CustomHandwritingTokenizer(textInput: self) }
      
          weak var inputDelegate: UITextInputDelegate?
        
            var selectedTextRange: UITextRange? {
              // Update visuals when assistive technologies change selection
              willSet { inputDelegate?.selectionWillChange(self) }
              didSet { inputDelegate?.selectionDidChange(self) }
          }
        
      }
    • 0:01 - Introduction
    • What makes reading apps an accessibility challenge distinct from UI navigation, and what the session covers — the characteristics of a great reading experience, extending UIKit and SwiftUI text views, and making custom text accessible.

    • 1:26 - Characteristics
    • Reading apps present unique accessibility challenges distinct from standard UI navigation, requiring fluid movement through text for technologies like VoiceOver and Speak Screen. This session covers three goals — granular navigation, continuous reading, and text selection — using UIKit, SwiftUI, and AppKit APIs.

    • 3:45 - Standard views
    • UITextView, SwiftUI's TextEditor and selectable Text, and NSTextView on macOS all adopt UITextInput automatically, providing line, word, and character navigation and accessible text selection. The accessibilityNextTextNavigationElement and accessibilityPreviousTextNavigationElement APIs (and the new accessibilityLinkedGroup for SwiftUI) connect separate text elements so VoiceOver can move between them seamlessly, while the causesPageTurn trait provides page turning automatically during read-all gestures.

    • 14:05 - Custom text
    • When using custom or custom-rendered text — such as scanned images — adopting the full UITextInput protocol gives VoiceOver and Speak Screen the same granular navigation and selection capabilities as native text views. This requires implementing text geometry methods like selectionRects(for:), a tokenizer, and text range methods, and can be paired with UITextInteraction for visible selection handles.

Developer Footer

  • 视频
  • WWDC26
  • 提升阅读 App 的辅助功能体验
  • 打开菜单 关闭菜单
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    打开菜单 关闭菜单
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    打开菜单 关闭菜单
    • 辅助功能
    • 配件
    • Apple 智能
    • App 扩展
    • App Store
    • 音频与视频 (英文)
    • 增强现实
    • 设计
    • 分发
    • 教育
    • 字体 (英文)
    • 游戏
    • 健康与健身
    • App 内购买项目
    • 本地化
    • 地图与位置
    • 机器学习与 AI
    • 开源资源 (英文)
    • 安全性
    • Safari 浏览器与网页 (英文)
    打开菜单 关闭菜单
    • 完整文档 (英文)
    • 部分主题文档 (简体中文)
    • 教程
    • 下载
    • 论坛 (英文)
    • 视频
    打开菜单 关闭菜单
    • 支持文档
    • 联系我们
    • 错误报告
    • 系统状态 (英文)
    打开菜单 关闭菜单
    • Apple 开发者
    • App Store Connect
    • 证书、标识符和描述文件 (英文)
    • 反馈助理
    打开菜单 关闭菜单
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program (英文)
    • Mini Apps Partner Program
    • News Partner Program (英文)
    • Video Partner Program (英文)
    • 安全赏金计划 (英文)
    • Security Research Device Program (英文)
    打开菜单 关闭菜单
    • 与 Apple 会面交流
    • Apple Developer Center
    • App Store 大奖 (英文)
    • Apple 设计大奖
    • Apple Developer Academies (英文)
    • WWDC
    阅读最近新闻。
    获取 Apple Developer App。
    版权所有 © 2026 Apple Inc. 保留所有权利。
    使用条款 隐私政策 协议和准则