0
votes

SWIFTUI Carte Flip Animation avec deux vues, dont l'une est intégrée dans une pile

J'essaie de créer une animation d'une "carte" entre deux vues:

  • View 'A' est un CardView dans un Lazyvgrid
  • Voir 'B' est une vue sur la superposition modale personnalisée

    Le Lazyvgrid et la vue 'B' sont ensemble dans un zstack

    spécifiquement, le contentview est organisé comme: xxx

    je suis tombé sur Ce SO POST, et la réponse semble super prometteuse, mais la réponse ne prend pas en compte si l'une des vues se situe dans une pile / une grille, ce qui est le cas pour moi. Donc, ma question est, comment puis-je adapter la solution liée de sorte qu'elle fonctionne comme prévu si l'une des vues est effectivement intégrée dans une pile ou une grille.

    modifier : Une autre chose à noter est que la taille et la position des vues sont différentes

    J'ai essayé d'ajouter .MOdifier (Flipeffect (flipped: $ showmodal, angle: animate3d? 180: 0, axe: (x : 0, Y: 1)))) à la fois sur le zstack et smallcardview , cependant n'a donné que les résultats attendus.

    merci!

    éditer: Pour plus de clarté, je veux animer un style de retournement de carte entre ces deux vues:

     Entrez la description de l'image ici

     Entrez la description de l'image ici


0 commentaires

3 Réponses :


4
votes

Cette construction vraiment simple devrait vous aider à comprendre la structure nécessaire nécessaire:

Il existe un modificateur spécifique Rotation3Deffecte code> à cet effet. P>

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


3 commentaires

Cela ne fonctionne pas vraiment bien lorsque les deux vues sont différentes tailles et positions, ce qui, dans mon cas, ils sont


Je dois admettre que je ne vois pas vraiment votre problème. Ceci est une maquette qui devrait vous aider à comprendre le concept. Non implémenter un produit fini. Ajoutez simplement d'autres attributs et modifiez-les également dans la canapeuse. J'ai ajouté l'exemple avec la largeur et la hauteur des cartes.


Toutes mes excuses pour mon manque de clarté. Spécifiquement, je veux une vue à l'intérieur d'une grille / une pile et de l'autre vue sur le dessus de cette pile (c'est-à-dire, déplacez la vue à l'intérieur de la grille surtout de la grille entière), plutôt que juste un seul Vu la vue de retour d'avant en arrière. Ainsi, l'animation devra se déplacer de l'intérieur de la grille à l'ex-un exemple, voir l'animation d'édition pour les widgets IOS 14



2
votes

Pour expliquer la réponse, je veux expliquer ce que vous devez atteindre. Vous voulez que votre vue / EditView aime l'animer quand il est en avant. Cela signifie que nous devons utiliser le modificateur code> transition code>.

Maintenant que le modificateur de transition intégré d'Apple utilise de nombreuses transitions comme Easein, Out, etc. et qui n'a pas cette transition, nous devons donc créer une transition personnalisée pour atteindre il. Permet de faire cela en premier. P> xxx pré>

Maintenant, car nous avons la transition personnalisée, nous devons appliquer à cette vue. P>

Donc, c'est donc le code que vous considérez. Avoir une vue de carte. p> xxx pré>

La vue parent comme dans votre cas votre vue où vous cliquez sur Modifier P>

Ajouter cette P>

  ParentView() //your view

  .matchedGeometryEffect(id: "popup", in: animation)


0 commentaires

3
votes

Je n'ai jamais réussi à le faire fonctionner sans problèmes lorsque les cartes sont dans une fazhavgrid en utilisant .MatchDeDreDryEffect (). Il s'agit donc de la solution plutôt désordonnée abusant des décalages et de la mise à l'échelle que j'utilise dans mon projet: xxx

Animation de la carte passe à Vgrid


1 commentaires

Merci beaucoup de partager cet exemple et la visualisation GIF. Le code permet de comprendre et de créer mon propre code en fonction de cette façon de travailler.