기어가더라도 제대로

[SwiftUI-기초] Shape 를 애니메이션 주기 - animatableData 본문

SwiftUI - 기초

[SwiftUI-기초] Shape 를 애니메이션 주기 - animatableData

Damagucci-juice 2022. 11. 21. 00:56
struct Trapezoid: Shape {
    var insetAmount: Double

    func path(in rect: CGRect) -> Path {
        var path = Path()

        path.move(to: CGPoint(x: 0, y: rect.maxY))
        path.addLine(to: CGPoint(x: insetAmount, y: rect.minY))
        path.addLine(to: CGPoint(x: rect.maxX - insetAmount, y: rect.minY))
        path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
        path.addLine(to: CGPoint(x: 0, y: rect.maxY))

        return path
   }
}

struct ContentView: View {
    @State private var insetAmount = 50.0

    var body: some View {
        Trapezoid(insetAmount: insetAmount)
            .frame(width: 200, height: 100)
            .onTapGesture {
                withAnimation {
                    insetAmount = Double.random(in: 10...90)
                }
            }
    }
}
  • 탭 될 때마다  사각형의 윗변이 변화하는 애니메이션을 그리고 싶음
  • withAnimation {} 덕분에 애니메이션이 될거같은데 그렇지 않음
  • 값이 변할 때마다 그 사이 값을 반영을 해야할텐데, 그게 아니라 이전 값에서 다음 값으로 바로 점프를 함
  • Binding 된 값이 변화하기 전에 뷰의 상태를 본 후 값이 변화한 다음에 뷰의 상태를 점검해서 다시 뷰를 그린다. 
  • [현실] 탭을 해서 새로운 랜덤값으로 즉시 넘어감: 50 -> 55
  • [이상] 50, 51, 52, 53, 54, 55

animatableData

var animatableData: Double {
    get { insetAmount }
    set { insetAmount = newValue }
}
  • 이 연산 프로퍼티를 Trapezoid 구조체에 추가
  • SwiftUI 적으로는 랜덤한 값으로 바로 가지만, 스크린 내부적으로는 애니메이션을 위해 상태 변화 값을 추적하게 함
  • animatableData의 값은 애니메이션이 진행될 수록 목적한 값(insetAmount)에 가까워짐 
Comments