SwiftUI вращение Эффект - Как go только по часовой стрелке? - PullRequest
0 голосов
/ 26 марта 2020

(Xcode 11.4 · Swift 5 · iOS Target 13.4)

Урезанный код SwiftUI iOS ниже создает представление, которое содержит плавно вращающиеся секундные стрелки часов. Он работает нормально, за исключением того, что анимация запускается против часовой стрелки, когда значение секунд изменяется с 59 на 0. Как заставить секундный стрелку вращаться только по часовой стрелке?

import SwiftUI

struct ClockView: View {

    @State var now = Date()
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

    var body: some View {
        ZStack {
            Pointer()
                .stroke(Color.orange, lineWidth: 1)
                .rotationEffect(Angle.degrees(360 * now.second / 60))
                .animation(Animation.linear(duration: 1.0))
                .frame(width: 300, height: 300)
        }.onReceive(timer) { time in
            self.now = time
        }
    }
}

struct ClockView_Previews: PreviewProvider {
    static var previews: some View {
        ClockView()
    }
}

struct Pointer: Shape {
    func path(in rect: CGRect) -> Path {
        Path { p in
            p.move(to: CGPoint(x: rect.midX, y: rect.minY))
            p.addLine(to: CGPoint(x: rect.midX, y: rect.midY))
        }
    }
}

extension Date {
    var second: Double {
        return Double(Calendar.current.dateComponents([.second], from: self).second ?? 0)
    }
}

1 Ответ

0 голосов
/ 26 марта 2020

Попробуйте код ниже. Стратегия здесь состоит в том, чтобы отключать анимацию движущейся руки раз в минуту. Когда анимация выключена, угол можно регулировать, не получая нежелательное вращательное вращение. Возможно, есть более простой способ сделать это, но это определенно делает свою работу.

struct ClockView: View {

      @State var seconds : Double = 0
      let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

      var body: some View {
            ZStack {
                  Pointer()
                        .stroke(Color.orange, lineWidth: 1)
                        .rotationEffect(Angle.degrees(360 * seconds / 60))
                        .frame(width: 300, height: 300)
            }.onReceive(timer) { time in

                  self.seconds = Date().second

                  if self.seconds == 60.0 {
                        withAnimation(.none) {
                              self.seconds = 0.01 }
                  }
                  withAnimation(Animation.linear(duration: 1.0)) {
                  self.seconds = round(self.seconds + 1)
                  }
            }
      }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...