ZStack中的矩形更改SwiftUI动画

时间:2020-04-22 16:32:17

标签: ios swift swiftui

我正在尝试使用SwiftUI在两种状态之间转换。

我已将其简化为一个简单的示例

struct Test2View: View {

    @State var isLoading: Bool = true

    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 10)
                .fill(Color. secondary)
                .shadow(radius: 4, x: 2, y: 5)
                .frame(width: 300, height: 150, alignment: .center)

            if isLoading {
                Text("Loading")
                .transition(.moveAndFade())
            } else {
                Text("Content")
                .transition(.moveAndFade())
            }
        }.onTapGesture {
            withAnimation {
                self.isLoading.toggle()
            }
        }
    }

}
extension AnyTransition {
    static func moveAndFade(delay: TimeInterval = 0) -> AnyTransition {
        let insertion = AnyTransition.offset(x: 0, y: 15)
            .combined(with: .opacity)
        let removal = AnyTransition.offset(x: 20, y: 20)
            .combined(with: .opacity)
        return .asymmetric(insertion: insertion, removal: removal)
    }
}

这可以满足我在没有RoundedRectangle的情况下的预期方式:

enter image description here

但是,一旦添加RoundRectangle,我就会丢失删除动画(除非我中断了动画,否则您可以看到我期望的动画):

enter image description here

有人知道为什么RoundedRectangle与动画混淆吗?我什至尝试添加.transition(.identity)都没有成功。

1 个答案:

答案 0 :(得分:0)

我不能说出动画改变的确切原因,但是我找到了原因。这与框架的大小有关。

您的Test2View版本的视图主体:

ZStack {
    RoundedRectangle(cornerRadius: 10)
        .fill(Color.white)
        .shadow(radius: 4, x: 2, y: 5)
        .frame(width: 300, height: 150, alignment: .center)

    if isLoading {
        Text("Loading")
        .transition(.moveAndFade())
    } else {
        Text("Content")
        .transition(.moveAndFade())
    }
}
.border(Color.red)
.onTapGesture {
    withAnimation {
        self.isLoading.toggle()
    }
}

固定版本:

ZStack {
    if isLoading {
        Text("Loading")
        .transition(.moveAndFade())
    } else {
        Text("Content")
        .transition(.moveAndFade())
    }
}
.background(
    RoundedRectangle(cornerRadius: 10)
        .fill(Color.white)
        .shadow(radius: 4, x: 2, y: 5)
        .frame(width: 300, height: 150, alignment: .center)
)
.border(Color.green)
.onTapGesture {
    withAnimation {
        self.isLoading.toggle()
    }
}

基本上,我使用.background而不是创建VStack

比较图像:

Broken Fixed

边框颜色仅用于指示帧大小。您可以删除它!