Анимация с цепочкой, сбивающаяся при смене ориентации

#swift #animation #layout #swiftui

#swift #Анимация #макет #swiftui

Вопрос:

Когда я меняю ориентацию, символ sparkle SF начинает двигаться вверх и вниз. Анимация вверх и вниз должна быть реализована только один раз (при появлении). Однако я пытался использовать verticalSizeClass, это не помогает.

Как это работает: при появлении текст и символ SF перемещаются вверх, а затем символ Sparkle SF масштабируется вверх и вниз.

Вот как это выглядит и ведет себя при смене ориентации:

введите описание изображения здесь

 struct ContentView: View {
    @State private var offsetY: CGFloat = 150
    @State private var opacityAmount: Double = 0
    @State private var animationAmount: CGFloat = 1
    
    var body: some View {
        VStack {
            HStack {
                Image(systemName: "sparkle").foregroundColor(.yellow)
                    .offset(y: offsetY)
                    .opacity(opacityAmount)
                    .animation(
                        Animation.easeOut(duration: 0.5).delay(0.1)
                    )
                    .scaleEffect(animationAmount)
                    .animation(Animation.easeInOut(duration: 1).repeatForever(autoreverses: true))
                Text("All new design").font(.largeTitle)
                    .offset(y: offsetY)
                    .opacity(opacityAmount)
                    .animation(
                        Animation.easeOut(duration: 0.5).delay(0.1)
                    )
            }
            .onAppear {
                offsetY = 0
                opacityAmount = 0.8
                animationAmount = 2
            }
        }
    }
}
  

Ответ №1:

Вы не адаптировали объединение значений анимации из моего предыдущего ответа и не наблюдали за результатом этого.

Это связано с тем, что .animation модификатор вводит неявную анимацию, которая применяется ко всем модификаторам анимируемого вида над ним, что может привести к нежелательному накоплению нескольких анимаций (однако иногда это то, что нужно, конечно).

Вот исправленная часть. Протестировано с Xcode 12 / iOS 14

 HStack {
    Image(systemName: "sparkle").foregroundColor(.yellow)
        .offset(y: offsetY)
        .opacity(opacityAmount)
        .animation(
            Animation.easeOut(duration: 0.5).delay(0.1)
        , value: opacityAmount)                     // << here !!
        .scaleEffect(animationAmount)
        .animation(Animation.easeInOut(duration: 1).repeatForever(autoreverses: true),
            value: animationAmount)                // << here !!
    Text("All new design").font(.largeTitle)
        .offset(y: offsetY)
        .opacity(opacityAmount)
        .animation(
            Animation.easeOut(duration: 0.5).delay(0.1)
        , value: opacityAmount)                           // << here !!
}
  

Примечание: вы можете поиграть с тем, какой анимации давать явное значение, а какой нет.

Комментарии:

1. Спасибо, это имеет большой смысл! Я не знал, что могу использовать ‘value: opacityAmount’ и так далее.