2

SwiftUI – withAnimation 和 AnyTransition. animation() 的区别

 2 years ago
source link: https://www.hawu.me/coding/2603
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

SwiftUI – withAnimation 和 AnyTransition. animation() 的区别

Base on macOS 10.15, Xcode 11.7.

暂且不看对外部视图的影响的话,withAnimation() 和 AnyTransition.animation() 对于其修饰的视图其实是相同效果的不同写法。

Button("show/hide"){
withAnimation {
self.show.toggle()
if show {
Text("hello")
.transition(.scale)
Button("show/hide"){
    withAnimation {
        self.show.toggle()
    }
}

if show {
    Text("hello")
        .transition(.scale)
}
Button("show/hide"){
self.show.toggle()
if show {
Text("hello")
.transition(AnyTransition.scale.animation(.default))
Button("show/hide"){
    self.show.toggle()
}
if show {
    Text("hello")
        .transition(AnyTransition.scale.animation(.default))
}

还有一个要注意! 在那几种 AnyTransition 中,只有对 .opacity 与 .scale 直接调用 animation() 是有效的。而对于 .slide, .move, .offset 这几种,是要将 .transition() 修饰器与 .animation() 修饰器连用才行。即:

withAnimation {
self.show.toggle()
if show {
Text("hello").transition(.move(edge: .top))
if show {
Text("hello")
.transition(.move(edge: .top))
.animation(.default)
withAnimation {
    self.show.toggle()
}

if show {
    Text("hello").transition(.move(edge: .top))
}

等效于:

if show {
    Text("hello")
        .transition(.move(edge: .top))
        .animation(.default)
}

呃,我也无法理解 SwiftUI 为什么会有这种幺蛾子。。 =。=#


指定 Animation 的话

Button("show/hide"){
withAnimation(Animation.easeInOut(duration: 1)) {
self.show.toggle()
if show {
Text("hello")
.transition(.scale)
Button("show/hide"){
    withAnimation(Animation.easeInOut(duration: 1)) {
        self.show.toggle()
    }
}

if show {
    Text("hello")
        .transition(.scale)
}
Button("show/hide"){
self.show.toggle()
if show {
Text("hello")
.transition(AnyTransition.scale.animation(Animation.easeInOut(duration: 1)))
Button("show/hide"){
    self.show.toggle()
}

if show {
    Text("hello")
        .transition(AnyTransition.scale.animation(Animation.easeInOut(duration: 1)))
}

但是在实际的使用中,如果父视图的 size 是非固定大小的,那么使用 withAnimation() 可能会导致父视图也出现连锁的“动画”异动。以上述的例子,我把完整代码与截图贴出来对比一下就知道:

2.1 使用 withAnimation 的效果

struct ContentView: View {
@State var show = false
var body: some View {
VStack {
Button("show/hide"){
withAnimation(Animation.easeInOut(duration: 1)) {
self.show.toggle()
Divider()
if show {
Text("hello")
.transition(.scale)
}.padding()
struct ContentView: View {
    @State var show = false

    var body: some View {
        VStack {
            Button("show/hide"){
                withAnimation(Animation.easeInOut(duration: 1)) {
                    self.show.toggle()
                }
            }

            Divider()

            if show {
                Text("hello")
                    .transition(.scale)
            }
        }.padding()
    }
}

可以看到动画效果影响到了 “show/hide” 按钮与分割线,这并不是我们想要的结果。

2.2 只在对应视图使用 AnyTransition. animation()  的效果

ct ContentView: View {
@State var show = false
var body: some View {
VStack {
Button("show/hide"){
self.show.toggle()
Divider()
if show {
Text("hello")
.transition(AnyTransition.scale.animation(Animation.easeInOut(duration: 1)))
}.padding()
ct ContentView: View {
    @State var show = false

    var body: some View {
        VStack {
            Button("show/hide"){
                self.show.toggle()
            }

            Divider()

            if show {
                Text("hello")
                    .transition(AnyTransition.scale.animation(Animation.easeInOut(duration: 1)))
            }
        }.padding()
    }
}

"show/hide" 按钮纹丝未动,这才是我们想要的。

对于要实现动画效果的视图,还是尽量只在该视图上使用 .animation() 修饰器,与 .transition(AnyTransition.animation()) 修饰器。withAnimation() 在写法上又多余,还可能携带副作用,不明白它有啥用呢😠 。

SwiftUI

One thought on “SwiftUI – withAnimation 和 AnyTransition. animation() 的区别”

发表评论 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注

评论

显示名称 *

电子邮箱地址 *

网站地址

如果有人回复我的评论,请通过电子邮件通知我。


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK