视图不会以应有的方式消失

View don't disappear with the way it should

我正在尝试使用漂亮流畅的动画让黄色视图从底部和顶部消失。 (slide/move 到 top/bottom + 淡入淡出并保持中间视图占据整个 space) 这就是我现在的状态,一点都不顺畅,哈哈。但它有效。

import SwiftUI

struct ContentView: View {
    @State var isInterfaceHidden: Bool = false

    var body: some View {
        VStack(spacing: 0, content: {
            if !isInterfaceHidden {
                Rectangle()
                    .id("animation")
                    .foregroundColor(Color.yellow)
                    .frame(height: 40)
                    .transition(AnyTransition.move(edge: .top).combined(with: .opacity).animation(.linear))
            }
            Rectangle()
                .id("animation2")
                .foregroundColor(Color.red)
                .transition(AnyTransition.opacity.animation(Animation.linear))
                /// We make sure it won't cover the top and bottom view.
                .zIndex(-1)
                .background(Color.red)
                .onTapGesture(perform: {
                    DispatchQueue.main.async {
                        self.isInterfaceHidden.toggle()
                    }
                })
            if !isInterfaceHidden {
                Rectangle()
                    .id("animation3")
                    .foregroundColor(Color.yellow)
                    .frame(height: 80)
                    .transition(AnyTransition.move(edge: .bottom).combined(with: .opacity).animation(.linear))
            }
        })
        .navigationBarTitle("")
        .navigationBarHidden(true)
    }
}

当前动画:

Edit3:感谢@Andrew,我能够以更好的状态进步。 但现在我有一种生涩的动画。 有什么想法吗?

只需将两个黄色视图的 Z 索引设置为高于默认值 1.0。这样 SwiftUI 将确保它们不会被红色视图覆盖。

这样做的修饰符是.zIndex()

更简单的解决方案

结构测试:查看{

@State private var isHiding = false

var body: some View {
    ZStack {
        Rectangle()
            .foregroundColor(.yellow)
            .frame(width: 200, height: 100)
        Rectangle()
            .foregroundColor(.red)
            .frame(width: 200, height: isHiding ? 100 : 80)
            .onTapGesture {
                withAnimation {
                    self.isHiding.toggle()
                }
        }
    }
}

}

我可能已经找到适合您的解决方案:

import SwiftUI

struct ContentView: View {
    @State var isInterfaceHidden: Bool = false

    var body: some View {
        VStack(spacing: 0, content: {
            if !isInterfaceHidden {
                Rectangle()
                    .id("animation")
                    .foregroundColor(Color.yellow)
                    .frame(height: 40)
                    .transition(.topViewTransition)
            }
            Rectangle()
                .id("animation2")
                .foregroundColor(Color.red)
                /// We make sure it won't cover the top and bottom view.
                .zIndex(-1)
                .background(Color.red)
                .onTapGesture(perform: {
                    DispatchQueue.main.async {
                        self.isInterfaceHidden.toggle()
                    }
                })
            if !isInterfaceHidden {
                Rectangle()
                    .id("animation3")
                    .foregroundColor(Color.yellow)
                    .frame(height: 80)
                    .transition(.bottomViewTransition)
            }
        })
        .navigationBarTitle("")
        .navigationBarHidden(true)
        .animation(.easeInOut)
    }
}

extension AnyTransition {

    static var topViewTransition: AnyTransition {
        let transition = AnyTransition.move(edge: .top)
            .combined(with: .opacity)
        return transition
    }

    static var bottomViewTransition: AnyTransition {
        let transition = AnyTransition.move(edge: .bottom)
            .combined(with: .opacity)
        return transition
    }
}

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