【问题标题】:In SwiftUI, how do I animate a view from its current position to the center of the screen?在 SwiftUI 中,如何将视图从当前位置动画到屏幕中心?
【发布时间】:2020-04-28 23:54:07
【问题描述】:

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

目前,当您按下按钮时,它会向上/向左一点动画。但我希望按钮动画到屏幕(或安全区域)的确切中心,无论设备或按钮大小如何。代码如下所示,以及我想要的动画开始和结束的图像。

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,但我不知道如何将它用于此目的。

【问题讨论】:

    标签: ios swift swiftui


    【解决方案1】:

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

    使用 Xcode 11.4 / iOS 13.4 测试

    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)
        }
    }
    

    【讨论】:

    • 这太完美了!我喜欢你使用 ZStack 使它有条件地在屏幕中居中;我什至没有想到这一点。我试图用 .overlay() 做这样的事情,但它确实使代码复杂,我无法让它动画。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-28
    相关资源
    最近更新 更多