iOS矩阵栈实现:如何将Core Graphics的CTM重置为单位矩阵
Core Graphics 自定义CTM栈不生效问题解决方案
核心问题根源
你的代码没有生效的核心原因是混淆了CGAffineTransform的纯计算方法和CGContext的状态修改方法:
CGContext.ctm是只读属性,仅用于读取当前变换矩阵的值CGAffineTransform.concatenating(_:)是纯计算方法,只会返回新的矩阵结果,不会修改CGContext的实际状态
你之前的代码只是计算了新的矩阵值,但完全没有把计算结果应用到上下文上,因此不会产生任何实际效果。
修正后的实现代码
全版本兼容实现
public func resetMatrixToIdentity() { guard let context = context else { return } let inverted = context.ctm.inverted() // 调用CGContext的concatenate方法直接修改上下文CTM context.concatenate(inverted) } open func pushMatrix() { guard let context = context else { return } matrixStack.push(matrix: context.ctm) } open func popMatrix() { guard let context = context, let savedMatrix = matrixStack.pop() else { return } resetMatrixToIdentity() // 调用CGContext的concatenate方法应用保存的矩阵 context.concatenate(savedMatrix) }
新系统简化实现(iOS 15+/macOS 12+)
如果你的工具包仅支持较新的系统版本,可以直接通过transform属性赋值替换CTM,不需要手动计算逆矩阵:
@available(iOS 15.0, macOS 12.0, *) open func popMatrix() { guard let context = context, let savedMatrix = matrixStack.pop() else { return } context.transform = savedMatrix }
额外注意事项
- 要保证
pushMatrix、popMatrix调用时,你持有的context是当前活跃的图形上下文 - 需保证
push和pop严格配对,避免矩阵栈泄露导致后续绘制状态异常
内容的提问来源于stack exchange,提问作者rikitikitavi
相关产品推荐
相关产品推荐

