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

猫克杯 2020/7/29 23:33:39

译自 www.hackingwithswift.com/books/ios-s… 更多内容,欢迎关注公众号 「Swift花园」 喜欢文章?不如来个 🔺💛➕三连?关注专栏,关注我 🚀🚀🚀轻扫时给视图着色 用户可以通过向左或者向右滑出卡片来标记这次回答是正确还是错误,但是两个方向现在没有视觉上…

译自 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花园微信公众号
随时随地学软件编程-关注百度小程序和微信小程序
关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。
本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。
[[SwiftUI 100 天] 轻扫时给视图着色]http://www.zyiz.net/tech/detail-145373.html

上一篇:Dart 异步与多线程

下一篇:避风头?库克表示安卓才是全球手机第一大操作系统,垄断跟 iOS 没关系

赞(0)

共有 条评论 网友评论

验证码: 看不清楚?
    关注微信小程序
    程序员编程王-随时随地学编程

    扫描二维码或查找【程序员编程王】

    可以随时随地学编程啦!

    技术文章导航 更多>
    扫一扫关注最新编程教程