具有两个视图的SwiftUI Card Flip动画,其中一个视图嵌入到Stack中 [英] SwiftUI Card Flip animation with two views, one of which is embedded within a Stack

查看:106
本文介绍了具有两个视图的SwiftUI Card Flip动画,其中一个视图嵌入到Stack中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在两个视图之间创建卡片翻转"动画:

I'm trying to create a 'card flip' animation between two Views:

  • 视图'A'是LazyVGrid
  • 中的CardView
  • 视图'B'是自定义模式叠加视图

LazyVGrid和视图'B'一起在ZStack

The LazyVGrid and View 'B' are together in a ZStack

具体来说,ContentView的组织方式如下:

Specifically, the ContentView is organized like so:

var body: some View {
    ZStack {
        NavigationView {
            ScrollView {
                LazyVGrid(columns: columns, spacing: 10) {
                    ForEach(model.events, id: \.self) { event in
                        SmallCardView(event: event)
                            .opacity(!showModal || event != modifiableEvent ? 1.0 : 0.0)
                    }
                }
            }
        }
        .brightness(self.showModal ? -0.1 : 0)
        .blur(radius: self.showModal ? 16 : 0)
        
        if self.showModal {
            AddEventView(
                showModal: $showModal,
                existingEvent: modifiableEvent,
            )
            .opacity(showModal ? 1.0 : 0.0)
            .padding(.horizontal, 16)
        }            
    }
}

我遇到了这篇 SO帖子,答案似乎很有希望,但是,如果其中一个视图位于Stack/Grid中,则不会考虑答案,这对我来说就是这种情况.因此,我的问题是,如果其中一个视图确实嵌入在Stack或Grid中,我如何才能调整链接的解决方案,使其按预期工作.

I came across this SO post, and the answer seems super promising, however the answer doesn't take into account if one of the views is within a Stack / Grid, which is the case for me. So, my question is, how can I adapt the linked solution so that it works as expected if one of the views is indeed embedded within a Stack or a Grid.

编辑:另外要注意的是,视图的大小和位置是不同的

Edit: Another thing to note is that the size and position of the Views are different

我尝试在ZStackSmallCardView中都添加.modifier(FlipEffect(flipped: $showModal, angle: animate3d ? 180 : 0, axis: (x: 0, y: 1))),但是均未产生预期的结果.

I tried adding .modifier(FlipEffect(flipped: $showModal, angle: animate3d ? 180 : 0, axis: (x: 0, y: 1))) to both the ZStack and SmallCardView, however neither yielded the expected results.

谢谢!

为清楚起见,我想在这两个视图之间以卡片翻转样式制作动画:

For clarity, I want to animate in a card flip style between these two views:

推荐答案

这个非常简单的结构应该可以帮助您了解所需的必要结构:

This really simple construct should help you understand the necessary structure needed:

为此目的有一个特定的rotation3DEffect修饰符.

There is a specific rotation3DEffect modifier for this purpose.

struct ContentView: View {
    
    // What is the current status
    @State var flipped: Bool = false
    
    // Whats the initial "flip" degree
    @State var degrees: Double = 180.0
    
    @State var width: CGFloat = 200
    @State var height: CGFloat = 300
    
    var body: some View {
        ZStack {
            if flipped {
                //Cart Back
                CardBack(width: self.$width, height: self.$height)
                  
            } else {
                //Cart front

                CardFront(width: self.$width, height: self.$height)
                 
            }
        }//Styling
        .background(Color.gray)
        .cornerRadius(20)
        .rotation3DEffect(.degrees(degrees), axis: (x: 0, y: 1, z: 0))
            
            // When tapped turn it around
        .onTapGesture {
            if self.flipped {
                self.flipped = false
                withAnimation {
                    self.degrees += 180
                    self.width = 200 // add other animated stuff here
                    self.height = 300
                }
            } else {
                self.flipped = true
                withAnimation {
                    self.degrees -= 180
                    self.width = 300 // add other animated stuff here
                    self.height = 500
                }
            }
        }
    }
}

struct CardBack: View {
    
    @Binding var width: CGFloat
    @Binding var height: CGFloat
    
    var body: some View {
        Rectangle().foregroundColor(Color.red).frame(width: self.width, height: self.height).overlay(Text("Back"))
    }
}

struct CardFront: View {
    
    @Binding var width: CGFloat
    @Binding var height: CGFloat
    
    var body: some View {
        Rectangle().foregroundColor(Color.blue).frame(width: self.width, height: self.height).overlay(Text("Front"))
    }
}

这将产生以下视图:

这篇关于具有两个视图的SwiftUI Card Flip动画,其中一个视图嵌入到Stack中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆