как сделать простую анимацию масштабирования и почему это не работает? - PullRequest
0 голосов
/ 03 апреля 2020

Я только что прочитал в stackoverflow, я могу только объединить animatino с задержкой, поэтому я попробовал это здесь, который просто сжимается, а затем снова масштабирует круг. к сожалению, сокращение не работает !? если я прокомментирую растущие, сокращающиеся работы ...

struct ContentView: View {

    @State var scaleImage : CGFloat = 1

    var body: some View {
        VStack {
            Button(action: {
                withAnimation(Animation.easeInOut(duration: 1)) {
                    self.scaleImage = 0.01
                }

                withAnimation(Animation.easeInOut(duration: 1).delay(1.0)) {
                    self.scaleImage = 1
                }
            }) {
                Text ("Start animation")
            }
            Image(systemName: "circle.fill")
                .scaleEffect(scaleImage)
        }
    }
}

1 Ответ

0 голосов
/ 03 апреля 2020

Здесь возможен подход (на основе AnimatableModifier). Фактически это демонстрирует, как текущий конец анимации может быть обнаружен и что-то выполнено - в этом случае, для вашего сценария масштабирования, просто инициируйте реверсирование.

Протестировано с Xcode 11.4 / iOS 13.4

demo

Упростил и изменил ваш пример

struct TestReversingScaleAnimation: View {

    @State var scaleImage : CGFloat = 1

    var body: some View {
        VStack {
            Button("Start animation") {
                self.scaleImage = 0.01       // initiate animation
            }

            Image(systemName: "circle.fill")
                .modifier(ReversingScale(to: scaleImage) {
                    self.scaleImage = 1      // reverse set
                })
                .animation(.default)         // now can be implicit
        }
    }
}

На самом деле, шоу-мейкер здесь ... важные комментарии в строке.

struct ReversingScale: AnimatableModifier {
    var value: CGFloat

    private var target: CGFloat
    private var onEnded: () -> ()

    init(to value: CGFloat, onEnded: @escaping () -> () = {}) {
        self.target = value
        self.value = value
        self.onEnded = onEnded // << callback
    }

    var animatableData: CGFloat {
        get { value }
        set { value = newValue
            // newValue here is interpolating by engine, so changing
            // from previous to initially set, so when they got equal
            // animation ended
            if newValue == target {
                onEnded()
            }
        }
    }

    func body(content: Content) -> some View {
        content.scaleEffect(value)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...