【问题标题】:How to clip a view while using a SwiftUI .move transition / animation如何在使用 SwiftUI .move 过渡/动画时剪辑视图
【发布时间】:2022-07-17 19:34:29
【问题描述】:

我试图在一个视图中制作动画,让它看起来好像是从另一个视图打开的一种抽屉。这一切都很好,除非第一个视图不是不透明的。您似乎可以在动画开始动画的那一刻看到动画视图。有没有办法剪辑这个,看起来视图是从底部视图的顶部开始增长的?

即使没有不透明度,如果您从中制作动画的位置没有被覆盖(在第二个 gif 中演示),这也是一个问题

示例代码:

struct ContentView: View {
    @State private var showingSecondView: Bool = false
    

    var body: some View {
        VStack(spacing: 0) {
            Spacer()
            if showingSecondView {
                ZStack {
                    Color.green.opacity(0.25)
                    Text("Second View")
                }
                .frame(width: 300, height: 300)
                .transition(.move(edge: .bottom))
            }
            ZStack {
                Color.black.opacity(1)
                Text("First View")
            }
            .frame(width: 300, height: 300)
            Button("Animate In / Out") {
                showingSecondView.toggle()
            }
            .padding()
        }
        .animation(.easeInOut, value: showingSecondView)
      }
}

【问题讨论】:

    标签: ios swift swiftui swiftui-animation


    【解决方案1】:

    可以通过裁剪“抽屉”的确切容器来做到这一点。这是可能的方法的演示。

    使用 Xcode 13.2 / iOS 15.2 进行测试(模拟器慢速动画已开启以获得更好的演示)

    var body: some View {
        VStack(spacing: 0) {
            Spacer()
            VStack {
                if showingSecondView {
                    ZStack {
                        Color.green.opacity(0.25)
                        Text("Second View")
                    }
                    .transition(.move(edge: .bottom))
                } else {
                    Color.clear // << replacement for transition visibility
                }
            }
            .frame(width: 300, height: 300)
            .animation(.easeInOut, value: showingSecondView)  // << animate drawer !!
            .clipped()            // << clip drawer area
            
            ZStack {
                Color.black.opacity(0.2)
                Text("First View")
            }
            .frame(width: 300, height: 300)
    
            Button("Animate In / Out") {
                showingSecondView.toggle()
            }
            .padding()
        }
    }
    

    backup

    【讨论】:

    • 可爱。像往常一样使用 SwiftUI,我希望我能理解它为什么起作用。
    【解决方案2】:

    这里给你一个方法:

     struct ContentView: View {
        
        @State private var isSecondViewPresented: Bool = false
    
        var body: some View {
            
            VStack(spacing: 0) {
                Spacer()
                
                ZStack {
                    Color.green.opacity(0.25).cornerRadius(20)
                    Text("Second View")
                }
                .frame(width: 300, height: 300)
                .offset(y: isSecondViewPresented ? 0 : 300)
                .clipShape(RoundedRectangle(cornerRadius: 20))
                
                
                ZStack {
                    Color.black.opacity(0.1).cornerRadius(20)
                    Text("First View")
                }
                .frame(width: 300, height: 150)
                
                Button("Animate In / Out") {
                    isSecondViewPresented.toggle()
                }
                .padding()
            }
            .animation(.easeInOut, value: isSecondViewPresented)
            
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2015-06-15
      • 2020-03-17
      • 2020-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多