SwiftUI - 在列表中的视图内触发的动画也不会为列表设置动画

Posted

技术标签:

【中文标题】SwiftUI - 在列表中的视图内触发的动画也不会为列表设置动画【英文标题】:SwiftUI - Animations triggered inside a View that's in a list doesn't animate the list as well 【发布时间】:2019-09-09 12:52:15 【问题描述】:

我有一个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()
    

【问题讨论】:

嗨,你在这方面有什么进展吗?我也有同样的事情。 不幸的是,从那以后我真的没有时间了。可能是swiftUI中的一个错误 @MichaelForrest,请参阅下面的答案。 【参考方案1】:

解决方案就是通过为此提供明确的动画修饰符来使高度连续动画化。

这是工作方法。使用 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()
                
            
    

【讨论】:

嘿,可以自动确定单元格高度吗?我不知道你会怎么做 @Quantm 也许您可以尝试使用 GeometryReader 获取单元格高度

以上是关于SwiftUI - 在列表中的视图内触发的动画也不会为列表设置动画的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:动画列表中的圆圈

SwiftUI找回丢失的列表视图(List)动画

SwiftUI找回丢失的列表视图(List)动画

navigationBarTitle 与 SwiftUI 中的列表标题重叠

一行代码为特定状态绑定SwiftUI视图动画

一行代码为特定状态绑定SwiftUI视图动画