Невозможно управлять анимацией в форме?
Разве это не означает, что можно управлять анимацией, происходящей внутри представления формы? У меня есть игровая площадка, которая демонстрирует проблему, а также гифку о том, что происходит. Как видите, мой переход ко 2-му анимированному представлению полностью игнорируется, и мне пришлось вручную замедлить видео, потому что длительность также игнорируется.
Мне действительно не нужен масштабный переход, это было просто, чтобы продемонстрировать, что независимо от того, что я туда вставляю, анимация остается неизменной. Ожидается ли это или это ошибка? Или я просто что-то делаю не так?
Мне также непонятно, почему анимация VStack обрабатывается так иначе, чем просто текстовое поле, которое красиво скользит вниз, в то время как VStack, кажется, получает некоторую комбинацию.move и.opacity.
import SwiftUI
import PlaygroundSupport
struct ContentView: View {
@State var showGoodAnimation = false
@State var showBadAnimation = false
var body: some View {
Form {
Toggle(isOn: self.$showGoodAnimation.animation(.easeInOut(duration: 1))) {Text("Yay!")}
if self.showGoodAnimation {
Text("I animate beautifully.")
}
Toggle(isOn: self.$showBadAnimation.animation(.easeInOut(duration: 1))) {Text("Boo!")}
if self.showBadAnimation {
VStack {
Text("Hi.").padding()
Text("I'm a hot mess.").padding()
}
.frame(height: 250)
.transition(.scale)
}
Text("I'm just always here.")
}
}
}
PlaygroundPage.current.setLiveView(ContentView())
1 ответ
Предполагаю, что, вероятно, некоторое время назад этот вопрос обошелся, но в интересах тех, кто бьется головой о SwiftUI Form и тому подобное сейчас (как и я :-))
Оказывается, что формы, списки и (без сомнения) другие компоненты намеренно игнорируют настройку анимации, потому что они являются компонентами SwiftUI View «более высокого уровня» (в отличие от V и HStack).
Они делают это, потому что компоненты SwiftUI более высокого уровня предназначены для передачи семантической информации и (более практично) для хорошей работы на всех платформах. Чтобы добиться этого, инженерное решение Apple заключалось в том, чтобы сделать анимацию «простой», но (как было замечено) только в той степени, в которой она по существу «включается» или «выключается».
Скорее всего, он спроектирован таким образом, потому что разработчик хочет большего контроля. Затем Apple считает, что поощрение их к использованию компонентов нижнего уровня будет менее болезненным, чем попытки обойти оптимизацию, которую они применили к компонентам представления более высокого уровня.
В любом случае, для определенного есть по крайней мере один аварийный люк, заключив View в контейнер и указав
.animation(nil)
модификатор (как упоминалось в ответе Asperi SO здесь.
Пример этого показан ниже для полноты; Лично я избегаю этого шаблона, так как подозреваю, что это что-то вроде ножного ружья.
import PlaygroundSupport
import SwiftUI
struct ContentView: View {
@State var showGoodAnimation = false
@State var showBadAnimation = false
var body: some View {
Form {
Toggle(isOn: self.$showGoodAnimation.animation(.easeInOut(duration: 1))) { Text("Yay!") }
if self.showGoodAnimation {
Text("I animate beautifully.")
}
Toggle(isOn: self.$showBadAnimation.animation()) { Text("Boo!") }
VStack {
if self.showBadAnimation {
List {
Text("I animated differently").padding()
Text("But am I a footgun?").padding()
}
.transition(.asymmetric(insertion: .slide, removal: .opacity))
.animation(.easeOut(duration: 5))
}
}
.animation(nil)
.transition(.slide)
Text("I'm just always here.")
}
}
}
PlaygroundPage.current.setLiveView(ContentView())