SwiftUI-仅对视图位置进行动画处理

问题描述

我有一个应用,其中我尝试在更改时对不同的属性进行动画处理。在以下演示应用程序中,按下“翻转”按钮时,弹簧动画将同时应用于大小和位置:

Screen recording of app

代码如下:

class Thing: Identifiable {
    var id: Int

    init(id: Int) {
        self.id = id
    }
}

struct ContentView: View {
    @State var isFlipped: Bool = false

    let thing1 = Thing(id: 1)
    let thing2 = Thing(id: 2)

    var body: some View {
        vstack(spacing: 12) {
            HStack(spacing: 20) {
                ForEach(isFlipped ? [thing2,thing1] : [thing1,thing2]) { thing in
                    Text("\(thing.id)").font(.system(size: 150,weight: .heavy))
                        .scaleEffect(isFlipped ? CGFloat(thing.id)*0.4 : 1.0)
                        .animation(.spring(response: 0.5,dampingFraction: 0.3))
                }
            }
            Button("Flip") { isFlipped.toggle() }
        }
    }
}

我的问题是:如何在不设置比例动画的情况下为位置设置动画?

如果删除.scaleEffect()修饰符,则仅对位置进行动画处理。 但是,如果我随后将其插入.animation()修饰符后的 中,则根本不会出现 no 动画,甚至没有位置。对我来说这很奇怪!

我熟悉“动画堆栈”的概念-哪些动画应用于视图属性,取决于修改器和动画应用于视图的顺序。但是我无法理解这些位置在该堆栈中的位置...或者如何去思考发生了什么。

有什么想法吗?

已编辑:我更改了.scaleEffect()修饰符,以对不同的Thing对象进行不同的操作,以包括我所面对的问题的那一部分;谢谢@Bill提供的解决方案。

解决方法

如何缩放HStack而不是Text?

var body: some View {
    VStack(spacing: 12) {
        HStack(spacing: 20) {
            ForEach(isFlipped ? [thing2,thing1] : [thing1,thing2]) { thing in
                Text("\(thing.id)").font(.system(size: 150,weight: .heavy))
            }
        }
        .animation(.spring(response: 0.5,dampingFraction: 0.3))
        .scaleEffect(isFlipped ? 0.5 : 1.0)
        
        Button("Flip") { isFlipped.toggle() }
    }
}