【问题标题】:How to change anchor of rotation angle to center with CGAffineTransform?如何使用 CGAffineTransform 将旋转角度的锚点更改为中心?
【发布时间】:2019-09-18 12:25:14
【问题描述】:

出于某些原因,在我的 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)
    }
  }
} 

【问题讨论】:

  • 您是否尝试执行.rotationEffect(Angle(radians: yourAngle))(默认情况下具有中心锚点)并将任何其他transformEffects 与CGAffineTransform 翻译链接?

标签: swift swiftui cgaffinetransform


【解决方案1】:

如果你想用一个变换矩阵来做,你需要平移、旋转、平移。但是您可以使用锚点执行旋转效果。请注意,默认锚点是中心。我只是明确地包括它,所以如果你想在其他地方旋转锚定它就可以了。

在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)
        }
    }
}

【讨论】:

  • 已更新,添加了矩阵替代方案。
  • 感谢您的回复。最后一个问题,即使 CGAffineTransform 不符合 Animatable ,也可以使用 CGAffineTransform 添加动画?
  • 您可以使用 GeometryEffect 为变换设置动画。我发布了关于如何操作的其他问题的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-09
  • 1970-01-01
  • 1970-01-01
  • 2021-08-31
相关资源
最近更新 更多