Skip to content

Commit 0b3bf32

Browse files
authored
Merge pull request #450 from wanteddev/feature/PI-82408
[PI-82408] ์ „์ฒด ์ปดํฌ๋„ŒํŠธ์— VoiceOver ์ ‘๊ทผ์„ฑ ์ง€์› ์ถ”๊ฐ€
2 parents e385702 + e561d68 commit 0b3bf32

23 files changed

Lines changed: 164 additions & 11 deletions

โ€ŽPackage.swiftโ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import PackageDescription
44

55
let package = Package(
66
name: "Montage",
7+
defaultLocalization: "ko",
78
platforms: [.iOS(.v16)],
89
products: [
910
.library(name: "Montage", targets: ["Montage"])

โ€ŽSources/Montage/1 Components/2 Actions/Button.swiftโ€Ž

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ public struct Button: View {
166166
private var loading = false
167167
private var fillHorizontal = false
168168
private var fillVertical = false
169-
170169
/// ๋ฒ„ํŠผ์„ ๋น„ํ™œ์„ฑํ™” ์ƒํƒœ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
171170
///
172171
/// ๋น„ํ™œ์„ฑํ™”๋œ ๋ฒ„ํŠผ์€ ์‹œ๊ฐ์ ์œผ๋กœ ํ๋ฆฌ๊ฒŒ ํ‘œ์‹œ๋˜๋ฉฐ ์‚ฌ์šฉ์ž ์ƒํ˜ธ์ž‘์šฉ์— ๋ฐ˜์‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
@@ -366,6 +365,10 @@ public struct Button: View {
366365
}
367366
.modifier(PressActionDetectingModifier(isPressed: $isPressed, action: handler))
368367
.allowsHitTesting(!disable && !loading)
368+
.accessibilityElement(children: .ignore)
369+
.accessibilityLabel(text ?? leadingIcon?.rawValue ?? "")
370+
.accessibilityAddTraits(.isButton)
371+
.accessibilityValue(loading ? String(localized: "๋กœ๋”ฉ ์ค‘", bundle: .module) : "")
369372
}
370373
}
371374

โ€ŽSources/Montage/1 Components/2 Actions/Chip.swiftโ€Ž

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ public struct Chip: View {
125125
)
126126
.modifier(PressActionDetectingModifier(isPressed: $isPressed, action: handler))
127127
.disabled(disable)
128+
.accessibilityElement(children: .ignore)
129+
.accessibilityLabel(text)
130+
.accessibilityAddTraits(.isButton)
131+
.accessibilityValue(active ? String(localized: "์„ ํƒ๋จ", bundle: .module) : "")
128132
}
129133

130134
// MARK: - Modifiers

โ€ŽSources/Montage/1 Components/2 Actions/IconButton.swiftโ€Ž

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ public struct IconButton: View {
6464
private var iconColor: SwiftUI.Color?
6565
private var backgroundColor: SwiftUI.Color?
6666
private var borderColor: SwiftUI.Color?
67-
6867
/// ๋ฒ„ํŠผ์˜ ๋น„ํ™œ์„ฑํ™” ์—ฌ๋ถ€๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
6968
/// - Parameter value: ๋น„ํ™œ์„ฑํ™” ์—ฌ๋ถ€, true์ด๋ฉด ๋ฒ„ํŠผ์ด ๋น„ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.
7069
/// - Returns: ์ˆ˜์ •๋œ IconButton ์ธ์Šคํ„ด์Šค
@@ -223,6 +222,9 @@ public struct IconButton: View {
223222
)
224223
.allowsHitTesting(disable == false)
225224
.modifier(PressActionDetectingModifier(isPressed: $isPressed, action: handler))
225+
.accessibilityElement(children: .ignore)
226+
.accessibilityLabel("\(icon.rawValue) \(String(localized: "์•„์ด์ฝ˜", bundle: .module))")
227+
.accessibilityAddTraits(.isButton)
226228
}
227229
}
228230

โ€ŽSources/Montage/1 Components/3 Selection And Input/Control.swiftโ€Ž

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ struct Control: View {
9191
onSelect?($0 ? .checked : .unchecked)
9292
})
9393
)
94+
.labelsHidden()
9495
.disabled(disable)
9596
.tint(backgroundColor)
9697
.frame(width: switchSize.width, height: switchSize.height)
@@ -166,6 +167,10 @@ struct Control: View {
166167
}
167168
}
168169
}
170+
.accessibilityElement(children: .ignore)
171+
.accessibilityLabel(label)
172+
.accessibilityValue(accessibilityStateDescription)
173+
.accessibilityAddTraits(.isButton)
169174
}
170175
}
171176

@@ -407,6 +412,14 @@ extension Control {
407412
)
408413
}
409414

415+
fileprivate var accessibilityStateDescription: String {
416+
switch state {
417+
case .checked: String(localized: "์„ ํƒ๋จ", bundle: .module)
418+
case .unchecked: String(localized: "์„ ํƒ ์•ˆ ๋จ", bundle: .module)
419+
case .indeterminate: String(localized: "๋ถ€๋ถ„ ์„ ํƒ๋จ", bundle: .module)
420+
}
421+
}
422+
410423
fileprivate var spacing: CGFloat {
411424
switch variant {
412425
case .checkbox, .radio:

โ€ŽSources/Montage/1 Components/3 Selection And Input/FilterButton.swiftโ€Ž

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ public struct FilterButton: View {
124124
)
125125
.modifier(PressActionDetectingModifier(isPressed: $isPressed, action: handler))
126126
.disabled(disable)
127+
.accessibilityElement(children: .ignore)
128+
.accessibilityLabel(text)
129+
.accessibilityAddTraits(.isButton)
130+
.accessibilityValue(active ? (activeLabel ?? String(localized: "์„ ํƒ๋จ", bundle: .module)) : "")
127131
}
128132

129133
// MARK: - Modifiers
@@ -137,7 +141,6 @@ public struct FilterButton: View {
137141
private var customIconColor: SwiftUI.Color?
138142
private var fillHorizontal = false
139143
private var fillVertical = false
140-
141144
/// ๋ฒ„ํŠผ์˜ ํ™œ์„ฑํ™” ์ƒํƒœ์™€ ๋ ˆ์ด๋ธ”์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
142145
///
143146
/// - Parameters:

โ€ŽSources/Montage/1 Components/3 Selection And Input/SegmentedControl.swiftโ€Ž

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ public struct SegmentedControl: View {
131131
.padding(buttonInsets)
132132
.frame(width: max(0, buttonWidth))
133133
.frame(maxHeight: .infinity)
134+
.accessibilityRemoveTraits(selectedIndex == index ? [] : .isSelected)
135+
.accessibilityAddTraits(selectedIndex == index ? .isSelected : [])
134136
.background {
135137
Group {
136138
switch variant {
@@ -193,7 +195,6 @@ public struct SegmentedControl: View {
193195
// MARK: - Modifiers
194196
private var variant: Variant = .solid
195197
private var size: Size = .large
196-
197198
/// ์„ธ๊ทธ๋จผํŠธ ์ปจํŠธ๋กค์˜ ์‹œ๊ฐ์  ์Šคํƒ€์ผ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
198199
///
199200
/// - Parameter variant: ์ ์šฉํ•  ์Šคํƒ€์ผ

โ€ŽSources/Montage/1 Components/3 Selection And Input/Select.swiftโ€Ž

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ public struct Select: View {
149149
private var shadowBackgroundColor: SwiftUI.Color = .init(uiColor: UIColor.systemBackground)
150150
private var leadingContent: LeadingContent?
151151
private var menuResize: BottomSheet.Resize = .hug
152-
153152
/// negative ์ƒํƒœ ์—ฌ๋ถ€๋ฅผ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
154153
/// - Parameter negative: ๋ถ€์ •์  ์ƒํƒœ ์—ฌ๋ถ€, ์ƒ๋žตํ•˜๋ฉด ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ `true` ์ ์šฉ
155154
/// - Returns: ์ˆ˜์ •๋œ Select ์ธ์Šคํ„ด์Šค
@@ -428,6 +427,10 @@ public struct Select: View {
428427
}
429428
}
430429
.allowsHitTesting(disable == false)
430+
.accessibilityElement(children: .ignore)
431+
.accessibilityLabel(heading.isEmpty ? placeholder : heading)
432+
.accessibilityValue(selectedItems.map(\.text).joined(separator: ", "))
433+
.accessibilityAddTraits(.isButton)
431434
.onTapGesture {
432435
menuPresented.wrappedValue.toggle()
433436
}

โ€ŽSources/Montage/1 Components/3 Selection And Input/Slider.swiftโ€Ž

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,18 @@ public struct Slider: View {
232232
}
233233
}
234234
.allowsHitTesting(!disable)
235+
.modifier(SliderAccessibilityModifier(
236+
label: String(localized: "์Šฌ๋ผ์ด๋”", bundle: .module),
237+
value: headingLabel,
238+
disable: disable,
239+
onAdjust: handleAccessibilityAdjust
240+
))
235241
}
236242

237243
// MARK: - Modifiers
238244
private var heading = false
239245
private var label = false
240246
private var disable = false
241-
242247
/// ์Šฌ๋ผ์ด๋” ์ƒ๋‹จ์— ์ œ๋ชฉ์„ ํ‘œ์‹œํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
243248
///
244249
/// - Parameter heading: ์ œ๋ชฉ ํ‘œ์‹œ ์—ฌ๋ถ€, ์ƒ๋žตํ•˜๋ฉด ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ `true` ์ ์šฉ
@@ -270,7 +275,30 @@ public struct Slider: View {
270275
}
271276

272277
// MARK: - private
273-
278+
279+
private func handleAccessibilityAdjust(_ direction: AccessibilityAdjustmentDirection) {
280+
guard !disable else { return }
281+
let step = 0.05
282+
switch direction {
283+
case .increment:
284+
if isRangeSlider, focusedThumb == 1 {
285+
thumbRatio1 = min(thumbRatio2, thumbRatio1 + step)
286+
} else {
287+
thumbRatio2 = min(1.0, thumbRatio2 + step)
288+
}
289+
case .decrement:
290+
if isRangeSlider, focusedThumb != 1 {
291+
thumbRatio2 = max(thumbRatio1, thumbRatio2 - step)
292+
} else if isRangeSlider {
293+
thumbRatio1 = max(0.0, thumbRatio1 - step)
294+
} else {
295+
thumbRatio2 = max(0.0, thumbRatio2 - step)
296+
}
297+
@unknown default:
298+
break
299+
}
300+
}
301+
274302
private func updateValues() {
275303
lowValue = (valueRange.upperBound - valueRange.lowerBound) * lowThumbRatio + valueRange.lowerBound
276304
highValue = (valueRange.upperBound - valueRange.lowerBound) * highThumbRatio + valueRange.lowerBound
@@ -445,3 +473,18 @@ public struct Slider: View {
445473
}
446474
}
447475
}
476+
477+
private struct SliderAccessibilityModifier: ViewModifier {
478+
let label: String
479+
let value: String
480+
let disable: Bool
481+
let onAdjust: (AccessibilityAdjustmentDirection) -> Void
482+
483+
func body(content: Content) -> some View {
484+
content
485+
.accessibilityElement(children: .ignore)
486+
.accessibilityLabel(label)
487+
.accessibilityValue(value)
488+
.accessibilityAdjustableAction(onAdjust)
489+
}
490+
}

โ€ŽSources/Montage/1 Components/3 Selection And Input/TextArea.swiftโ€Ž

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,6 @@ public struct TextArea: View {
205205
private var trailingResourceSpacing: CGFloat = 4
206206
private var characterCounterLimit: Int?
207207
private var characterCounterOverflow: Bool = false
208-
209208
/// ํ…์ŠคํŠธ ์˜์—ญ์˜ ํฌ๊ธฐ ์กฐ์ ˆ ๋ฐฉ์‹์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
210209
///
211210
/// - Parameter resize: ํฌ๊ธฐ ์กฐ์ ˆ ๋ฐฉ์‹
@@ -430,6 +429,8 @@ public struct TextArea: View {
430429
.onTapGesture {
431430
focus.wrappedValue = true
432431
}
432+
.accessibilityLabel(heading ?? "")
433+
.accessibilityValue(negative ? (description ?? String(localized: "์˜ค๋ฅ˜", bundle: .module)) : "")
433434
}
434435

435436
private var editorStrokeColor: SwiftUI.Color {

0 commit comments

Comments
ย (0)