Используя SwiftUI, как мне анимировать p ie индикатор выполнения - PullRequest
2 голосов
/ 17 февраля 2020

Я создал код для отображения индикатора выполнения p ie. Мне нужно добавить анимацию в этот индикатор. Я попробовал линейную анимацию, но это не помогло. Я застрял и не знаю, как заставить его оживить. Может кто-нибудь помочь? Вот код.

import SwiftUI

struct PieProgress: View {
    @State var progress: Float

    var body: some View {
        GeometryReader { geometry in
            VStack(spacing:20) {
                HStack{
                    Text("0%")
                    Slider(value: self.$progress)
                    Text("100%")
                }.padding()
                Circle()
                    .stroke(Color.gray, lineWidth: 1)
                    .frame(width: geometry.size.width, height: geometry.size.width, alignment: .center)
                    .padding()
                    .overlay(
                        PieShape(progress: Double(self.progress))
                            .frame(width: geometry.size.width - 10, height: geometry.size.width - 10 , alignment: .center)
                            .foregroundColor(.blue)
                    )
            }
        }
    }
}

struct PieShape: Shape {
    var progress: Double = 0.0
    private let startAngle: Double = (Double.pi) * 1.5
    private var endAngle: Double {
        get {
            return self.startAngle + Double.pi * 2 * self.progress
        }
    }

    func path(in rect: CGRect) -> Path {
        var path = Path()
        let arcCenter =  CGPoint(x: rect.size.width / 2, y: rect.size.width / 2)
        let radius = rect.size.width / 2
        path.move(to: arcCenter)
        path.addArc(center: arcCenter, radius: radius, startAngle: Angle(radians: startAngle), endAngle: Angle(radians: endAngle), clockwise: false)
        path.closeSubpath()
        return path
    }
}

1 Ответ

2 голосов
/ 17 февраля 2020

Здесь возможен подход (протестировано и работает с Xcode 11.2 / iOS 13.2):

1) Вам необходимо указать animatableData для вашей фигуры, как показано ниже

struct PieShape: Shape {
    var progress: Double = 0.0

    var animatableData: Double {
        get {
            self.progress
        }
        set {
            self.progress = newValue
        }
    }
    ...

2) затем добавьте анимацию к Circle

Circle()
    .stroke(Color.gray, lineWidth: 1)
    .frame(width: geometry.size.width, height: geometry.size.width, alignment: .center)
    .padding()
    .overlay(
        PieShape(progress: Double(self.progress))
            .frame(width: geometry.size.width - 10, height: geometry.size.width - 10 , alignment: .center)
            .foregroundColor(.blue)
    )
.animation(Animation.linear) // << here !!

и все. Для тестирования (только!) Вы можете добавить следующее в PieProgress

.onAppear {
    DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
        self.progress = 0.72
    }
}

Примечание: для использования PieProgress в качестве повторно используемого компонента было бы разумно сделать progress как @Binding, просто в случай.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...