Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
What’s New in Accessibility WWDC21
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Jierong Li
June 28, 2021
Programming
360
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
What’s New in Accessibility WWDC21
Jierong Li
June 28, 2021
More Decks by Jierong Li
See All by Jierong Li
一般的な通信でも使える バックグラウンドURLSessionの活用方法 / How to use background URLSession for general network data transfer tasks.
myihsan
0
3.1k
Multi-Module 101
myihsan
0
370
Hierarchical Structure について / About Hierarchical Structure
myihsan
1
540
Property WrapperでDecodableのデフォルト値を設定 / Providing Default Value for Decodable Property by Property Wrapper
myihsan
1
380
モックフレームワーク比較 / Mocking Framework Comparison
myihsan
0
570
Other Decks in Programming
See All in Programming
数年滞っていたダークモード対応をおよそ2週間で完了させる
chigichan24
0
700
PHPプロジェクトの結合バランスを可視化する #php_night
kajitack
0
230
ゲームコントローラやキーボードのファームウェアをSwiftで書く
kishikawakatsumi
1
180
Seeing Through Serverless: Observability for AWS Lambda with ADOT and CloudWatch Application Signals
seike460
PRO
1
130
デプロイ直後のレイテンシスパイクを調べたら、 Railsの仕様にたどり着いた
nhsykym
0
110
[GoCon2026] When Goroutines Are Not Enough: Runtime Locality in High-Throughput Go
takehaya
6
1.9k
世界の中心で、AI(App Intents)をさけぶ ー App Intents中心設計の実践ガイド
touyou
0
390
AIエージェント時代のコードレビューを設計する
nogu66
6
2.6k
Can LLMs Replicate 4 Years of Compose Migration? Exploring the boundaries of automation with 279 XML files from a real product
makun
0
130
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
3
1.2k
Laravelのアプリケーションをどこにデプロイするか #ツナギメオフライン.9
akase244
0
120
iOS開発×AI駆動開発 〜最近使って便利だったスキルの話〜
nogu66
0
140
Featured
See All Featured
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
660
The agentic SEO stack - context over prompts
schlessera
0
920
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
280
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
540
The Invisible Side of Design
smashingmag
301
52k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
Accessibility Awareness
sabderemane
1
210
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
820
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.6k
Music & Morning Musume
bryan
47
7.4k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
67k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
270
Transcript
WHAT’S NEW IN ACCESSIBILITY YUMEMI.SWIFT #12 FEAT. HAKATA.SWIFT 〜WWDC RECAP~
⾃⼰紹介 JIERONG LI (李) ▸ 株式会社ゆめみ ▸ iOSエンジニア ▸ KMMでAndroid開発キャッチアップ
▸ 永遠にリリースできず個⼈開発 ▸ https://jierong.dev
COVERED SESSIONS ▸ SwiftUI Accessibility: Beyond the basics ▸ Bring
accessibility to charts in your app
PREVIEW WITHOUT RUNNING APP
CUSTOM VIEW IMPLEMENTATION SegmentedControl( selectedSegmentIndex: $selectedSegmentIndex ) { HStack {
Image(systemName: "tray.full") Text("Inbox") Spacer() Text("\(tasks.count)") } HStack { Image(systemName: "archivebox") Text("Done") } }
CUSTOM VIEW ACCESSIBILITY PREVIEW ▸ Inbox Icon ▸ Label: Inbox
Full ▸ Traits: .isImage ▸ Inbox Text ▸ Label: Inbox ▸ Traits: .isStaticText ▸ Count ▸ Label: 5 ▸ Traits: .isStaticText ▸ Done Icon ▸ Label: Archive ▸ Traits: .isImage ▸ Done Text ▸ Label: Done ▸ Traits: .isStaticText
CUSTOM VIEW EXPECTED ▸ Inbox ▸ Label: Inbox 5 ▸
Traits: .isButton .isSelected ▸ Done ▸ Label: Done ▸ Traits: .isButton
CUSTOM VIEW BELOW IOS 15 SegmentedControl( selectedSegmentIndex: $selectedSegmentIndex ) {
HStack { Image(systemName: "tray.full") Text("Inbox") Spacer() Text("\(tasks.count)") } ... }
CUSTOM VIEW BELOW IOS 15 SegmentedControl( selectedSegmentIndex: $selectedSegmentIndex ) {
HStack { Image(systemName: "tray.full") Text("Inbox") Spacer() Text("\(tasks.count)") } .accessibilityElement(children: .ignore) ... }
CUSTOM VIEW BELOW IOS 15 SegmentedControl( selectedSegmentIndex: $selectedSegmentIndex ) {
HStack { Image(systemName: "tray.full") Text("Inbox") Spacer() Text("\(tasks.count)") } .accessibilityElement(children: .ignore) .accessibility(label: Text(“\(tasks.count)”)) ... }
CUSTOM VIEW BELOW IOS 15 SegmentedControl( selectedSegmentIndex: $selectedSegmentIndex ) {
HStack { Image(systemName: "tray.full") Text("Inbox") Spacer() Text("\(tasks.count)") } .accessibilityElement(children: .ignore) .accessibility(label: Text(“\(tasks.count)”)) .accessibility(addTraits: selectedSegmentIndex == 0 ? [.isButton, .isSelected] : [.isButton] ) ... }
CUSTOM VIEW IOS 15 AND ABOVE SegmentedControl( selectedSegmentIndex: $selectedSegmentIndex )
{ HStack { Image(systemName: "tray.full") Text("Inbox") Spacer() Text("\(tasks.count)") } HStack { Image(systemName: "archivebox") Text("Done") } }
CUSTOM VIEW IOS 15 AND ABOVE SegmentedControl( selectedSegmentIndex: $selectedSegmentIndex )
{ HStack { Image(systemName: "tray.full") Text("Inbox") Spacer() Text("\(tasks.count)") } HStack { Image(systemName: "archivebox") Text("Done") } } .accessibilityRepresentation { Picker("", selection: $selectedSegmentIndex) { Text("Inbox \(tasks.count)").tag(0) Text("Done").tag(1) } .pickerStyle(.segmented) }
EXTERNAL VIEW (CHARTVIEW) BELOW IOS 15 BarChart() .data(dataSet.map(\.value)) .chartStyle(chartStyle) 🤷
EXTERNAL VIEW (CHARTVIEW) IOS 15 AND ABOVE BarChart() .data(dataSet.map(\.value)) .chartStyle(chartStyle)
EXTERNAL VIEW (CHARTVIEW) IOS 15 AND ABOVE BarChart() .data(dataSet.map(\.value)) .chartStyle(chartStyle)
.accessibilityChildren { HStack { ForEach(dataSet) { data in Rectangle() .accessibilityLabel(data.label) .accessibilityValue("\(data.value)") } } }
ROTOR BELOW IOS 15 UIKit Only
ROTOR IOS 15 AND ABOVE VStack { ForEach(lines) { line
in Text(line.content) } } .accessibilityRotor("Titles") { ForEach(lines) { line in if line.isTitle { AccessibilityRotorEntry( line.content, id: line.id ) } } }
ROTOR IOS 15 AND ABOVE VStack { ForEach(lines) { line
in Text(line.content) } } .accessibilityRotor(.headings) { ForEach(lines) { line in if line.isTitle { AccessibilityRotorEntry( line.content, id: line.id ) } } }
CONTROL FOCUS @ACCESSIBILITYFOCUSSTATE @AccessibilityFocusState var isFocused: Bool
CONTROL FOCUS @ACCESSIBILITYFOCUSSTATE struct NotificationBanner: View { @Binding var notification:
Notification? @State var timer: Timer? @AccessibilityFocusState var isNotificationFocused: Bool var body: some View { content .accessibilityFocused(isNotificationFocused) } func startTimer() { timer = Timer.scheduledTimer( withTimeInterval: 3, repeats: true) { _ in if !isNotificationFocused { notification = nil } } } }
AUDIO GRAPH AXCHART protocol AXChart: NSObjectProtocol { var accessibilityChartDescriptor: AXChartDescriptor?
{ get set } }
AUDIO GRAPH AXCHART protocol AXChart: NSObjectProtocol { var accessibilityChartDescriptor: AXChartDescriptor?
{ get set } } class AXChartDescription: NSObject { convenience init( title: String? = nil, summary: String? = nil, xAxis: AXDataAxisDescriptor, yAxis: AXNumericDataAxisDescriptor? = nil, additionalAxes: [AXDataAxisDescriptor] = [], series: [AXDataSeriesDescriptor] ) ... }
ご清聴ありがとうございました