1

我使用matchedGeometryEffectTapGesture来交换带有动画过渡的两个元素。

动画按预期工作,但我想在动画期间更改元素的zIndex

我从这个例子开始:https
://www.appcoda.com/matchedgeometryeffect/ 并根据我的需要进行了调整:

struct MyView: View {
    @State var colors = [Color.orange,Color.red,Color.yellow,Color.pink,Color.blue]
    @State var target = Int.random(in: 0..<4)
    @Namespace private var animationNamespace : Namespace.ID
    
    var body: some View {
        let columns: [GridItem] = Array(repeating: .init(.fixed(80)), count: 2)
        LazyVGrid(columns: columns, spacing: 5){
            ForEach(Array(self.colors.enumerated()), id: \.self.element) { indexedColor in
                Element(color: indexedColor.element, animationNamespace: self.animationNamespace, action: {
                    self.colors.swapAt(target, indexedColor.offset)
                    target = Int.random(in: 0..<4)
                })
            }
        }.animation(.linear)
    }
}

struct Element: View {
    let color : Color
    let animationNamespace : Namespace.ID
    let action: () -> Void

    
    var body: some View {
        Circle()
            .fill(color)
            .frame(width: 80, height: 80)
            .matchedGeometryEffect(id: color, in: animationNamespace)
            .onTapGesture {
                action()
            }
    }
}

动画

我希望动画元素始终位于其他元素之上。
zIndex 必须在动画结束时重置

这可以通过使用TapGesture吗?

Xcode 版本 12.0.1 (12A7300)
iOS 14.0

4

1 回答 1

0

可以将点击的点放在顶层..我在这里更改了您的代码..

struct ContentView: View {
    @State var colors = [Color.orange,Color.red,Color.yellow,Color.pink,Color.blue]
    @Namespace private var animationNamespace : Namespace.ID
    
    var body: some View {
        HStack{
            ForEach(Array(self.colors.enumerated()), id: \.self.element) { indexedColor in
                Element(color: indexedColor.element, animationNamespace: self.animationNamespace, order: indexedColor.0, action: {
                    self.colors.swapAt(0, indexedColor.offset)
                })
            }
        }.animation(.linear)
    }
}

struct Element: View {
    let color : Color
    let animationNamespace : Namespace.ID
    var order : Int
    let action: () -> Void
    
    var body: some View {
        Circle()
            .fill(color)
            .frame(width: 80, height: 80)
            .matchedGeometryEffect(id: color, in: animationNamespace)
            .zIndex(Double(5-order))
            .onTapGesture {
                action()
            }
    }
}

基本上我只是根据它们的位置为每个元素放置 zIndex。这意味着第一个点将具有最高的 zIndex。如果你改变位置,被点击的那个会得到最高的 zIndex 并且会相互重叠。我认为不可能将另一个放在顶部,因为它会得到另一个 zIndex,它是较低的。

于 2020-10-31T14:48:12.853 回答