When dragging a rectangle from the upper HStack (red rectangle) to the lower HStack, the dragged rectangle goes behind the views of the lower HStack, despite adjusting the zIndex with (.zIndex(isDragging ? 1.0 : 0.0)
). I don’t want to use arbitrary zIndex values like 10 or 100. I need a solution that logically adjusts the zIndex to ensure the dragged view stays on top without hardcoding unnecessary values.
import SwiftUI
struct ContentView: View {
@State private var array1: [CustomType] = [CustomType(value: 1, color: .red), CustomType(value: 2, color: .red), CustomType(value: 3, color: .red)]
@State private var array2: [CustomType] = [CustomType(value: 4, color: .blue), CustomType(value: 5, color: .blue), CustomType(value: 6, color: .blue)]
var body: some View {
VStack {
Spacer()
MyHstackView(array: $array1)
Spacer()
MyHstackView(array: $array2)
Spacer()
}
.padding()
}
}
struct MyHstackView: View {
@Binding var array: [CustomType]
var body: some View {
HStack {
ForEach(array) { item in
RectangleView(customType: item)
}
}
.padding()
.background(Rectangle().strokeBorder(.black, lineWidth: 1.0))
.background(Color.yellow)
}
}
struct RectangleView: View {
let customType: CustomType
@State private var currentOffset: CGSize = CGSize()
@State private var lastOffset: CGSize = CGSize()
@State private var isDragging: Bool = Bool()
var body: some View {
Rectangle()
.fill(customType.color)
.frame(width: 100.0, height: 100.0)
.overlay(Text(String(describing: customType.value)).font(.body.bold().monospaced()))
.overlay(Rectangle().strokeBorder(.black, lineWidth: 1.0))
.zIndex(isDragging ? 1.0 : 0.0)
.offset(currentOffset)
.gesture(dragGesture)
}
private var dragGesture: some Gesture {
DragGesture(minimumDistance: .zero, coordinateSpace: .local)
.onChanged { gestureValue in
isDragging = true
currentOffset = CGSize(
width: gestureValue.translation.width + lastOffset.width,
height: gestureValue.translation.height + lastOffset.height
)
}
.onEnded { gestureValue in
lastOffset = currentOffset
isDragging = false
}
}
}
struct CustomType: Identifiable {
init(value: Int, color: Color) {
self.value = value
self.color = color
}
let id: UUID = UUID()
var value: Int
var color: Color
}