You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用AffineTransform围绕视图中心旋转CGPoint?UIBezierPath旋转可行但方案失效

围绕视图中心旋转CGPoint的可行方案

我太懂研究一上午没进展的憋屈感了!你说的网格旋转方案不适用,核心原因是没处理UIKit坐标系和旋转原点的差异——网格旋转一般默认以(0,0)为原点,但你需要的是围绕视图的中心旋转,得先做坐标转换才行。下面给你一套直接能用的步骤和代码:

核心三步法

1. 将目标点转换为「以视图中心为原点」的相对坐标

UIKit视图的坐标系原点在左上角,所以首先要把目标点的坐标减去视图中心的坐标,把原点“移”到视图中心:

// 先获取视图的中心坐标(基于自身bounds)
let viewCenter = CGPoint(x: yourView.bounds.midX, y: yourView.bounds.midY)
// 计算目标点相对于视图中心的位置
let pointRelativeToCenter = CGPoint(
    x: targetPoint.x - viewCenter.x,
    y: targetPoint.y - viewCenter.y
)

2. 应用2D旋转公式计算旋转后的相对坐标

用标准的旋转公式,注意UIKit的Y轴是向下的,所以旋转方向是顺时针(如果需要逆时针,给角度传负数即可)。这里的角度要传弧度制(比如CGFloat.pi是180度,CGFloat.pi/2是90度):

let rotationAngle: CGFloat = .pi/2 // 示例:旋转90度
let rotatedX = pointRelativeToCenter.x * cos(rotationAngle) - pointRelativeToCenter.y * sin(rotationAngle)
let rotatedY = pointRelativeToCenter.x * sin(rotationAngle) + pointRelativeToCenter.y * cos(rotationAngle)
let rotatedRelativePoint = CGPoint(x: rotatedX, y: rotatedY)

3. 转换回视图坐标系

把旋转后的相对坐标加回视图中心坐标,就得到了最终在视图里的旋转后点:

let finalRotatedPoint = CGPoint(
    x: rotatedRelativePoint.x + viewCenter.x,
    y: rotatedRelativePoint.y + viewCenter.y
)

封装成工具方法(推荐复用)

把上面的逻辑封装成CGPoint的扩展,以后用起来超方便:

extension CGPoint {
    /// 围绕指定中心点旋转当前点
    /// - Parameters:
    ///   - center: 旋转中心点
    ///   - angle: 旋转角度(弧度制,顺时针为正)
    /// - Returns: 旋转后的点
    func rotated(around center: CGPoint, by angle: CGFloat) -> CGPoint {
        let dx = x - center.x
        let dy = y - center.y
        let rotatedX = dx * cos(angle) - dy * sin(angle)
        let rotatedY = dx * sin(angle) + dy * cos(angle)
        return CGPoint(x: rotatedX + center.x, y: rotatedY + center.y)
    }
}

使用示例

// 假设你有一个目标点和要旋转的视图
let targetPoint = CGPoint(x: 30, y: 30)
let yourView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
let viewCenter = CGPoint(x: yourView.bounds.midX, y: yourView.bounds.midY)

// 旋转90度
let rotatedPoint = targetPoint.rotated(around: viewCenter, by: .pi/2)

为什么之前的网格方案不适用?

那些网格旋转方案一般默认旋转原点是坐标系的(0,0),但你的需求是围绕视图中心——这个中心在视图坐标系里是(midX, midY),不是(0,0),所以必须先做坐标平移,把目标点转到以中心为原点的坐标系里再旋转,转完再平移回去,这是关键的差异点。

内容的提问来源于stack exchange,提问作者digit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:49:36