SwiftUI:如何一个接一个地连接 2 个以上的点
SwiftUI: How to connect more than 2 dots, one by one
我正在制作一个应用程序,我在其中生成具有随机位置的点。我想用线连接第一个点和第二个点,然后用线连接第二个点和第三个点,依此类推。
我的问题是它正在连接第二个与第三个,但同时第一个正在连接第三个。我不想那样。请帮忙。
这是我的代码:
struct Dot: Hashable {
var x: CGFloat
var y: CGFloat
}
struct TestShit: View {
@State var lastx = 0.0
@State var lasty = 0.0
@State var dots = [Dot]()
var body: some View {
VStack{
ZStack{
ForEach(dots, id: \.self){ dot in
Circle()
.frame(width: 5, height: 5)
.position(x: dot.x, y: dot.y)
Path { path in
path.move(to: CGPoint(x: lastx, y: lasty))
path.addLine(to: CGPoint(x: dot.x, y: dot.y))
}.stroke(.green, lineWidth: 5)
}
}
Spacer()
Button {
let randx = CGFloat.random(in: 100...300)
let randy = CGFloat.random(in: 100...300)
dots.append(Dot(x: randx, y: randy))
lastx = randx
lasty = randy
} label: {
Text("Button")
}
}
}
}
这里我只维护1条路径,每次追加,而不是在ForEach中多于1条路径
import Combine
import SwiftUI
struct Dot: Hashable {
var x: CGFloat
var y: CGFloat
}
class Model: ObservableObject {
@Published
var dots: [Dot] = []
@Published
var path: UIBezierPath?
func addDot(x: CGFloat, y: CGFloat) {
dots.append(Dot(x: x, y: y))
let randomPoint = CGPoint(x: x, y: y)
guard let path = path else {
path = UIBezierPath()
path?.move(to: randomPoint)
path?.lineWidth = 2
return
}
path.addLine(to: CGPoint(x: x, y: y))
}
}
struct TestIt: View {
@ObservedObject
var model: Model
var body: some View {
VStack{
ZStack{
if let path = model.path {
Path(path.cgPath)
.stroke(.green, lineWidth: 5)
}
ForEach(model.dots, id: \.self){ dot in
Circle()
.frame(width: 5, height: 5)
.position(x: dot.x, y: dot.y)
}
}
Spacer()
Button {
let randx = CGFloat.random(in: 100...300)
let randy = CGFloat.random(in: 100...300)
model.addDot(x: randx, y: randy)
} label: {
Text("Button")
}
}
}
}
您可能想要看起来更好看的东西
Path(path.cgPath.copy(strokingWithWidth: 5, lineCap: .round, lineJoin: .round, miterLimit: 0))
.stroke(.green, lineWidth: 5)
问题在于这个循环:
Path { path in
path.move(to: CGPoint(x: lastx, y: lasty))
path.addLine(to: CGPoint(x: dot.x, y: dot.y))
}.stroke(.green, lineWidth: 5)
您正在创建多条线段,方法是移动到同一点,然后向不同的点添加一条线。
您想做的是:
- 设置一个“起点”
- 移动到那个点
- 对于每个点,在下一个点上加一行
看看这里的区别:
import SwiftUI
struct Dot: Hashable {
var x: CGFloat
var y: CGFloat
}
struct DotsView: View {
// initialize start point
var startX = CGFloat.random(in: 100...300)
var startY = CGFloat.random(in: 100...300)
@State var dots = [Dot]()
var body: some View {
VStack{
ZStack{
Path { path in
// move to start point
path.move(to: CGPoint(x: startX, y: startY))
dots.forEach { dot in
// add line to each dot
path.addLine(to: CGPoint(x: dot.x, y: dot.y))
}
}.stroke(.green, lineWidth: 5)
// draw the start point circle in red
Circle()
.fill(Color.red)
.frame(width: 5, height: 5)
.position(x: startX, y: startY)
// draw each dot circle in blue
ForEach(dots, id: \.self){ dot in
Circle()
.fill(Color.blue)
.frame(width: 5, height: 5)
.position(x: dot.x, y: dot.y)
}
}
Spacer()
Button {
let randx = CGFloat.random(in: 100...300)
let randy = CGFloat.random(in: 100...300)
// add a dot point
dots.append(Dot(x: randx, y: randy))
} label: {
Text("Button")
}
}
}
}
我正在制作一个应用程序,我在其中生成具有随机位置的点。我想用线连接第一个点和第二个点,然后用线连接第二个点和第三个点,依此类推。 我的问题是它正在连接第二个与第三个,但同时第一个正在连接第三个。我不想那样。请帮忙。
这是我的代码:
struct Dot: Hashable {
var x: CGFloat
var y: CGFloat
}
struct TestShit: View {
@State var lastx = 0.0
@State var lasty = 0.0
@State var dots = [Dot]()
var body: some View {
VStack{
ZStack{
ForEach(dots, id: \.self){ dot in
Circle()
.frame(width: 5, height: 5)
.position(x: dot.x, y: dot.y)
Path { path in
path.move(to: CGPoint(x: lastx, y: lasty))
path.addLine(to: CGPoint(x: dot.x, y: dot.y))
}.stroke(.green, lineWidth: 5)
}
}
Spacer()
Button {
let randx = CGFloat.random(in: 100...300)
let randy = CGFloat.random(in: 100...300)
dots.append(Dot(x: randx, y: randy))
lastx = randx
lasty = randy
} label: {
Text("Button")
}
}
}
}
这里我只维护1条路径,每次追加,而不是在ForEach中多于1条路径
import Combine
import SwiftUI
struct Dot: Hashable {
var x: CGFloat
var y: CGFloat
}
class Model: ObservableObject {
@Published
var dots: [Dot] = []
@Published
var path: UIBezierPath?
func addDot(x: CGFloat, y: CGFloat) {
dots.append(Dot(x: x, y: y))
let randomPoint = CGPoint(x: x, y: y)
guard let path = path else {
path = UIBezierPath()
path?.move(to: randomPoint)
path?.lineWidth = 2
return
}
path.addLine(to: CGPoint(x: x, y: y))
}
}
struct TestIt: View {
@ObservedObject
var model: Model
var body: some View {
VStack{
ZStack{
if let path = model.path {
Path(path.cgPath)
.stroke(.green, lineWidth: 5)
}
ForEach(model.dots, id: \.self){ dot in
Circle()
.frame(width: 5, height: 5)
.position(x: dot.x, y: dot.y)
}
}
Spacer()
Button {
let randx = CGFloat.random(in: 100...300)
let randy = CGFloat.random(in: 100...300)
model.addDot(x: randx, y: randy)
} label: {
Text("Button")
}
}
}
}
您可能想要看起来更好看的东西
Path(path.cgPath.copy(strokingWithWidth: 5, lineCap: .round, lineJoin: .round, miterLimit: 0))
.stroke(.green, lineWidth: 5)
问题在于这个循环:
Path { path in
path.move(to: CGPoint(x: lastx, y: lasty))
path.addLine(to: CGPoint(x: dot.x, y: dot.y))
}.stroke(.green, lineWidth: 5)
您正在创建多条线段,方法是移动到同一点,然后向不同的点添加一条线。
您想做的是:
- 设置一个“起点”
- 移动到那个点
- 对于每个点,在下一个点上加一行
看看这里的区别:
import SwiftUI
struct Dot: Hashable {
var x: CGFloat
var y: CGFloat
}
struct DotsView: View {
// initialize start point
var startX = CGFloat.random(in: 100...300)
var startY = CGFloat.random(in: 100...300)
@State var dots = [Dot]()
var body: some View {
VStack{
ZStack{
Path { path in
// move to start point
path.move(to: CGPoint(x: startX, y: startY))
dots.forEach { dot in
// add line to each dot
path.addLine(to: CGPoint(x: dot.x, y: dot.y))
}
}.stroke(.green, lineWidth: 5)
// draw the start point circle in red
Circle()
.fill(Color.red)
.frame(width: 5, height: 5)
.position(x: startX, y: startY)
// draw each dot circle in blue
ForEach(dots, id: \.self){ dot in
Circle()
.fill(Color.blue)
.frame(width: 5, height: 5)
.position(x: dot.x, y: dot.y)
}
}
Spacer()
Button {
let randx = CGFloat.random(in: 100...300)
let randy = CGFloat.random(in: 100...300)
// add a dot point
dots.append(Dot(x: randx, y: randy))
} label: {
Text("Button")
}
}
}
}