Swift教程

【译】[SwiftUI 100 天] Animations - part4

本文主要是介绍【译】[SwiftUI 100 天] Animations - part4,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
译自 Showing and hiding views with transitions
更多内容,欢迎关注公众号 「Swift花园」
喜欢文章?不如来个 🔺💛➕三连?关注专栏,关注我 🚀🚀🚀

用过渡显示和隐藏视图

SwiftUI 一个最强大的特性是可以定制视图的显示和隐藏。之前你已经见过我们如何使用常规的 if 条件来实现条件化视图,也就是我们可以根据条件变化在视图体系中插入或者移除视图。

过渡控制这些插入和移除如何发生。我们可以使用内建的过渡,以各种方式组合它们,甚至完全自定义过渡。

下面用一个带按钮和矩形块的 VStack 来演示:

struct ContentView: View {
    var body: some View {
        VStack {
            Button("Tap Me") {
                // do nothing
            }

            Rectangle()
                .fill(Color.red)
                .frame(width: 200, height: 200)
        }
    }
}复制代码

我们可以让矩形块在某个条件满足时才出现。首先,添加一个状态:

@State private var isShowingRed = false复制代码

然后用状态作为条件来显示矩形块:

if isShowingRed {
    Rectangle()
        .fill(Color.red)
        .frame(width: 200, height: 200)
}复制代码

最后,在按钮的 action 中触发 isShowingRed 在 true 和 false 间转换:

self.isShowingRed.toggle()复制代码

运行程序,你会看到点击按钮会显示或者隐藏一个红色矩形块。但没有动画,它只是突然地出现或者消失。

我们可以用 SwiftUI 的默认视图过渡来包装状态变化过程,像这样:

withAnimation {
    self.isShowingRed.toggle()
}复制代码

通过这个小改变,应用现在可以渐显或者渐隐矩形块,同时将按钮上移或者下移来调整空间。看起来还不错,但我们可以利用 transition() modifier 做到更好。

举个例子,我们可以让矩形块以缩放的方式来出场和离场,添加 transition() modifier 给矩形块:

Rectangle()
    .fill(Color.red)
    .frame(width: 200, height: 200)
    .transition(.scale)复制代码

现在点击按钮,看起来更好了:矩形块随着按钮给它腾地方的时候变大,再点击按钮,矩形块又以缩小的方式消失。

如果你想实验的话,有许多别的过渡可以尝试。其中一个很有用的过渡是 .asymmetric ,它可以让我们用一个过渡配置视图显示,另一个过渡配置视图隐藏。尽管尝试一下,把矩形块的退出过渡换成下面的:

.transition(.asymmetric(insertion: .scale, removal: .opacity))复制代码
译自 Building custom transitions using ViewModifier

用 ViewModifier 构建自定义过渡

用 SwiftUI 创建一个全新的过渡,是可能的,实际上非常容易。自定义过渡允许我们用完全自定义的动画来添加或者移除视图。

这个功能是通过 .modifier 过渡来实现的,它可以接收任意视图 modifier 。要点在于我们需要实例化这个 modifier ,也就是自行创建它们。

让我们动手尝试。写一个 view modifier ,实现一个类似 Keynote 里最简单的 Pivot 动画 —— 让一个新的幻灯片以旋转的方式从左上角进入画面 。用 SwiftUI 的术语来说,就是创建一个 view modifier,让我们的视图旋转着从某一个角进入屏幕,但不逃出它本该有的边界。 SwiftUI 直接提供了这样的 modifier :rotationEffect() ,这个 modifier 让我们在 2D 空间中旋转视图,而 clipped() 可以阻止超出视图区域的部分被绘制。

rotationEffect() 和 rotation3DEffect() 相似,除了它只围绕 Z 轴旋转。不过,它还提供了控制旋转锚点的能力 —— 锚点就是视图中作为旋转中心固定的部分。对此,SwiftUI 提供了 UnitPoint 类型,用于设置锚点,即可以指定精确的 X,Y 坐标,也可以用许多内置的选项 —— .topLeading,.bottomTrailing,.center 等等。

让我们创建一个 CornerRotateModifier 结构体,把上面介绍的知识点都放进去演示。这个 modifier 用一个锚点来控制旋转中心,并且可以设置旋转角度:

struct CornerRotateModifier: ViewModifier {
    let amount: Double
    let anchor: UnitPoint

    func body(content: Content) -> some View {
        content.rotationEffect(.degrees(amount), anchor: anchor).clipped()
    }
}复制代码

额外的 clipped() 表示当视图旋转时,超出它本来的矩形区域的部分不做绘制。

我们可以利用 .modifier 过渡直接尝试,但那样的方式不常用。更好的方式通过扩展 AnyTransition 来使用。下面的扩展实现以左上角为锚点,从 -90 度旋转到 0 度的过渡。

extension AnyTransition {
    static var pivot: AnyTransition {
        .modifier(
            active: CornerRotateModifier(amount: -90, anchor: .topLeading),
            identity: CornerRotateModifier(amount: 0, anchor: .topLeading)
        )
    }
}复制代码

上面的代码就绪后,我们可以用下面的代码附加这个过渡到任意视图上:

.transition(.pivot)复制代码

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



这篇关于【译】[SwiftUI 100 天] Animations - part4的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!