[SwiftUI 100 天] 在 SwiftUI 中支持特定的辅助功能需求

2020/7/21 23:04:05

本文主要是介绍[SwiftUI 100 天] 在 SwiftUI 中支持特定的辅助功能需求,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

译自 www.hackingwithswift.com/books/ios-s…

更多内容,欢迎关注公众号 「Swift花园」

喜欢文章?不如来个 🔺💛➕三连?关注专栏,关注我 🚀🚀🚀

在 SwiftUI 中支持特定的辅助功能需求

SwiftUI 提供了大量环境变量,描述了用户的自定义辅助设置,因此花点时间阅读和理解这些设置是值得的。

在项目 15 中,我们涉猎了标签、提示,控件特征,分组等辅助功能。但这里要介绍的辅助设置不一样,因为它们是通过环境提供的。这意味着 SwiftUI 会自动监控它们的变化,并在需要时自动调用我们的 body 属性。

例如,有一个辅助选项叫 “不以颜色区分”,它对于在人群中占比 1/12 的色盲群体是很有帮助的。但这项设置被启用时,应用会尝试借助形状,图标和纹理而不是颜色来让 UI 的含义更清晰。

添加这个环境属性来尝试:

@Environment(\.accessibilityDifferentiateWithoutColor) var differentiateWithoutColor
复制代码

这个属性是布尔型,你可以根据它的值来适配 UI。例如,下面的代码里我们为常规布局采用了一个简单的绿色背景,但当 “不以颜色区分” 启用时,我们采用黑色背景,外加一个复选标记:

struct ContentView: View {
    @Environment(\.accessibilityDifferentiateWithoutColor) var differentiateWithoutColor
    var body: some View {
        HStack {
            if differentiateWithoutColor {
                Image(systemName: "checkmark.circle")
            }

            Text("成功")
        }
        .padding()
        .background(differentiateWithoutColor ? Color.black : Color.green)
        .foregroundColor(Color.white)
        .clipShape(Capsule())
    }
}
复制代码

你可以在模拟器中打开设置应用,选择 辅助功能 > 显示和文子大小 > 不以颜色区分:

还有一个常见的选项是 “减弱动态效果”,位于 辅助功能 > 动态效果 > 减弱动态效果。当这项设置被启用时,应用会限制屏幕上会引起移动的动画数量。例如,iOS 应用的切换动画会由放大缩小变为淡入淡出。

在 SwiftUI 中,这意味着我们要对应地限制 withAnimation() 的使用,像下面这样:

struct ContentView: View {
    @Environment(\.accessibilityReduceMotion) var reduceMotion
    @State private var scale: CGFloat = 1

    var body: some View {
        Text("Hello, World!")
            .scaleEffect(scale)
            .onTapGesture {
                if self.reduceMotion {
                    self.scale *= 1.5
                } else {
                    withAnimation {
                        self.scale *= 1.5
                    }
                }
            }
    }
}
复制代码

不知道你是怎么想的,反正我觉得这么写着实恼人。好在我们可以借助对 withAnimation() 进行包装,在包装函数内部根据 UIKit’s UIAccessibility 来决定跳过动画还是执行动画:

func withOptionalAnimation<Result>(_ animation: Animation? = .default, _ body: () throws -> Result) rethrows -> Result {
    if UIAccessibility.isReduceMotionEnabled {
        return try body()
    } else {
        return try withAnimation(animation, body)
    }
}
复制代码

这样一来,当 “减弱动态效果” 启用时,闭包将立即执行,否则会传给 withAnimation()。这里的 throws/rethrows 是 Swift 的高级主题,是从 withAnimation() 的函数签名那里直接复制过来的,以便两个函数可以互相替换使用。

用法如下:

struct ContentView: View {
    @State private var scale: CGFloat = 1

    var body: some View {
        Text("Hello, World!")
            .scaleEffect(scale)
            .onTapGesture {
                withOptionalAnimation {
                    self.scale *= 1.5
                }
            }
    }
}
复制代码

通过这种方式,你就不再需要在各个地方都重复写动画的判断代码。

你应该考虑支持的选项还包括 “减弱透明度”。当这个设置启用时,应用应当减少模糊和透明设计的使用,以确保所有东西都足够清晰。

例如,下面的代码在 “减弱透明度” 启用时采用纯黑色背景,而不启用时则使用 50% 的透明度:

struct ContentView: View {
    @Environment(\.accessibilityReduceTransparency) var reduceTransparency
    var body: some View {
        Text("Hello, World!")
            .padding()
            .background(reduceTransparency ? Color.black : Color.black.opacity(0.5))
            .foregroundColor(Color.white)
            .clipShape(Capsule())
    }
}
复制代码

接下来我们就要进入实际构建项目的过程了,请把工程还原回原始状态。


我的公众号 这里有Swift及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~

Swift花园微信公众号

这篇关于[SwiftUI 100 天] 在 SwiftUI 中支持特定的辅助功能需求的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程