在 SwiftUI 和 Core Graphics 中,CGPoint 是一个二维空间中的点,用来表示一个坐标。它定义在 Core Graphics 框架中,包含 x 和 y 两个属性,分别表示点在水平(X 轴)和垂直(Y 轴)方向上的位置。
CGPoint 的结构定义
struct CGPoint {
var x: CGFloat
var y: CGFloat
}
x: 点在水平轴上的位置(横坐标)。
y: 点在垂直轴上的位置(纵坐标)。
CGFloat 是一个浮点数类型,可以存储整数或小数。
创建 CGPoint
1、直接初始化
let point = CGPoint(x: 50, y: 100)
print(point) // 输出: (50.0, 100.0)
2、默认零点
使用 .zero 创建位于原点的点 (0, 0):
let origin = CGPoint.zero
print(origin) // 输出: (0.0, 0.0)
CGPoint 的常见操作
1、访问属性
let point = CGPoint(x: 30, y: 70)
print("x: \(point.x), y: \(point.y)") // x: 30.0, y: 70.0
2、加减点操作
可以通过计算修改点的位置:
var point = CGPoint(x: 50, y: 100)
point.x += 20
point.y -= 30
print(point) // 输出: (70.0, 70.0)
3、两点之间的距离
使用勾股定理计算两点之间的距离:
let point1 = CGPoint(x: 0, y: 0)
let point2 = CGPoint(x: 3, y: 4)
let distance = sqrt(pow(point2.x - point1.x, 2) + pow(point2.y - point1.y, 2))
print(distance) // 输出: 5.0
4、转换到其他坐标系
SwiftUI 中,GeometryReader 提供的 frame 可以返回视图的坐标,通过 CGPoint 表示位置。例如:
GeometryReader { geometry in
let point = CGPoint(x: geometry.frame(in: .local).midX, y: geometry.frame(in: .local).midY)
Text("Center: \(point.debugDescription)")
}
CGPoint 在 SwiftUI 中的应用场景
1、自定义路径
CGPoint 通常用来绘制自定义路径和形状:
struct CustomShape: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: rect.midX, y: rect.minY)) // 移动到顶部中心
path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY)) // 左下角
path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY)) // 右下角
path.closeSubpath()
return path
}
}
struct ContentView: View {
var body: some View {
CustomShape()
.stroke(Color.blue, lineWidth: 2)
}
}

需要注意的是,在iOS的坐标系统中,y坐标是从顶部开始增大的。(0,0)是视图的左上角,随着往下移动,y值会增加。
2、动画和运动路径
使用 CGPoint 来计算视图的位置偏移,模拟运动:
struct MovingCircle: View {
@State private var position = CGPoint(x: 50, y: 50)
var body: some View {
Circle()
.frame(width: 50, height: 50)
.position(position)
.onAppear {
withAnimation(.easeInOut(duration: 2).repeatForever(autoreverses: true)) {
position = CGPoint(x: 200, y: 400)
}
}
}
}

3、手势处理
使用手势时,可以通过 CGPoint 获取触摸点的具体位置:
struct DragExample: View {
@State private var dragPosition = CGPoint.zero
var body: some View {
Circle()
.frame(width: 50, height: 50)
.position(dragPosition)
.gesture(
DragGesture()
.onChanged { value in
dragPosition = value.location
}
)
}
}

扩展 CGPoint
为了简化常见操作,可以通过扩展来添加功能:
extension CGPoint {
// 两点之间的距离
func distance(to point: CGPoint) -> CGFloat {
sqrt(pow(point.x - x, 2) + pow(point.y - y, 2))
}
// 向量加法
static func + (lhs: CGPoint, rhs: CGPoint) -> CGPoint {
CGPoint(x: lhs.x + rhs.x, y: lhs.y + rhs.y)
}
// 向量减法
static func - (lhs: CGPoint, rhs: CGPoint) -> CGPoint {
CGPoint(x: lhs.x - rhs.x, y: lhs.y - rhs.y)
}
}
// 使用扩展
let p1 = CGPoint(x: 0, y: 0)
let p2 = CGPoint(x: 3, y: 4)
let distance = p1.distance(to: p2) // 5.0
let sum = p1 + p2 // (3.0, 4.0)
总结
CGPoint 是二维空间中点的表示形式,常用于图形绘制、动画路径、视图位置计算等场景。
在 SwiftUI 中,CGPoint 与坐标系、几何计算密切相关,是构建自定义布局和交互的基础。
熟练使用 CGPoint 可以实现更加灵活的图形和动画效果。