ios - SwiftUI - 在列表中的视图内触发的动画也不会为列表设置动画
问题描述
我有一个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()
}
}
}
}
推荐阅读
- node.js - Object seems undefined inside forEach loop
- java - Smallest element in largest row
- canvas - Can't add SpriteCanvasMaterial in three.js r94
- validation - 如何在 tcomb-form-native 中使用secureTextEntry?
- javascript - 在 JavaScript 中使用 Google Maps API 查找当前位置
- c# - How to populate a combobox with query that contains user input?
- google-maps - billing clients for google api's
- java - QueryRecord vs. PartitionRecord for better performance?
- c# - ASP.Net Core 2 Web API performance metrics in database
- visual-studio-code - How to show vscode debug console?