SwiftUI动画/转换覆盖视图无法正常工作

5

我想要做类似于这样的事情:

VStack { 
   content()
}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
.overlay(
   MyView()
   .transition(.asymmetric(insertion: .move(edge: .top), removal: .opacity))
   .animation(.easeInOut)
)

由于某些原因,MyView无法进行动画效果。是否有人能提供解决方案?

1个回答

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

1
这对我可能有用,谢谢,但我想知道是否可以使用此覆盖属性 https://developer.apple.com/documentation/swiftui/image/3269703-overlay 来实现相同的结果。 - Sergiu Coca
据我所知,您不能在.overlay()方法内部使用自定义转换。放置在那里的任何转换都不会动画。我看过的Apple文档和第三方教程(https://swiftui-lab.com/advanced-transitions/)(https://medium.com/better-programming/fancy-swiftui-making-an-interactive-overlay-control-202e691c04bf)都没有使用这样的转换,因此这可能不是正确的方法。您想使用`.overlay()`的特定原因吗? - John M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接