【问题标题】:View don't disappear with the way it should视图不会以应有的方式消失
【发布时间】:2021-01-04 19:04:30
【问题描述】:

我正在尝试通过漂亮流畅的动画使黄色视图从底部和顶部消失。 (滑动/移动到顶部/底部+渐变并保持中间视图占据整个空间) 这是我现在的状态,一切都不是顺滑漂亮哈哈。但它有效。

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,我能够以更好的状态进步。 但现在我有一种生涩的动画。 有什么想法吗?

【问题讨论】:

  • 如果您尝试将两个黄色矩形都固定并移动红色矩形?这样你就可以去掉黄色矩形,这就是给你带来麻烦的原因

标签: swift animation swiftui ios14


【解决方案1】:

我可能已经为您找到了解决方案:

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

【讨论】:

    【解决方案2】:

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

    要做到这一点的修饰符是.zIndex()

    【讨论】:

    • 我猜zIndex(-1) 在中间视图上也很好用吧?
    • 是的,也可以这样工作。非常感谢@Andrew!
    • 在途中,我想添加一个带有淡入淡出的额外过渡。 .combined(with: .opacity) 似乎破坏了动画,您是否也知道如何修复该动画?
    【解决方案3】:

    更简单的解决方案

    结构测试:查看 {

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

    }

    【讨论】:

    • 不确定你的代码和帖子的最终目标之间的关系:/ 我试图有一个顶部/中间/底部视图,顶部/底部可以通过按中间隐藏一。用例:音频播放器 - 中间是任何图片,顶部包含音乐名称等,底部包含播放/暂停按钮等。
    • 好的!想到另一个用途
    • 感谢您帮助我!我更新了原始帖子,希望它更具可读性:D
    猜你喜欢
    • 2012-08-11
    • 2014-01-30
    • 1970-01-01
    • 2014-07-08
    • 1970-01-01
    • 2020-07-01
    • 1970-01-01
    • 2013-09-03
    • 1970-01-01
    相关资源
    最近更新 更多