SwiftUI - 在列表中的视图内触发的动画也不会为列表设置动画 [英] SwiftUI - Animations triggered inside a View that's in a list doesn't animate the list as well
问题描述
我有一个 List
显示两个相同类型的 Views
.当您点击其中一个视图时,它们会通过动画改变高度.
I have a List
that's displaying two Views
of the same type. When you tap on one of the views, they change their height with an animation.
但是,这些视图嵌入的 List
没有动画,这会导致丑陋的故障,因为 List
行的高度会立即更改,而实际视图该行内是动画的:
However, the List
those views are embedded in doesn't animate which results in an ugly glitch because the height of the List
row changes instantly, while the actual view inside that row is animated:
我怎样才能使 List
也有动画效果?我尝试向其添加 .animation
修饰符,但没有任何作用.
How can I make the List
animate as well? I tried addinga .animation
modifier to it but that doesn't do anything.
我也不想将 tapGesture
移出视图.视图应该是自包含的,而不是依赖其他视图来控制它(我认为这就是 MVVM 的意义所在)
I also don't want to move the tapGesture
out of the view. The view should be self-contained and not rely on some other view to control it (I think that's what MVVM is about)
谢谢!
import SwiftUI
struct SubView: View {
@State var change: Bool = false
var body: some View {
Rectangle()
.frame(width: 200, height: change ? 300 : 200)
.foregroundColor(Color.red)
.onTapGesture {
withAnimation {
self.change.toggle()
}
}
}
}
struct Test: View {
var body: some View {
List {
SubView()
SubView()
}
}
}
struct Test_Previews: PreviewProvider {
static var previews: some View {
Test()
}
}
推荐答案
解决方案只是通过为此提供明确的可动画修饰符来使高度连续动画化.
The solution is just to make height animatable continuously, by providing explicit animatable modifier for this.
这是工作方法.使用 Xcode 11.4/iOS 13.4 测试.
Here is working approach. Tested with Xcode 11.4 / iOS 13.4.
简单辅助修饰符的实现
struct AnimatingCellHeight: AnimatableModifier {
var height: CGFloat = 0
var animatableData: CGFloat {
get { height }
set { height = newValue }
}
func body(content: Content) -> some View {
content.frame(height: height)
}
}
使用视图修改(其他部分不变)
Modified using view (other parts unchanged)
struct SubView: View {
@State var change: Bool = false
var body: some View {
Rectangle()
.frame(width: 200)
.modifier(AnimatingCellHeight(height: change ? 300 : 200))
.foregroundColor(Color.red)
.onTapGesture {
withAnimation {
self.change.toggle()
}
}
}
}
这篇关于SwiftUI - 在列表中的视图内触发的动画也不会为列表设置动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!