admin管理员组文章数量:1405112
I'm trying to drag a group of elements and I want the element to be on top of all other elements in the group when I drag it. I'm trying to change the zIndex of the dragged element but for some reason it doesn't work... Maybe someone who knows this stuff can point out my mistake
struct DragShapesView: View {
var body: some View {
let layout = [GridItem(), GridItem()]
LazyHGrid(rows: layout, spacing: 15) {
ForEach(1..<5) { i in
Circle()
.frame(width: 50, height: 50)
.overlay {
Text(String(i))
.font(.evolventaBold(25))
.foregroundColor(.white)
}
.draggable(
onChanged: { location in
},
onEnded: {
}
)
}
}
}
}
modifier draggable
is:
struct Draggable: ViewModifier {
@State private var location: CGPoint = .zero
@State private var offset: CGSize = .zero
@State private var zIndex: Double = 0
var onChanged: ((CGPoint) -> Void)?
var onEnded: (() -> Void)?
func body(content: Content) -> some View {
content
.zIndex(zIndex)
.offset(offset)
.gesture(
DragGesture(coordinateSpace: .global)
.onChanged { value in
zIndex = Double.infinity
offset = value.translation
onChanged?(value.location)
}
.onEnded { _ in
zIndex = .zero
offset = .zero
onEnded?()
}
)
}
}
extension View {
func draggable(onChanged: ((CGPoint) -> Void)?, onEnded: (() -> Void)?) -> some View {
self.modifier(Draggable(onChanged: onChanged, onEnded: onEnded))
}
}
I'm trying to drag a group of elements and I want the element to be on top of all other elements in the group when I drag it. I'm trying to change the zIndex of the dragged element but for some reason it doesn't work... Maybe someone who knows this stuff can point out my mistake
struct DragShapesView: View {
var body: some View {
let layout = [GridItem(), GridItem()]
LazyHGrid(rows: layout, spacing: 15) {
ForEach(1..<5) { i in
Circle()
.frame(width: 50, height: 50)
.overlay {
Text(String(i))
.font(.evolventaBold(25))
.foregroundColor(.white)
}
.draggable(
onChanged: { location in
},
onEnded: {
}
)
}
}
}
}
modifier draggable
is:
struct Draggable: ViewModifier {
@State private var location: CGPoint = .zero
@State private var offset: CGSize = .zero
@State private var zIndex: Double = 0
var onChanged: ((CGPoint) -> Void)?
var onEnded: (() -> Void)?
func body(content: Content) -> some View {
content
.zIndex(zIndex)
.offset(offset)
.gesture(
DragGesture(coordinateSpace: .global)
.onChanged { value in
zIndex = Double.infinity
offset = value.translation
onChanged?(value.location)
}
.onEnded { _ in
zIndex = .zero
offset = .zero
onEnded?()
}
)
}
}
extension View {
func draggable(onChanged: ((CGPoint) -> Void)?, onEnded: (() -> Void)?) -> some View {
self.modifier(Draggable(onChanged: onChanged, onEnded: onEnded))
}
}
Share
Improve this question
edited Mar 23 at 9:58
Benzy Neez
23.5k3 gold badges15 silver badges44 bronze badges
asked Mar 22 at 22:00
Alex BroAlex Bro
1117 bronze badges
0
1 Answer
Reset to default 1Unfortunately, changing the zIndex
of items in a lazy grid does not work well.
- One way to solve is to set an id on the
LazyHGrid
based on the item being dragged. This is demonstrated in the answers to LazyVGrid is not redrawn on .id(). This would probably mean, passing a binding toDraggable
so that it can be updated with the id of the item being dragged. - Alternatively,
.matchedGeometryEffect
can be used. This is demonstrated in the answer to Cant change zIndex of LazyVGrid element to bring it to the front with animation (it was my answer).
To use .matchedGeometryEffect
in your case, the following changes are needed:
- Build the grid using hidden placeholders for the items.
- The visible items are shown together in an overlay.
- The visible items are matched to the placeholders using their indices as ids.
Here is an updated version of the example to show it working:
struct DragShapesView: View {
private let colors: [Color] = [.red, .orange, .yellow, .green]
private let layout = [GridItem(), GridItem()]
@Namespace private var ns
var body: some View {
LazyHGrid(rows: layout, spacing: 15) {
ForEach(Array(colors.enumerated()), id: \.offset) { i, _ in
Color.clear
.frame(width: 100, height: 100)
.matchedGeometryEffect(id: i, in: ns)
}
}
.overlay {
ForEach(Array(colors.enumerated()), id: \.offset) { i, color in
Circle()
.fill(color)
.overlay {
Text(String(i))
.font(.title) // .evolventaBold(25)
.foregroundStyle(.white)
}
.draggable(
onChanged: { location in },
onEnded: {}
)
.matchedGeometryEffect(id: i, in: ns, isSource: false)
}
}
}
}
本文标签: iosIncorrect zindex calculation when draggingStack Overflow
版权声明:本文标题:ios - Incorrect zindex calculation when dragging - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744302323a2599640.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论