首页 > 解决方案 > SwiftUI 过渡(.asymmetric..)不适用于偏移

问题描述

我正在开发一套游戏,我希望卡片通过 .transition(.asymmetric(insertion: .offset(x: 100.0, y: 100.0), remove: .offset( x: 100.0, y: 100.0))) 命令。

实际上,卡片通过完全偏移离开屏幕,但它们只是在程序开始时“出现”而不是实际离开屏幕。

应用视频

如您所见,被选中并“匹配”的卡片使用 .transition(offset) 飞离屏幕。我希望看到卡片在游戏开始时以同样的方式从屏幕外飞入。

@ViewBuilder
private func body (for size: CGSize) -> some View{
    let paddingAllSidesInCards:CGFloat = 8
    if card.isFaceUp || !card.isMatched
    {
        GeometryReader { geo in
            VStack(alignment: .center) {
                Group
                {
                        
                        ForEach( 0..<card.numberofsymbols)
                        { numberofcards in
                            
                            let cardshape = cardViewModelShape.getShape(Card: card, size: size, numberOfCards: card.numberofsymbols)
                                cardshape
                                .transition(.identity)
                                .aspectRatio(1,contentMode: .fit)
                                .frame(minWidth: 20, idealWidth: 100, maxWidth: .infinity, minHeight: 20, idealHeight: 100, maxHeight: .infinity, alignment: .center)
                                .scaleEffect(card.isSelected ? 1.2 : 1)
                                .animation(.spring(response: (card.isSelected ? 1:0), dampingFraction: 0.1, blendDuration: .infinity))
                        }.padding(paddingAllSidesInCards)
                    //Implicit animation - with linear execution
                }
            }
            .cardify(isFaceUp: card.isFaceUp)
        }
        .transition(.asymmetric(insertion: .offset(x: 100.0, y: 100.0), removal: .offset(x: 100.0, y: 100.0)))
   

    }
}

我做错了什么或忘记了一点 - 我尝试了 onAppear() 运算符,但它不起作用。

谢谢你的帮助!

PS:如果您想查看完整的源代码,可以查看存储库:

链接 SetGame 回购

标签: swiftswiftui

解决方案


提供的代码是不可测试的,所以只是一个想法 - 尝试将所有内容包装到容器中(它需要作为占位符来动画转换),比如

@ViewBuilder
private func body (for size: CGSize) -> some View{
    let paddingAllSidesInCards:CGFloat = 8

    VStack // << this one !!
    {
      if card.isFaceUp || !card.isMatched
      {
        GeometryReader { geo in
            VStack(alignment: .center) {

               // .. other code
            }
            .cardify(isFaceUp: card.isFaceUp)
        }
        .transition(.asymmetric(insertion: .offset(x: 100.0, y: 100.0), removal: .offset(x: 100.0, y: 100.0)))
      }
   }
   .animation(.default) // << use any you want
}

推荐阅读