SwiftUI动画/过渡叠加视图不起作用

时间:2019-09-27 09:58:54

标签: ios swiftui

我正在尝试执行以下操作:

=

由于某些原因 MyView 没有动画。有人对此有解决方案吗?

1 个答案:

答案 0 :(得分:0)

在SwiftUI中,您告诉您的应用您希望UI在给定状态下的外观。然后,如果您的状态发生变化,SwiftUI就会神奇地从显示状态1转换为显示状态2。

在这种情况下,您已告诉SwiftUI,您想要一个VStack,顶部叠放MyView,并且如果有动画,则希望它具有这样的过渡和动画样式。但是,因为您仅提供了一个应用程序状态,所以没有两个状态可以进行动画处理。

以下代码示例应说明我认为您正在尝试做的事情:

struct ContentView: View {
    // We have two states - the border rectangle is shown, or not shown
    // @State allows SwiftUI to know to redraw anything that changes when this variable changes
    @State private var showingOverlay = false

    var body: some View {
        // We lay our root view down first, and the border rectangle on top using ZStack
        ZStack {
            // VSTack likes to shrink down as small as it's content allows
            VStack {
                Text("Hello World")
            }
                // .background() is kind of an implicit ZStack, which lets other content
                //    flow around the VStack like it had the Rectangle's dimensions
                .background(
                    Rectangle()
                        .fill(Color.gray)
                        .frame(width: 300, height: 300)
                )
                // When the VStack appears (when your app launches), set the showingOverlay variable to true
                // Two seconds later, set it back to false
                .onAppear {
                    self.showingOverlay.toggle()
                    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                        self.showingOverlay.toggle()
                    }
            }

            // We only show this Rectangle if the showingOverlay variable is true
            // Since we are transitioning from not showing, to showing, to not showing, SwiftUI will animate
            if showingOverlay {
                Rectangle()
                    .stroke(Color.blue, lineWidth: 5)
                    .frame(width: 300, height: 300)
                    .transition(.asymmetric(insertion: .move(edge: .top), removal: .opacity))
                    .animation(.easeInOut(duration: 1))
            }
        }
    }
}