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
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
380
Hierarchical Structure について / About Hierarchical Structure
myihsan
1
540
Property WrapperでDecodableのデフォルト値を設定 / Providing Default Value for Decodable Property by Property Wrapper
myihsan
1
390
モックフレームワーク比較 / Mocking Framework Comparison
myihsan
0
570
Other Decks in Programming
See All in Programming
phperだってパンチカードでコーディングしたい
o0h
PRO
0
310
Event is what happens
moro
2
400
技術的負債の返済は、AI時代の複利で効く投資 — 経営としての意思決定とその遂行
curekoshimizu
1
2.3k
AIに “答え“を書かせるのを やめてみた
___akari11
0
120
mrbgem 三角測量 開発
ogom
0
240
When benchmarks go bad - what I learned from measuring performance wrong
hollycummins
0
210
Agentic Software Factoryに、すごく賢いIF文を。 / super smart IF statement into the Agentic Software Factory.
rkaga
8
2.1k
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.6k
PumaからFalconに移行したRailsアプリケーションでの実践
falcon8823
0
100
Optunaを作ったときにやりたかったこと、その後 (2026/10/16, Optuna Meetup #3)
iwiwi
1
180
UnityでSystem.Net.WebSocketsなWebSocketサーバが動かないのでUnity Monoのコードを覗いてみた / about implementing websocket server with unity mono
drumath2237
1
590
Everything will be SERVERLESS — 信じて運用した10年の経験値 / Everything Will be Serverless — Lessons Learned from 10 Years of Operational Experience
seike460
PRO
1
1k
Featured
See All Featured
How to build a perfect <img>
jonoalderson
1
6.1k
Exploring anti-patterns in Rails
aemeredith
4
540
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
280
Rails Girls Zürich Keynote
gr2m
96
14k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
270
Building Flexible Design Systems
yeseniaperezcruz
330
41k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Discover your Explorer Soul
emna__ayadi
2
1.3k
Designing Powerful Visuals for Engaging Learning
tmiket
1
600
The Language of Interfaces
destraynor
162
27k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
850
[RailsConf 2023] Rails as a piece of cake
palkan
59
7.1k
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] ) ... }
ご清聴ありがとうございました