swift - 如何使用 CGAffineTransform 将旋转角度的锚点更改为中心?
问题描述
对于某些原因,在我的 SwiftUI 应用程序中,我需要使用带有 CGAffineTransform 和 rotationAngle 属性的 transformEffect 修饰符。但结果是这样的:
如何将旋转角度的锚点设置为箭头图像的中心?我在文档中看到我们可以使用 CGPoint 吗?
我的代码:
import SwiftUI
import CoreLocation
struct Arrow: View {
var locationManager = CLLocationManager()
@ObservedObject var heading: LocationManager = LocationManager()
private var animationArrow: Animation {
Animation
.easeInOut(duration: 0.2)
}
var body: some View {
VStack {
Image("arrow")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 300, height: 300)
.overlay(RoundedRectangle(cornerRadius: 0)
.stroke(Color.white, lineWidth: 2))
.animation(animationArrow)
.transformEffect(
CGAffineTransform(rotationAngle: CGFloat(-heading.heading.degreesToRadians))
.translatedBy(x: 0, y: 0)
)
Text(String(heading.heading.degreesToRadians))
.font(.system(size: 30))
.fontWeight(.light)
}
}
}
解决方案
如果你想用一个变换矩阵来做,你需要平移、旋转、平移。但是您可以使用锚点执行旋转效果。请注意,默认锚点是中心。我只是明确地包括它,所以如果你想在其他地方旋转锚定它就可以了。
锚点在 UnitPoint 中指定,表示坐标为 0 到 1。其中 0.5 表示中心。
struct ContentView: View {
@State private var angle: Double = 0
var body: some View {
VStack {
Rectangle().frame(width: 100, height: 100)
.rotationEffect(Angle(degrees: angle), anchor: UnitPoint(x: 0.5, y: 0.5))
Slider(value: $angle, in: 0...360)
}
}
}
使用矩阵的相同效果更丑陋,但也有效:
struct ContentView: View {
@State private var angle: Double = 0
var body: some View {
VStack {
Rectangle().frame(width: 100, height: 100)
.transformEffect(
CGAffineTransform(translationX: -50, y: -50)
.concatenating(CGAffineTransform(rotationAngle: CGFloat(angle * .pi / 180)))
.concatenating(CGAffineTransform(translationX: 50, y: 50)))
Slider(value: $angle, in: 0...360)
}
}
}
推荐阅读
- c - 3D空间OpenGL(C)中的弯曲圆柱体
- javascript - CrashLoopBackOff 运行循环:Docker 和 GraphQl 警告不健康连接被拒绝
- orchardcms - 果园核心级联删除
- javascript - 通过数组获取的正确方法
- c# - 如何在 Roslyn 中使用项目方法?
- flask - 无法在烧瓶中使用 request.args
- eclipse - JAX-RS 完全没有响应 (404)
- javascript - 如何使用 TypeScript 中的对象解构为构造函数中的类级别属性赋值?
- maxima - Maxima:类似于 Excel 中的圆形
- android - 一旦我开始做广告,我的 android BLE 设备会在多长时间内做广告?有没有办法增加持续时间?