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屋!