Протестировано на Xcode 11.3.1 и 11.4:
При прикреплении неявных анимаций к переходу некоторые типы переходов выглядят неработающими. В частности, любые связанные с позицией переходы не применяют данную неявную анимацию. .slide
, .move
, .offset
сломаны. .opacity
и .scale
кажутся нормальными. (См. Вложение)
Кажется, что во всех случаях явная анимация работает нормально.
Даже при использовании пользовательских составных переходов субпереходы, связанные с положением, не реагируют на неявную анимацию.
Это ошибка или ожидаемое поведение?
Похоже, это было бы проблемой, если вы хотите запустить несколько различных кривых анимации для определенных c элементов пользовательского интерфейса на основе неявного изменение свойства.
struct MyExample: View {
@State private var isShowing = true
private let myAnimation = Animation.spring(response: 0.8, dampingFraction: 0.2, blendDuration: 3.0)
var body: some View {
VStack(spacing:20) {
if self.isShowing {
Text("Opacity").modifier(MyBigFont())
.transition(AnyTransition.opacity.animation(myAnimation))
Text("Scale").modifier(MyBigFont())
.transition(AnyTransition.scale.animation(myAnimation))
Text("Slide").modifier(MyBigFont())
.transition(AnyTransition.slide.animation(myAnimation))
Text("Move").modifier(MyBigFont())
.transition(AnyTransition.move(edge: .trailing).animation(myAnimation))
Text("Offset").modifier(MyBigFont())
.transition(AnyTransition.offset(x: 20, y: 0).animation(myAnimation))
Text("Custom").modifier(MyBigFont())
.transition(AnyTransition.myCustomTransition.animation(myAnimation))
}
Spacer()
Button(action: {
self.isShowing.toggle()
}) {
Text("Implicit Toggle")
}
Button(action: {
withAnimation(self.myAnimation) {
self.isShowing.toggle()
}
}) {
Text("Explicit Toggle")
}
}
}
}
struct MyBigFont: ViewModifier {
func body(content: Content) -> some View {
content
.lineLimit(1)
.padding()
.background(Color.purple)
.foregroundColor(.white)
.cornerRadius(8)
.font(Font.system(size: 21).bold())
}
}
struct MyCustomTransition: ViewModifier {
var isEnabled: Bool
func body(content: Content) -> some View {
if isEnabled {
return content
.offset(x: 20.0, y: 0.0)
.opacity(0)
} else {
return content
.offset(x: 0.0, y: 0.0)
.opacity(1)
}
}
}
extension AnyTransition {
static let myCustomTransition = AnyTransition.modifier(
active: MyCustomTransition(isEnabled: true),
identity: MyCustomTransition(isEnabled: false))
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
VStack {
MyExample()
Spacer()
}
}
}