SwiftUI Цепная анимация - PullRequest
0 голосов
/ 27 апреля 2020

Я пытаюсь сделать что-то очень простое. Сначала используйте анимацию заполнения, а затем ширину анимации.

@state var animate = false

Rect().frame(width: animate ? 200 : 1, height: 2).animate(Animation.easeOut(duration: 0.5).delay(0.5)).padding(.bottom, animate ? 300 : 10).animate(.easeOut)

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

В чем я не ошибаюсь?

Обновление: рабочее решение с использованием метода Аспери asyn c после


    @State private var width: CGFloat = 0.1
    @State private var isFirstResponder = false

    private var becameFirstResponder: Binding<Bool> { Binding (
        get: { self.isFirstResponder },
        set: {
            self.isFirstResponder = $0
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                self.width = self.isFirstResponder ? 240 : 0.1

            }

            }
        )}

    var body: some View {
       Divider().frame(width: width, height: 2)
.animation(Animation.easeOut(duration: 1), value: width)
.background(Color.primary)
.padding(.bottom, keyboard.height).animate(.easeOut)
   }

Как видите, этот код слишком сложен для очень простой цепной анимации. Кто-нибудь получил решение без использования asyncAfter?

1 Ответ

1 голос
/ 27 апреля 2020

Вы задерживаете анимацию, но одновременно изменяете оба значения, поэтому она запутана.

Здесь возможно решение

demo

struct DemoDelayedAnimations: View {
    @State private var animate = false

    // separate animatable values
    @State private var width: CGFloat = 1
    @State private var padding: CGFloat = 10
    var body: some View {
        VStack {
            Rectangle()
                .frame(width: width, height: 2)
                    .animation(.easeOut, value: width) // explicit to width
                .padding(.bottom, padding)
                    .animation(.easeOut, value: padding) // explicit to padding
            Divider()
            Button("Go") {
                self.padding = self.padding == 10 ? 300 : 10

                // delay value change, not animation (it reacts on change)
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                    self.width = self.width == 1 ? 200 : 1
                }
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...