Animation 在SwiftUI中将视图添加到层次结构时如何设置过渡动画

Animation 在SwiftUI中将视图添加到层次结构时如何设置过渡动画,animation,swiftui,transition,Animation,Swiftui,Transition,我试图建立一个覆盖的“popover”视图和动画过渡进出。向外转换有效,但向内转换无效——添加popover视图时,它会突然出现(错误),但当移除popover视图时,它会向右滑动(正确)。在这段代码中,当popover被添加到视图层次结构中时,我如何使其滑入(从右侧)呢 iOS 14中的全功能代码 import SwiftUI struct ContentView: View { var body: some View { Popovers() }

我试图建立一个覆盖的“popover”视图和动画过渡进出。向外转换有效,但向内转换无效——添加popover视图时,它会突然出现(错误),但当移除popover视图时,它会向右滑动(正确)。在这段代码中,当popover被添加到视图层次结构中时,我如何使其滑入(从右侧)呢

iOS 14中的全功能代码

import SwiftUI

struct ContentView: View {
    
    var body: some View {
        Popovers()
    }
}

struct Popovers : View {
    
    @State var popovers : [AnyView] = []
    
    var body : some View {
        Button("Add a view ...") {
            withAnimation {
                popovers += [new()]
            }
        }
        .blur(radius: 0 < popovers.count ? 8 : 0)
        .overlay(ZStack {
            ForEach(0..<self.popovers.count, id: \.self) { i in
                popovers[i]
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .blur(radius: (i+1) < popovers.count ? 8 : 0)
                    .transition(.move(edge: .trailing)) // works only when popover is removed
            }
        })
    }
    
    func new() -> AnyView {
        let popover = popovers.count
        
        return AnyView.init(
            VStack(spacing: 64) {
                
                Button("Close") {
                    withAnimation {
                        _ = popovers.removeLast()
                    }
                }
                .font(.largeTitle)
                .padding()

                Button("Add") {
                    withAnimation {
                        popovers += [new()]
                    }
                }
                .font(.largeTitle)
                .padding()

                Text("This is popover #\(popover)")
                    .font(.title)
                    .foregroundColor(.white)
                    .fixedSize()
                
            }
            .background(Color.init(hue: 0.65-(Double(3*popover)/100.0), saturation: 0.3, brightness: 0.9).opacity(0.98))
        )
    }
    
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

extension View {
    var asAnyView : AnyView {
        AnyView(self)
    }
}
导入快捷界面
结构ContentView:View{
var body:一些观点{
爆米花()
}
}
结构弹出框:视图{
@状态变量弹出框:[AnyView]=[]
var body:一些观点{
按钮(“添加视图…”){
动画片{
弹出框+=[new()]
}
}
.blur(半径:0
解决方案是将动画添加到容器中。使用Xcode 12/iOS 14进行测试

struct弹出框:视图{
@状态变量弹出框:[AnyView]=[]
var body:一些观点{
按钮(“添加视图…”){
动画片{
弹出框+=[new()]
}
}
.blur(半径:0ForEach(0..工作得很好,但为什么它现在可以工作-为什么它可以用于向外转换而不是向内转换?
struct Popovers : View {
    
    @State var popovers : [AnyView] = []
    
    var body : some View {
        Button("Add a view ...") {
            withAnimation {
                popovers += [new()]
            }
        }
        .blur(radius: 0 < popovers.count ? 8 : 0)
        .overlay(ZStack {
            ForEach(0..<self.popovers.count, id: \.self) { i in
                popovers[i]
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .blur(radius: (i+1) < popovers.count ? 8 : 0)
                    .transition(.move(edge: .trailing))
            }
        }.animation(.default))    // << add animation to container
    }
    
    func new() -> AnyView {
        let popover = popovers.count
        
        return AnyView.init(
            VStack(spacing: 64) {
                
                Button("Close") {
                            _ = popovers.removeLast()
                }
                .font(.largeTitle)
                .padding()

                Button("Add") {
                            popovers += [new()]
                }
                .font(.largeTitle)
                .padding()

                Text("This is popover #\(popover)")
                    .font(.title)
                    .foregroundColor(.white)
                    .fixedSize()
                
            }
            .background(Color.init(hue: 0.65-(Double(3*popover)/100.0), saturation: 0.3, brightness: 0.9).opacity(0.98))
        )
    }
    
}