#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’ и так далее.