切换覆盖家长辅助功能,保留儿童辅助功能首选项

问题描述 投票:0回答:1

假设 iOS 应用程序通过

overlay
修饰符或在
ZStack
中呈现一些内容。通过这种方式,可访问性焦点(例如,当用户启用语音时)可用于父内容和呈现内容的元素。

我可以在底层视图上使用

accessibilityHidden(isOverlayPresented)
修饰符来解决此问题,但在这种情况下,当
isOverlayPresented
false
时,SwiftUI 会忽略传递给应用于子视图的
accessibilityHidden
修饰符的参数。

在下面的示例中,当显示“文本 3”时,可访问性转子会忽略“文本 1”和“文本 2”标签,但当未显示“文本 3”时,它不会忽略“文本 1”,尽管应用了

.accessibilityHidden(true)
.

struct ContentView: View {
    
    @State var isOverlayPresented = false

    var body: some View {
        VStack(spacing: 40) {
            ZStack {
                VStack(spacing: 20) {
                    Text("Text 1")
                        .accessibilityHidden(true)
                    Text("Text 2")
                    
                }
                // don't want the view to be accessible when overlay is presented
                .accessibilityHidden(isOverlayPresented)
                
                if isOverlayPresented {
                    Text("Text 3")
                        .padding(30)
                        .background(.yellow)
                }
            }
            
            Button(isOverlayPresented ? "Show" : "Hide") {
                isOverlayPresented.toggle()
            }
            .buttonStyle(.bordered)
        }
    }
}

在我看来,“文本 1”总是被可访问性忽略应该是预期的行为。如果我在 SwiftUI 环境中实现这一点,我会做类似的事情,这样从父级传递的

true
值就无法覆盖子级首选项。

extension View {
    func accessibilityHidden(_ hidden: Bool) -> some View {
        transformEnvironment(\.accessibilityHidden) { hiddenByParent in 
            hidden = hidden || hiddenByParent
        }
    }
}

我还可以使用条件修饰符,当参数值为 false 时不会应用它,但在我看来条件修饰符是邪恶的,特别是当应用于复杂视图时(例如某些流程的根视图)。

有什么好的方法可以实现我想要的吗?

ios swiftui accessibility
1个回答
0
投票

由于您将accessibilityHidden应用于容器,它会重写您应用于Text(“Text1”)的内部修饰符,并且因为当未显示Text3的背景时

isOverlayPresented == false
,因此第
.accessibilityHidden(isOverlayPresented)
行表示所有VStack的子级都不应该隐藏可达性。

发生这种情况是因为容器默认不是可访问元素。所以你需要指定它们是

要实现此目的,您需要在

.accessibilityElement(children: .contain)
之前应用
.accessibilityHidden(isOverlayPresented)
。这样我们就知道 VStack 是可访问元素,并且它包含它的子元素,因此我们可以与它们交互

代码如下:

struct ContentView: View {
    
    @State var isOverlayPresented = false

    var body: some View {
        VStack(spacing: 40) {
            ZStack {
                VStack(spacing: 20) {
                    Text("Text 1")
                        .accessibilityHidden(true)
                    Text("Text 2")
                }
                // ====
                // ==== You need to add this line ====
                // ====
                .accessibilityElement(children: .contain)
                // don't want the view to be accessible when overlay is presented
                .accessibilityHidden(isOverlayPresented)
                
                if isOverlayPresented {
                    Text("Text 3")
                        .padding(30)
                        .background(.yellow)
                }
            }
            
            Button(isOverlayPresented ? "Show" : "Hide") {
                isOverlayPresented.toggle()
            }
            .buttonStyle(.bordered)
        }
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.