diff --git a/BlueprintUICommonControls/Sources/AccessibilityContainer.swift b/BlueprintUICommonControls/Sources/AccessibilityContainer.swift index 94e8ccbfb..93f046d47 100644 --- a/BlueprintUICommonControls/Sources/AccessibilityContainer.swift +++ b/BlueprintUICommonControls/Sources/AccessibilityContainer.swift @@ -18,10 +18,12 @@ public struct AccessibilityContainer: Element { /// An optional `accessibilityIdentifier` to give the container. Defaults to `nil`. public var identifier: String? public var wrapped: Element + public var accessibilityElements: [Any]? /// Creates a new `AccessibilityContainer` wrapping the provided element. - public init(identifier: String? = nil, wrapping element: Element) { + public init(identifier: String? = nil, accessibilityElements: [Any]? = nil, wrapping element: Element) { self.identifier = identifier + self.accessibilityElements = accessibilityElements wrapped = element } @@ -36,6 +38,7 @@ public struct AccessibilityContainer: Element { public func backingViewDescription(with context: ViewDescriptionContext) -> ViewDescription? { AccessibilityContainerView.describe { config in config[\.accessibilityIdentifier] = identifier + config[\.explicitAccessibilityElements] = self.accessibilityElements } } } @@ -44,15 +47,17 @@ extension Element { /// Acts as an accessibility container for any subviews /// where `isAccessibilityElement == true`. - public func accessibilityContainer(identifier: String? = nil) -> Element { - AccessibilityContainer(identifier: identifier, wrapping: self) + public func accessibilityContainer(identifier: String? = nil, accessibilityElements: [Any]? = nil) -> Element { + AccessibilityContainer(identifier: identifier, accessibilityElements: accessibilityElements, wrapping: self) } } extension AccessibilityContainer { private final class AccessibilityContainerView: UIView { + var explicitAccessibilityElements: [Any]? + override var accessibilityElements: [Any]? { - get { recursiveAccessibleSubviews() } + get { explicitAccessibilityElements ?? recursiveAccessibleSubviews() } set { fatalError("This property is not settable") } } } diff --git a/BlueprintUICommonControls/Tests/Sources/AccessibilityContainerTests.swift b/BlueprintUICommonControls/Tests/Sources/AccessibilityContainerTests.swift index ff9e71ac8..7a0fab57c 100644 --- a/BlueprintUICommonControls/Tests/Sources/AccessibilityContainerTests.swift +++ b/BlueprintUICommonControls/Tests/Sources/AccessibilityContainerTests.swift @@ -121,4 +121,50 @@ class AccessibilityContainerTests: XCTestCase { XCTAssertNil(accessibleSubviews.first) } + + func test_overrideAccessibility() { + let label1 = Label(text: "One") + let label2 = Label(text: "Two") + let label3 = Label(text: "Three") + let element = Column { + label1 + label2 + label3 + } + + let view = BlueprintView(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) + + element + .accessibilityContainer() + .accessBackingView(in: view) { view in + let textVals: [String] = view.accessibilityElements!.map { + ($0 as! UILabel).text! + } + + XCTAssertEqual(view.accessibilityElements?.count, 3) + XCTAssertEqual(textVals, ["One", "Two", "Three"]) + } + + element + .accessibilityContainer(accessibilityElements: [label1, label3]) + .accessBackingView(in: view) { view in + let textVals: [String] = view.accessibilityElements!.map { + ($0 as! BlueprintUICommonControls.Label).text + } + + XCTAssertEqual(view.accessibilityElements?.count, 2) + XCTAssertEqual(textVals, ["One", "Three"]) + } + + element + .accessibilityContainer(accessibilityElements: [label3, label2, label1]) + .accessBackingView(in: view) { view in + let textVals: [String] = view.accessibilityElements!.map { + ($0 as! BlueprintUICommonControls.Label).text + } + + XCTAssertEqual(view.accessibilityElements?.count, 3) + XCTAssertEqual(textVals, ["Three", "Two", "One"]) + } + } } diff --git a/CHANGELOG.md b/CHANGELOG.md index e8d5fa781..01bb732c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - `AccessibilityElement.CustomContent` now exposes previously internal methods for creating `AXCustomContent` objects. +- Expose `accessibilityElements` on `accessibilityContainer` ### Removed