[SwiftUI 100 天] 轻扫时给视图着色

2020/7/29 23:33:39

本文主要是介绍[SwiftUI 100 天] 轻扫时给视图着色,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

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

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

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

轻扫时给视图着色

用户可以通过向左或者向右滑出卡片来标记这次回答是正确还是错误,但是两个方向现在没有视觉上的区分。借用 约会应用 Tinder 的做法,我们可以让右滑表示好(回答正确),左滑表示不好(回答错误)。

我们会以两种方式解决这个问题:对于采用默认设置的手机,我们会给卡片上绿色或者红色,但是如果用户启用了“不以颜色区分”设置,我们会保持卡片为白色,并且在背景上添加一些额外的 UI。

首先让我们来看一下卡片目前的效果:

RoundedRectangle(cornerRadius: 25, style: .continuous)
    .fill(Color.white)
    .shadow(radius: 10)
复制代码

现在我们把上面的代码替换为更高级的版本:我们要让背景的颜色随着手势的移动呈现绿色或者红色,同时让前景填充的白色随着拖拽的移动变大。

首先是背景部分。把下面的代码直接添加到 shadow() modifier 之后:

.background(
    RoundedRectangle(cornerRadius: 25, style: .continuous)
        .fill(offset.width > 0 ? Color.green : Color.red)
)
复制代码

对于前景的透明度,处理方式跟我们之前处理拖拽渐隐的方式相似,只不过用 1 - 1/50 的手势宽度而不是 2 - 1/50 的手势宽度。 这样做的区别是之前的渐隐需要至少拖拽 50 个点才会触发,而现在只要移动就会看到颜色变化。

把之前的 fill() modifier 替换成:

.fill(
    Color.white
        .opacity(1 - Double(abs(offset.width / 50)))
)
复制代码

运行应用,你可以看到随着拖拽进行,卡片从白色变成红色或者绿色,然后开始渐隐。酷!

不过,对红绿色盲人群,我们的方案是不管用的 —— 他们只会看到卡片亮度的变化,但感受不到左右两边的区别。

为了解决这个问题,我们需要添加一个环境属性来确认我们是否应当使用颜色,这个属性如下:

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

对于 RoundedRectangle,前景和背景我们都要使用这个技巧。

把当前的 RoundedRectangle 代码替换为下面这样:

RoundedRectangle(cornerRadius: 25, style: .continuous)
    .fill(
        differentiateWithoutColor
            ? Color.white
            : Color.white
                .opacity(1 - Double(abs(offset.width / 50)))

    )
    .background(
        differentiateWithoutColor
            ? nil
            : RoundedRectangle(cornerRadius: 25, style: .continuous)
                .fill(offset.width > 0 ? Color.green : Color.red)
    )
    .shadow(radius: 10)
复制代码

因此,在默认配置下,我们的卡片会变化为绿色或者红色,但不以颜色区分启用时,这个颜色变化不会发生。因此,我们需要提供一些额外的 UI 来区分正确和错误。

把这个属性添加到 ContentView

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

然后添加下面的视图到 VStack 之后:

if differentiateWithoutColor {
    VStack {
        Spacer()

        HStack {
            Image(systemName: "xmark.circle")
                .padding()
                .background(Color.black.opacity(0.7))
                .clipShape(Circle())
            Spacer()
            Image(systemName: "checkmark.circle")
                .padding()
                .background(Color.black.opacity(0.7))
                .clipShape(Circle())
        }
        .foregroundColor(.white)
        .font(.largeTitle)
        .padding()
    }
}
复制代码

这样会创建一个新的 VStack,以 Spacer() 是为了把这个栈推到屏幕底部,并且由于条件的存在,这个 UI 只有“不以颜色区分”启用时才会出现。

这些额外的工作很重要:确保所有的用户都能够获得良好的体验,不管他们是否启用了辅助功能。这是应用开发者应该努力的目标。


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

Swift花园微信公众号

这篇关于[SwiftUI 100 天] 轻扫时给视图着色的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程