如何在 SwiftUI 中制作“显示”式的折叠/展开动画?

Posted

技术标签:

【中文标题】如何在 SwiftUI 中制作“显示”式的折叠/展开动画?【英文标题】:How to do a "reveal"-style collapse/expand animation in SwiftUI? 【发布时间】:2022-01-20 14:24:34 【问题描述】:

我想在 SwiftUI 中实现一个动画,“显示”视图的内容以启用展开/折叠功能。我要折叠和展开的视图内容很复杂:它不仅仅是一个简单的框,而是一个动态高度和内容的视图层次结构,包括图像和文本。

我尝试了不同的选项,但都没有达到预期的效果。通常发生的情况是,当我“展开”时,整个视图立即以 0% 的不透明度显示,然后逐渐淡入,展开视图下方的按钮同时向下移动。这就是我使用条件if 语句实际添加和删除视图时发生的情况。所以这是有道理的。

然后我尝试使用frame 修饰符:.frame(maxHeight: isExpanded ? .infinity : 0)。但这导致视图的内容被“压缩”而不是显示。

我做了一个我想要的纸质原型:

关于如何实现这一点的任何想法?

【问题讨论】:

这应该会有所帮助(另请参阅此答案中的链接)***.com/a/62482773/12299030。 @Asperi 非常感谢! 【参考方案1】:

这样的事情可能会奏效。您可以将要显示的高度修改为隐藏时为 0,或者在不隐藏时修改为 nil,以便它将达到视图定义的高度。确保之后剪辑视图,以便在未公开时内容在框架高度之外不可见。

struct ContentView: View 
    @State private var isDisclosed = false
    
    var body: some View 
        VStack 
            Button("Expand") 
                withAnimation 
                    isDisclosed.toggle()
                
            
            .buttonStyle(.plain)
            
            
            VStack 
                GroupBox 
                    Text("Hi")
                
                
                GroupBox 
                    Text("More details here")
                
            
            .frame(height: isDisclosed ? nil : 0, alignment: .top)
            .clipped()
            
            HStack 
                Text("Cancel")
                Spacer()
                Text("Book")
            
        
        .frame(maxWidth: .infinity)
        .background(.thinMaterial)
        .padding()
    

不,这也不是为了匹配您的设计。这只是为了提供创建动画的示例方法。

【讨论】:

太棒了!这正是我需要的,非常感谢!我认为clippedalignment: .top的组合是关键。

以上是关于如何在 SwiftUI 中制作“显示”式的折叠/展开动画?的主要内容,如果未能解决你的问题,请参考以下文章

ExtJS可折叠面板在展开时不呈现工具栏?

拆分视图控制器折叠/展开时更新表格单元格附件

在 SwiftUI (Xcode 12) 中折叠侧边栏

修改swiftui数组值

折叠/展开时动画字体真棒雪佛龙图标旋转

如何在 webview 中制作可折叠列表/内容