iOS 15 Swift UI VStack 动画不会将行作为动画的一部分向下推

iOS 15 Swift UI VStack Animation doesn't push down rows as part of animating

我今天刚开始使用 Swift UI,并按照教程进行了扩展。一切都很顺利 并且动画效果很好 直到 .animation(.default) 出现弃用警告。我使用了转换为 .animation(.default, value: isOpen) 的推荐方法,该方法也有效,但 VStack 没有为行设置动画并且看起来很糟糕。我可以做些什么来解决这个问题吗?

仅包含 .animation(.default)

的示例

调整为 .animation(.default, value: isOpen)

的示例

import SwiftUI

struct FilterTest: View {
    var body: some View {
        ScrollView{
            HeaderCellTest()
            HeaderCellTest()
            HeaderCellTest()
            HeaderCellTest()
            
            Spacer()
        }
    }
}

struct HeaderCellTest: View {
    @State private var isOpen: Bool = false
    
    var body: some View {
        content
            .padding(.leading)
            .frame(maxWidth: .infinity)
    }
    
    private var content: some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack {
                Text("HEADING")
            }
            .onTapGesture { isOpen.toggle() }
            if isOpen {
                Group {
                    Text("Item")
                    Text("Item")
                    Text("Item")
                    Text("Item")
                    Text("Item")
                }
                .padding(.leading)
                
            }
            Divider()
        }
        .animation(.default, value: isOpen)
    }
}


struct FilterTest_Previews: PreviewProvider {
    static var previews: some View {
        FilterTest()
    }
}

你应该使用 VStack 并删除组!

struct FilterTest: View {
    var body: some View {
        ScrollView{
            HeaderCellTest()
            HeaderCellTest()
            HeaderCellTest()
            HeaderCellTest()
            
            Spacer()
        }
    }
}

struct HeaderCellTest: View {
    @State private var isOpen: Bool = false
    
    var body: some View {
        content
            .padding(.leading)
            .frame(maxWidth: .infinity)
    }
    
    private var content: some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack {
                Text("HEADING")
            }
            .onTapGesture { isOpen.toggle() }
            if isOpen {
                VStack {                 // <<: Here!
                    Text("Item")
                    Text("Item")
                    Text("Item")
                    Text("Item")
                    Text("Item")
                }
                .padding(.leading)
                
            }
            Divider()
        }
        .animation(.default, value: isOpen)
    }
}

当你想为变化设置动画时,你需要用 withAnimation 块围绕和修改值。

CF 文档: https://developer.apple.com/documentation/swiftui/withanimation(::)

编辑代码:

private var content: some View {
        VStack(alignment: .leading, spacing: 8) {
            HStack {
                Text("HEADING")
            }
            .onTapGesture {
                // <--- Add block for animation --->
                withAnimation {
                    isOpen.toggle()
                }
            }
            if isOpen {
                Group {
                    Text("Item")
                    Text("Item")
                    Text("Item")
                    Text("Item")
                    Text("Item")
                }
                .padding(.leading)

            }
            Divider()
        }
        .animation(.default, value: isOpen)
    }