如何根据GeometryReader绘制项目网格



我正在学习SwiftUI,作为当前项目的最终目标,我想绘制bezier路径,每个路径都在自己的层上,可以在交互时进行修改(例如,在点击时更改颜色(,还可以在放大手势时调整整个组的大小。

出于测试目的,我想创建一个圆形正方形的网格(将来将被任意的贝塞尔路径取代(,并在屏幕上显示网格。

代码如下:

import SwiftUI
struct PathView: View {
@State var scale: CGFloat = 1.0
var body: some View {
let overlayContent = VStack(alignment: .leading) {
Text("Hello")
}
.padding()
GeometryReader {
geometry in
let rectangles: [GridItem] = getSquareGrid(width: geometry.size.width, height: geometry.size.height, count: 10)
var rects = ZStack {
ForEach(rectangles) { rectangle in
RoundedRectangle(cornerRadius: rectangle.cornerRadius, style: /*@START_MENU_TOKEN@*/.continuous/*@END_MENU_TOKEN@*/)
.fill(rectangle.color)
.frame(width: rectangle.size, height: rectangle.size, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
.offset(x: rectangle.offsetX, y: rectangle.offsetY)
.onTapGesture {
print("rectangle (rectangle.id) tapped")
}
}
}.scaledToFit()
.scaleEffect(scale)
.gesture(MagnificationGesture()
.onChanged({ (scale) in
self.scale = scale.magnitude
})
.onEnded({ (scaleFinal) in
self.scale = scaleFinal
}))
return rects.drawingGroup()
.overlay(overlayContent, alignment: .topLeading)
}
}
}
struct GridItem: Identifiable {
let size: CGFloat
let offsetX: CGFloat
let offsetY: CGFloat
let cornerRadius: CGFloat
let color: Color
let id = UUID()

init(size: CGFloat, offsetX: CGFloat, offsetY: CGFloat, cornerRadius: CGFloat, color: Color) {
self.size = size
self.offsetX = offsetX
self.offsetY = offsetY
self.cornerRadius = cornerRadius
self.color = color
}
}
func getSquareGrid(width: CGFloat, height: CGFloat, count: Int) -> [GridItem] {
var rectangleArray: [GridItem] = []
let size = min(width, height)
let rectangleSize = round(size/CGFloat(count))
for row in 0...count - 1 {
for column in 0...count - 1 {
let rect = GridItem(size: rectangleSize, offsetX: CGFloat(column) * rectangleSize, offsetY: CGFloat(row) * rectangleSize, cornerRadius: 25.0, color: Color.red)

rectangleArray.append(rect)
}
}
return rectangleArray
}
struct PathView_Previews: PreviewProvider {
static var previews: some View {
PathView()
}
}

由于以下错误,此版本无法生成:

无法推断复杂闭包返回类型;将显式类型添加到消除的歧义

为了获得可用的空间维度,我使用GeometryReader并将其维度传递给函数getSquareGrid((。

有人知道如何在这种情况下适当地使用GeometryReader吗?或者无论如何都知道如何获得尺寸,以便用生成的网格填充可用的屏幕?

由于缺少依赖项,代码不可测试,但请尝试以下

let drawnRects = rects.drawingGroup()
return drawnRects
.overlay(overlayContent, alignment: .topLeading)

替换为

rects.drawingGroup()
.overlay(overlayContent, alignment: .topLeading)

更新:实际上,如果我只用Text("test")替换overlayContent,它就很好地满足了

最新更新