如何通过拖动在SwiftUI ZStack中重新排列视图

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过拖动在SwiftUI ZStack中重新排列视图相关的知识,希望对你有一定的参考价值。

如何将视图在ZStack中的位置拖动到另一个视图的上方或下方(例如,在这种情况下,如何通过在另一个卡的上方或下方拖动一个卡来移动卡的顺序来重新排列卡在卡组中的顺序?将卡片拖到卡组中该卡片的后面或前面)。

[我想让卡在堆栈中上下拖动时更改索引,并在拖动时流畅地出现在堆栈中的每张卡后面,并保持在鼠标上方。

我认为这与更改struct CardView: View中的ZStack顺序并通过评估卡已拖动的量(也许通过查看self.offset值)从DragGesture().onChanged内部更新位置有关,但我没有能够找出如何以可靠的方式执行此操作。

这是我现在拥有的:

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLnN0YWNrLmltZ3VyLmNvbS9qa1E5ai5naWYifQ==” width =“ 300” alt =“绘图”>

代码:

import SwiftUI

let cardSpace:CGFloat = 10

struct ContentView: View {
    @State var cardColors: [Color] = [.orange, .green, .yellow, .purple, .red, .orange, .green, .yellow, .purple]
    var body: some View {
            HStack {
                VStack {
                    CardView(colors: self.$cardColors)
                }
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .position(x: 370, y: 300)
    }
}

struct CardView: View {
    @State var offset = CGSize.zero
    @State var dragging:Bool = false
    @State var tapped:Bool = false
    @State var tappedLocation:Int = -1
    @Binding var colors: [Color]
    @State var locationDragged:Int = -1
    var body: some View {
        GeometryReader { reader in
            ZStack {
                ForEach(0..<self.colors.count, id: .self) { i in
                    ColorCard(reader:reader, i:i, colors: self.$colors, offset: self.$offset, tappedLocation: self.$tappedLocation, locationDragged:self.$locationDragged, tapped: self.$tapped, dragging: self.$dragging)
                }
            }
        }
        .animation(.spring())
    }
}

struct ColorCard: View {
    var reader: GeometryProxy
    var i:Int
    @State var offsetHeightBeforeDragStarted: Int = 0
    @Binding var colors: [Color]
    @Binding var offset: CGSize
    @Binding var tappedLocation:Int
    @Binding var locationDragged:Int
    @Binding var tapped:Bool
    @Binding var dragging:Bool
    var body: some View {
        VStack {
            Group {
            VStack {
                self.colors[i]
            }
            .frame(width: 300, height: 400)
            .cornerRadius(20).shadow(radius: 20)
            .offset(
                x: (self.locationDragged == i) ? CGFloat(i) * self.offset.width / 14
                    : 0,
                y: (self.locationDragged == i) ? CGFloat(i) * self.offset.height / 4
                    : 0
            )
            .offset(
                x: (self.tapped && self.tappedLocation != i) ? 100 : 0,
                y: (self.tapped && self.tappedLocation != i) ? 0 : 0
            )
            .position(x: reader.size.width / 2, y: (self.tapped && self.tappedLocation == i) ? -(cardSpace * CGFloat(i)) + 0 : reader.size.height / 2)
            }
                .rotationEffect(
                    (i % 2 == 0) ? .degrees(-0.2 * Double(arc4random_uniform(15)+1) ) : .degrees(0.2 * Double(arc4random_uniform(15)+1) )
                )

                .onTapGesture() { //Show the card
                    self.tapped.toggle()
                    self.tappedLocation = self.i
            }

            .gesture(
                DragGesture()
                    .onChanged { gesture in
                        self.locationDragged = self.i
                        self.offset = gesture.translation
                        self.dragging = true
                }
                .onEnded { _ in
                    self.locationDragged = -1 //Reset
                    self.offset = .zero
                    self.dragging = false
                    self.tapped = false //enable drag to dismiss
                    self.offsetHeightBeforeDragStarted = Int(self.offset.height)
                }
            )
        }.offset(y: (cardSpace * CGFloat(i)))
    }
}
答案

只是个主意(因为需要重新考虑/重新编码您的解决方案)。如果您要重新订购,则需要使用/修改卡zIndex,因此需要将其存储在某个地方。

因此,不是直接使用颜色作为模型,而是需要更明确的模型对象

以上是关于如何通过拖动在SwiftUI ZStack中重新排列视图的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI,ScrollView 在 ZStack 中向上推送 VStack 图像

SwiftUI 在 Zstack 中隐藏文本输入?

SwiftUI 在 ZStack 中不居中

SwiftUI动画视图出现在ZStack中时出现奇怪的过渡

带有渐变的SwiftUI ScrollView文本

如何使用 SwiftUI 将 Stacks 固定在顶部和底部