如何在SwiftUI中为有条件的呈现视图添加转换效果?

3
如何在 GroupedListStyle 列表中为有条件渲染的视图添加过渡效果?以实现像“设置”中“勿扰”部分的有条件DatePicker一样的效果(请参见下面的GIF)。
似乎无法为有条件渲染的视图添加transitionanimation效果。
if condition {
    Toggle(isOn: $foo) {
        HStack {
            Text("Foo")
        }
    }
    .transition(.opacity)
    .animation(.easeInOut)
    .toggleStyle(SwitchToggleStyle(tint: Color.red)
}

这里输入图片描述

基于pawello2222的实现

这个动画非常流畅,尤其是在视图即将消失时。从第1帧到第11帧的过渡位置是通过动画实现的,但从第12帧开始突然消失了。

这里输入图片描述

这里输入图片描述

2个回答

4

这里有一个可能的解决方案,使用 withAnimation 来更改 Published 的值。

class ContentViewModel : ObservableObject {
    @Published var isOn : Bool = false {
        didSet {
            withAnimation {
                if isOn {
                    showRow = true
                }
                else {
                    showRow = false
                }
            }
        }
    }
    
    @Published var showRow = false
}

struct ContentView: View {
    
    @ObservedObject var viewModel = ContentViewModel()
            
    var body: some View {
        
        List() {
            
            Text("Hello World")

            HStack() {
                Toggle("Test", isOn: $viewModel.isOn)
                    .toggleStyle(SwitchToggleStyle(tint: Color.red))
            }
            
            if (viewModel.showRow) {
                Text("Hello Second World")
            }
       }.listStyle(GroupedListStyle())
    }
}

3

将与动画相关的逻辑(如 withAnimation 放在视图内可能会更好。

一种可能的解决方案是创建一个自定义的 Binding

struct ContentView: View {
    @StateObject var viewModel = ViewModel()

    var binding: Binding<Bool> {
        .init(get: {
            viewModel.showRow
        }, set: { newValue in
            withAnimation {
                viewModel.showRow = newValue
            }
        })
    }

    var body: some View {
        List {
            Text("Text")
            Toggle("Toggle", isOn: binding)
                .toggleStyle(SwitchToggleStyle(tint: Color.red))
            if viewModel.showRow {
                Text("Hidden Text")
            }
        }
        .listStyle(GroupedListStyle())
    }
}

实际上这样更好。在视图中使用withAnimation比在ViewModel中使用要好得多。绑定的想法很棒。 - davidev
谢谢!在我的情况下,有条件渲染的视图位于“Section”内,动画效果不是很流畅,请参见上面的Gif。 - XY Li
不确定这是否是SwiftUI动画的bug,我已经检查了@davidev的GIF,他的动画看起来很流畅。 - XY Li

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接