译自 www.hackingwithswift.com/books/ios-s…
更多内容,欢迎关注公众号 「Swift花园」
喜欢文章?不如来个 🔺💛➕三连?关注专栏,关注我 🚀🚀🚀
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及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~