SwiftUI - 在列表中的视图内触发的动画也不会为列表设置动画
SwiftUI - Animations triggered inside a View that's in a list doesn't animate the list as well
我有一个 List
显示两个相同类型的 Views
。当您点击其中一个视图时,它们会通过动画更改高度。
但是,List
那些嵌入的视图没有动画,这会导致一个丑陋的故障,因为 List
行的高度会立即改变,而该行内的实际视图是动画:
如何让 List
也具有动画效果?我试着给它添加一个 .animation
修饰符,但这没有任何作用。
我也不想将 tapGesture
移出视图。视图应该是独立的,而不是依赖于其他视图来控制它(我认为这就是 MVVM 的意义所在)
谢谢!
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()
}
}
解决方案是通过为此提供明确的可动画修饰符,使高度连续可动画。
这是工作方法。使用 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)
}
}
使用视图修改(其他部分不变)
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()
}
}
}
}
我有一个 List
显示两个相同类型的 Views
。当您点击其中一个视图时,它们会通过动画更改高度。
但是,List
那些嵌入的视图没有动画,这会导致一个丑陋的故障,因为 List
行的高度会立即改变,而该行内的实际视图是动画:
如何让 List
也具有动画效果?我试着给它添加一个 .animation
修饰符,但这没有任何作用。
我也不想将 tapGesture
移出视图。视图应该是独立的,而不是依赖于其他视图来控制它(我认为这就是 MVVM 的意义所在)
谢谢!
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()
}
}
解决方案是通过为此提供明确的可动画修饰符,使高度连续可动画。
这是工作方法。使用 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)
}
}
使用视图修改(其他部分不变)
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()
}
}
}
}