如何在SwiftUI中使用CGAffineTransform制作旋转动画?

时间:2019-09-22 18:57:58

标签: swift swiftui cgaffinetransform

在我的指南针应用中,对于某些存在的漏洞,我必须使用CGAffineTransform旋转我的箭头。但是我不知道如何使用CGAffineTransform创建动画。

我的代码:

import SwiftUI
import CoreLocation

struct Arrow: View {

  var locationManager = CLLocationManager()
  @ObservedObject var location: LocationManager = LocationManager()
  @State private var angle: CGFloat = 0

  var body: some View {
    VStack {
      Image("arrow")
        .resizable()
        .aspectRatio(contentMode: .fit)
        .frame(width: 300, height: 300)
        .modifier(RotationEffect(angle: CGFloat(self.location.heading.degreesToRadians)))
      Text(String(self.location.heading.degreesToRadians))
        .font(.system(size: 20))
        .fontWeight(.light)
        .padding(.top, 15)

      Text(String(self.location.coordinates[0]))
        .font(.system(size: 20))
        .fontWeight(.light)
        .padding(.top, 15)

      Text(String(self.location.coordinates[1]))
        .font(.system(size: 20))
        .fontWeight(.light)
        .padding(.top, 15)
    }
  }
}

struct RotationEffect: GeometryEffect {
  var angle: CGFloat

  var animatableData: CGFloat {
    get { angle }
    set { angle = newValue }
  }

  func effectValue(size: CGSize) -> ProjectionTransform {
    return ProjectionTransform(
      CGAffineTransform(translationX: -150, y: -150)
        .concatenating(CGAffineTransform(rotationAngle: angle))
        .concatenating(CGAffineTransform(translationX: 150, y: 150))
    )
  }
}

我知道我可以像下面的代码一样使用withAnimation,但是我需要使用location.heading自动设置angle变量。无需按下任何按钮。

struct ContentView: View {
    @State private var angle: CGFloat = 0

    var body: some View {
        VStack {
            Rectangle()
                .frame(width: 50, height: 50)
                .modifier(MyEffect(angle: angle))

            Button("Go to 0") {
                withAnimation(.easeInOut(duration: 2.0)) {
                    self.angle = 0
                }
            }

            Button("Go to 360") {
                withAnimation(.easeInOut(duration: 2.0)) {
                    self.angle = .pi * 2
                }
            }
        }
    }
}

0 个答案:

没有答案