SwiftUI - 在列表中的视图内触发的动画也不会为列表设置动画 [英] SwiftUI - Animations triggered inside a View that's in a list doesn't animate the list as well

查看:20
本文介绍了SwiftUI - 在列表中的视图内触发的动画也不会为列表设置动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆