【问题标题】:How to drag across Views in a LazyVGrid with GeometryReader?如何使用 GeometryReader 在 LazyVGrid 中拖动视图?
【发布时间】:2020-12-12 16:59:30
【问题描述】:

我想拖动网格中的矩形并更改它们的颜色。这段代码几乎可以工作,但这并不总是正确的响应矩形:它的行为相当随机。有什么提示吗?

import SwiftUI


struct ContentView: View {
    let data = (0...3)
    
    @State private var colors: [Color] = Array(repeating: Color.gray, count: 4)
    @State private var rect = [CGRect]()
    
    var columns: [GridItem] =
        Array(repeating: .init(.fixed(70), spacing: 1), count: 2)
    
    var body: some View {
        LazyVGrid(columns: columns, spacing: 1) {
            ForEach(data, id: \.self) { item in
                Rectangle()
                    .fill(colors[item])
                    .frame(width: 70, height: 70)
                    .overlay(
                        GeometryReader{ geo in
                            Color.clear
                                .onAppear {
                                    rect.insert(geo.frame(in: .global), at: rect.endIndex)
                                }
                        }
                    )
            }
        }
        .gesture(DragGesture(minimumDistance: 0, coordinateSpace: .global)
                .onChanged({ (value) in
                    if let match = rect.firstIndex(where: { $0.contains(value.location) }) {
                        colors[match] = Color.red
                    }
                })
        )
    }
}

【问题讨论】:

    标签: swiftui geometryreader lazyvgrid


    【解决方案1】:

    如果我正确理解了您的目标,这里是固定变体(稍作修改以避免重复硬编码)。

    使用 Xcode 12.1 / iOS 14.1 测试

    struct ContentView: View {
        let data = (0...3)
        
        @State private var colors: [Color]
        @State private var rect: [CGRect]
        
        init() {
            _colors = State(initialValue: Array(repeating: .gray, count: data.count))
            _rect = State(initialValue: Array(repeating: .zero, count: data.count))
        }
        
        var columns: [GridItem] =
            Array(repeating: .init(.fixed(70), spacing: 1), count: 2)
        
        var body: some View {
            LazyVGrid(columns: columns, spacing: 1) {
                ForEach(data, id: \.self) { item in
                    Rectangle()
                        .fill(colors[item])
                        .frame(width: 70, height: 70)
                        .overlay(
                            GeometryReader{ geo in
                                Color.clear
                                    .onAppear {
                                        rect[item] = geo.frame(in: .global)
                                    }
                            }
                        )
                }
            }
            .gesture(DragGesture(minimumDistance: 0, coordinateSpace: .global)
                            .onChanged({ (value) in
                                if let match = rect.firstIndex(where: { $0.contains(value.location) }) {
                                    colors[match] = Color.red
                                }
                            })
            )
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-10
      • 1970-01-01
      相关资源
      最近更新 更多