SwiftUI嵌套的过渡和动画

时间:2020-03-20 02:14:22

标签: swiftui transition swiftui-animation

我有一个水平ScrollView,其中容纳一些Rectangle。我想要实现的是淡出每个Rectangle,然后隐藏(删除)ScrollView

我已经部分实现了这一目标:

enter image description here

我之所以这样说,部分原因是,如您所见,Rectangle被删除了,但是ScrollView仍然存在(请参阅属于ScrollView的蓝色边框框,我添加了一些填充或使其更加可见)

我认为我可能需要嵌套过渡(每个Rectangle都有一个.move(edge:)过渡,ScrollView应该有另一个“外部”过渡-但这也可以是错误的方法。

有什么想法如何实现此动画,以及在动画结束时转换(删除)ScrollView?我尝试了其他选择,但失败了。注意:黑色的Rectangle是固定的。

这是示例代码:

struct TestAnimation: View {
    @State var show : Bool = true
    var colors : [Color] = [.red, .orange, .yellow, .green, .blue]

    var body: some View {
        VStack(alignment: .leading) {
            Spacer()

            Color.purple
                .frame(height: 100)
                .overlay(
                    Text("Tap Me!").foregroundColor(.white))
                .onTapGesture {
                    self.show.toggle()
            }

            HStack(alignment: .bottom) {
                Rectangle()
                    .fill(Color.black)
                    .frame(width: 70, height: 100)
                    .overlay(Text("A").foregroundColor(.white).font(.largeTitle))
                    .padding(8)

                    ScrollView(.horizontal, showsIndicators: false) {

                        HStack(alignment: .bottom) {
                            if show {
                                self.cellForItemAt(idx: 2)
                                self.cellForItemAt(idx: 3)
                                self.cellForItemAt(idx: 4)
                                self.cellForItemAt(idx: 5)
                            }
                        }
                        .frame(height: 100)
                        .padding(4)
                        .border(Color.red)//HStack


                    }//Scrollview
                    .padding(4)
                    .border(Color.blue)

            }
            .padding(4)
            .border(Color.gray)//Hstack
        }
    }

    func cellForItemAt(idx: Int) -> some View {
        return Rectangle()
            .fill(colors[idx-1])
            .frame(width: 70, height: 100)
            .transition(AnyTransition.move(edge: .bottom).combined(with: .opacity).animation(self.ripple(idx: idx)))
            .animation(ripple(idx: idx))
    }

    func ripple(idx: Int) -> Animation {
        Animation
            .easeInOut(duration: 0.8)
            .delay(0.20 * Double(colors.count - idx) : Double(idx))
    }
}

1 个答案:

答案 0 :(得分:0)

我对您的问题的解决方案是,仅为滚动视图创建一个新的state,然后将“矩形”包装在“组”中,并将该组包装在“ if show”和“ onDisappear”上的{{1 }}

最后,请确保在点击self.showScroll = false时将Tap Me!设置为showScroll

这是最优雅的方式吗?不,但是可以完成工作! enter image description here

true