如何通过拖动在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中重新排列视图的主要内容,如果未能解决你的问题,请参考以下文章