如何创建仅显示线条网格的自定义视图?
How can I create a custom view that only displays a grid of lines?
我正在制作一个测试应用程序,看看使用 Swift 是什么感觉UI,我希望我的测试应用程序有一个自定义视图,它是一个垂直线网格,间距指定为状态变量。
但是,我不知道如何在似乎没有自定义绘图方法的 UI 系统中执行此操作。
import SwiftUI
struct GridBackgroundView : View {
@State var horizontalSpacing: CGFloat = 48
@State var verticalSpacing: CGFloat = 48
@State var anchor: Anchor<CGPoint>.Source = .center
var numberOfHorizontalGridLines: UInt {
return // Something?
}
var numberOfVerticalGridLines: UInt {
return // Something?
}
var body: some View {
Group {
ForEach(0 ... numberOfHorizontalGridLines) { _ in
// Something?
}
ForEach(0 ... numberOfVerticalGridLines) { _ in
// Something?
}
}
}
}
#if DEBUG
struct GridView_Previews : PreviewProvider {
static var previews: some View {
GridBackgroundView()
}
}
#endif
我不知道在 // Something?
区域放什么。 SwiftUI 中没有内置线视图,我这辈子都不知道视图的宽度是多少(可能是因为那不是 Swift[=19] 中 View
的一部分=]?)
您可以通过组合垫片和分隔片来做到这一点
var body: some View {
ZStack {
HStack {
Spacer()
Rectangle().frame(width: 1)
Spacer()
Divider()
Spacer()
}
VStack {
Spacer()
Divider()
Spacer()
Divider()
Spacer()
}
}
}
您也可以使用 Rectangle() 代替 Divider() 并查看
https://developer.apple.com/tutorials/swiftui/drawing-paths-and-shapes
upd: 如果你需要一个单元格大小固定的网格,你可以使用 GeometryReader
来计算你的行数,并组织你的 ForEach
对应
var cellSize: CGFloat = 48
var body: some View {
GeometryReader { geometry in
ZStack {
HStack {
ForEach(0..<Int(geometry.size.width / self.cellSize)) { _ in
Spacer()
Divider()
}
Spacer().frame(width: geometry.size.width.truncatingRemainder(dividingBy: self.cellSize))
}
VStack {
ForEach(0..<Int(geometry.size.height / self.cellSize)) { _ in
Spacer()
Divider()
}
Spacer().frame(width: geometry.size.height.truncatingRemainder(dividingBy: self.cellSize))
}
}
}
}
您可以使用 SwiftUI
使用 Path
(Path Documentation, Tutorial)
进行自定义绘图
要绘制网格,您可以使用如下内容:
struct ContentView : View {
var horizontalSpacing: CGFloat = 48
var verticalSpacing: CGFloat = 48
var body: some View {
GeometryReader { geometry in
Path { path in
let numberOfHorizontalGridLines = Int(geometry.size.height / self.verticalSpacing)
let numberOfVerticalGridLines = Int(geometry.size.width / self.horizontalSpacing)
for index in 0...numberOfVerticalGridLines {
let vOffset: CGFloat = CGFloat(index) * self.horizontalSpacing
path.move(to: CGPoint(x: vOffset, y: 0))
path.addLine(to: CGPoint(x: vOffset, y: geometry.size.height))
}
for index in 0...numberOfHorizontalGridLines {
let hOffset: CGFloat = CGFloat(index) * self.verticalSpacing
path.move(to: CGPoint(x: 0, y: hOffset))
path.addLine(to: CGPoint(x: geometry.size.width, y: hOffset))
}
}
.stroke()
}
}
}
这可以通过 ZStack 实现,它允许您将其中的视图渲染在彼此之上。
ZStack {
HStack(spacing: horizontalSpacing) {
ForEach(0 ..< Int(numberOfVerticalGridLines)) { _ in
Rectangle().fill(Color.gray).frame(width: 1)
}
}
VStack(spacing: verticalSpacing) {
ForEach(0 ..< Int(numberOfHorizontalGridLines)) { _ in
Rectangle().fill(Color.gray).frame(height: 1)
}
}
}
为了使用 SwiftUI 使用路径绘制网格视图 Drawing Paths and Shapes
struct GridView: View {
let rows: CGFloat
let cols: CGFloat
let gridColor: Color
var body: some View {
GeometryReader { geometry in
let width = geometry.size.width
let height = geometry.size.height
let xSpacing = width / cols
let ySpacing = height / rows
Path { path in
for index in 0...Int(cols) {
let vOffset: CGFloat = CGFloat(index) * xSpacing
path.move(to: CGPoint(x: vOffset, y: 0))
path.addLine(to: CGPoint(x: vOffset, y: height))
}
for index in 0...Int(rows) {
let hOffset: CGFloat = CGFloat(index) * ySpacing
path.move(to: CGPoint(x: 0, y: hOffset))
path.addLine(to: CGPoint(x: width, y: hOffset))
}
}
.stroke(gridColor)
}
}
}
GridView(rows: 9.0, cols: 9.0, gridColor: .white)
我正在制作一个测试应用程序,看看使用 Swift 是什么感觉UI,我希望我的测试应用程序有一个自定义视图,它是一个垂直线网格,间距指定为状态变量。
但是,我不知道如何在似乎没有自定义绘图方法的 UI 系统中执行此操作。
import SwiftUI
struct GridBackgroundView : View {
@State var horizontalSpacing: CGFloat = 48
@State var verticalSpacing: CGFloat = 48
@State var anchor: Anchor<CGPoint>.Source = .center
var numberOfHorizontalGridLines: UInt {
return // Something?
}
var numberOfVerticalGridLines: UInt {
return // Something?
}
var body: some View {
Group {
ForEach(0 ... numberOfHorizontalGridLines) { _ in
// Something?
}
ForEach(0 ... numberOfVerticalGridLines) { _ in
// Something?
}
}
}
}
#if DEBUG
struct GridView_Previews : PreviewProvider {
static var previews: some View {
GridBackgroundView()
}
}
#endif
我不知道在 // Something?
区域放什么。 SwiftUI 中没有内置线视图,我这辈子都不知道视图的宽度是多少(可能是因为那不是 Swift[=19] 中 View
的一部分=]?)
您可以通过组合垫片和分隔片来做到这一点
var body: some View {
ZStack {
HStack {
Spacer()
Rectangle().frame(width: 1)
Spacer()
Divider()
Spacer()
}
VStack {
Spacer()
Divider()
Spacer()
Divider()
Spacer()
}
}
}
您也可以使用 Rectangle() 代替 Divider() 并查看 https://developer.apple.com/tutorials/swiftui/drawing-paths-and-shapes
upd: 如果你需要一个单元格大小固定的网格,你可以使用 GeometryReader
来计算你的行数,并组织你的 ForEach
对应
var cellSize: CGFloat = 48
var body: some View {
GeometryReader { geometry in
ZStack {
HStack {
ForEach(0..<Int(geometry.size.width / self.cellSize)) { _ in
Spacer()
Divider()
}
Spacer().frame(width: geometry.size.width.truncatingRemainder(dividingBy: self.cellSize))
}
VStack {
ForEach(0..<Int(geometry.size.height / self.cellSize)) { _ in
Spacer()
Divider()
}
Spacer().frame(width: geometry.size.height.truncatingRemainder(dividingBy: self.cellSize))
}
}
}
}
您可以使用 SwiftUI
使用 Path
(Path Documentation, Tutorial)
要绘制网格,您可以使用如下内容:
struct ContentView : View {
var horizontalSpacing: CGFloat = 48
var verticalSpacing: CGFloat = 48
var body: some View {
GeometryReader { geometry in
Path { path in
let numberOfHorizontalGridLines = Int(geometry.size.height / self.verticalSpacing)
let numberOfVerticalGridLines = Int(geometry.size.width / self.horizontalSpacing)
for index in 0...numberOfVerticalGridLines {
let vOffset: CGFloat = CGFloat(index) * self.horizontalSpacing
path.move(to: CGPoint(x: vOffset, y: 0))
path.addLine(to: CGPoint(x: vOffset, y: geometry.size.height))
}
for index in 0...numberOfHorizontalGridLines {
let hOffset: CGFloat = CGFloat(index) * self.verticalSpacing
path.move(to: CGPoint(x: 0, y: hOffset))
path.addLine(to: CGPoint(x: geometry.size.width, y: hOffset))
}
}
.stroke()
}
}
}
这可以通过 ZStack 实现,它允许您将其中的视图渲染在彼此之上。
ZStack {
HStack(spacing: horizontalSpacing) {
ForEach(0 ..< Int(numberOfVerticalGridLines)) { _ in
Rectangle().fill(Color.gray).frame(width: 1)
}
}
VStack(spacing: verticalSpacing) {
ForEach(0 ..< Int(numberOfHorizontalGridLines)) { _ in
Rectangle().fill(Color.gray).frame(height: 1)
}
}
}
为了使用 SwiftUI 使用路径绘制网格视图 Drawing Paths and Shapes
struct GridView: View {
let rows: CGFloat
let cols: CGFloat
let gridColor: Color
var body: some View {
GeometryReader { geometry in
let width = geometry.size.width
let height = geometry.size.height
let xSpacing = width / cols
let ySpacing = height / rows
Path { path in
for index in 0...Int(cols) {
let vOffset: CGFloat = CGFloat(index) * xSpacing
path.move(to: CGPoint(x: vOffset, y: 0))
path.addLine(to: CGPoint(x: vOffset, y: height))
}
for index in 0...Int(rows) {
let hOffset: CGFloat = CGFloat(index) * ySpacing
path.move(to: CGPoint(x: 0, y: hOffset))
path.addLine(to: CGPoint(x: width, y: hOffset))
}
}
.stroke(gridColor)
}
}
}
GridView(rows: 9.0, cols: 9.0, gridColor: .white)