在SwiftUI中,如何为视图从当前位置到屏幕中心设置动画?

时间:2020-04-28 23:54:07

标签: ios swift swiftui

在此示例应用程序中,我在屏幕的左上方有一个标题,在右下方有一个按钮。我正在使用堆栈和垫片来对齐它们。

当前,当您按下按钮时,它会向上/向左移动一点动画。但是我希望按钮能够动画到屏幕的确切中心(或安全区域),而不管设备或按钮的大小如何。下面显示了代码以及所需动画的开始和结束图像。

struct ContentView: View {

    @State var buttonIsMoved = false

    var body: some View {
        VStack {
            HStack {
                Text("Title")
                    .font(.largeTitle)
                Spacer()
            }
            Spacer()
            HStack {
                Spacer()
                // This is the button I want to animate to the center
                Button(action: {
                    self.buttonIsMoved.toggle()
                }) {
                    Text("This is a button")
                        .foregroundColor(.black)
                        .padding(16)
                        .background(Color.green)
                }
                    // Currently I'm just using fixed offset values,
                    // but I want it to move to the actual center of the screen
                    .offset(buttonIsMoved ? CGSize(width: -50, height: -200) : .zero)
                    .animation(.easeInOut)
            }
        }
        .padding(32)
    }
}

Start of animation

End of animation

如果我使用.offset(),则不知道如何计算按钮的中心与屏幕中心之间的距离。我也尝试过使用.position(),但是它基于父视图,在这种情况下,它是标题下方的HStack,因此它不会位于整个屏幕的中央。我也听说过GeometryReader,但是我不知道如何为此目的使用它。

1 个答案:

答案 0 :(得分:0)

这是可能的解决方案-基于SwiftUI本机布局引擎,无需硬编码。

通过Xcode 11.4 / iOS 13.4测试

demo

struct DemoAnimateLayout: View {

    @State var buttonIsMoved = false

    var body: some View {
        ZStack {
            VStack {
                HStack {
                    Text("Title")
                        .font(.largeTitle)
                    Spacer()
                }
                Spacer()
            }
            VStack {
                if !buttonIsMoved {  // <<      here !!
                    Spacer()
                }

                HStack {
                    if !buttonIsMoved {  // <<     here !!
                        Spacer()
                    }
                    // This is the button I want to animate to the center
                    Button(action: {
                        self.buttonIsMoved.toggle()
                    }) {
                        Text("This is a button")
                            .foregroundColor(.black)
                            .padding(16)
                            .background(Color.green)
                    }
                }
            }
            .animation(.easeInOut)  // << animate container layout !!

        }.padding(32)
    }
}