1

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

我已经部分实现了这一点:

在此处输入图像描述

我说的部分原因是,如您所见,Rectangles 已被删除,但 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))
    }
}
4

1 回答 1

0

我对您的问题的解决方案是单独为滚动视图创建一个新state的,然后将矩形包装在一个组中并将该组包装if showonDisappear集合中self.showScroll = false

最后,确保在点击Tap Me!时设置showScrolltrue

这是最优雅的方式吗?不,但它可以完成工作! 在此处输入图像描述

//
//  TestAnimation.swift
//  playground
//
//  Created by Muhand Jumah on 3/20/20.
//  Copyright © 2020 Muhand Jumah. All rights reserved.
//

import SwiftUI

struct TestAnimation: View {
    @State var show : Bool = true
    @State var showScroll: 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.showScroll = true
                    self.show.toggle()
            }

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

                if(showScroll) {
                    ScrollView(.horizontal, showsIndicators: false) {

                        HStack(alignment: .bottom) {
                            if show {
                                Group {
                                    self.cellForItemAt(idx: 2)
                                    self.cellForItemAt(idx: 3)
                                    self.cellForItemAt(idx: 4)
                                    self.cellForItemAt(idx: 5)
                                }.onDisappear {
                                    self.showScroll = false
                                }
                            }
                        }
                        .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))
    }
}

struct TestAnimation_Previews: PreviewProvider {
    static var previews: some View {
        TestAnimation()
    }
}


于 2020-03-20T22:00:57.883 回答