繁体   English   中英

SwiftUI - 如何取消默认列表动画

[英]SwiftUI - how to cancel the default list animation

有没有办法在不使用列表本身的 .animation(nill) 修饰符的情况下删除默认列表行折叠动画?

正如您在下面的剪辑中看到的那样,我在列表中实现了一个动画修改器,但是默认的列表折叠动画有点破坏了所需的动画。

https://gfycat.com/cheerywelloffalleycat

我已经更新了下面的代码,这样你就可以在你的 Xcode 上运行它而没有任何依赖。

  import SwiftUI

struct CurrencyComparison: View {
    @State var mainArray = ["10", "10","10", "10", "10", "10", "10", "10", "10", "10"]
    @State var array = ["10", "10","10", "10", "10", "10", "10", "10", "10", "10"]
    @State var secondArray = ["20", "20","20", "20", "20", "20", "20", "20", "20", "20"]
    @State var hide = false
    @State var direction = false
    @State var triggerAnimation: Bool


    var body: some View {
        VStack {


                List (self.mainArray, id:\.self) { item in

                    Text(item)
                        .foregroundColor(Color.black)
                        .frame(width: 40, height: 80)
                        .padding(.leading, 80)
                        .isHidden(self.hide)
                    Spacer()
                    Text(item)
                        .foregroundColor(Color.black)
                        .frame(width: 40, height: 40)
                        .padding(.trailing, 80)
                        .isHidden(self.hide)
                }
                .background(LinearGradient(gradient: Gradient(colors: [Color.blue, Color.red]), startPoint: .center, endPoint: .center))
                .animation(Animation.spring().delay(triggerAnimation ? 0 : 0.4))
                .transition(.asymmetric(insertion: AnyTransition.opacity.combined(with: .move(edge: .trailing)), removal: .move(edge: .trailing)))
                .cornerRadius(30)
                .padding(.top, 30)
                .padding(.bottom, 30)
                .shadow(radius: 10)
                .gesture(
                    DragGesture(minimumDistance: 50)

                        .onEnded { value in
                            self.hide.toggle()

                            DispatchQueue.main.asyncAfter(deadline: .now() ) {
                                if self.mainArray == self.array {
                                    self.mainArray = self.secondArray
                                } else {
                                    self.mainArray = self.array
                                }
                            }
                            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                                self.hide.toggle()
                            }
                    }
                )
        }
        .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height + 50, alignment: .top)
        .background(Color.gray.aspectRatio(contentMode: .fill))
        .padding(.top, 120)
    }
}

struct CurrencyComparison_Previews: PreviewProvider {
    @State static var staticBool = true
    static var previews: some View {
        CurrencyComparison(triggerAnimation: true)
    }
}


extension View {
    func isHidden(_ bool: Bool) -> some View {
        modifier(HiddenModifier(isHidden: bool))
    }
}

private struct HiddenModifier: ViewModifier {

    fileprivate let isHidden: Bool

    fileprivate func body(content: Content) -> some View {
        Group {
            if isHidden {
                content.hidden()

            } else {
                content
                    .transition(.asymmetric(insertion: AnyTransition.opacity.combined(with: .slide), removal: .move(edge: .trailing)))

            }
        }
    }
}

好的,所以我设法找到了一个有效的解决方案。 通过在列表数据源发生更改时更改列表项的不透明度。

当不需要的默认动画播放时将其设置为 0,并在我想要的动画开始播放时将其恢复为 1。

这样我就可以隐藏默认列表动画而不删除我自己想要的动画:)

import SwiftUI

struct CurrencyComparison: View {
    @State var mainArray = ["10", "10","10", "10", "10", "10", "10", "10", "10", "10"]
    @State var array = ["10", "10","10", "10", "10", "10", "10", "10", "10", "10"]
    @State var secondArray = ["20", "20","20", "20", "20", "20", "20", "20", "20", "20"]
    @State var toggleHide = false
    @State var direction = false
    @State var triggerAnimation: Bool


    var body: some View {
        VStack {
            List (self.mainArray, id:\.self) { item in

                Text(item)
                    .foregroundColor(Color.black)
                    .frame(width: 40, height: 80)
                    .padding(.leading, 80)
                    .isHidden(self.toggleHide)
                    .opacity(self.toggleHide ? 0 : 1)
                Spacer()
                Text(item)
                    .foregroundColor(Color.black)
                    .frame(width: 40, height: 40)
                    .padding(.trailing, 80)
                    .isHidden(self.toggleHide)
                    .opacity(self.toggleHide ? 0 : 1)
            }
            .background(LinearGradient(gradient: Gradient(colors: [Color.blue, Color.red]), startPoint: .center, endPoint: .center))
            .animation(Animation.spring().delay(triggerAnimation ? 0 : 0.4))
            .transition(.asymmetric(insertion: AnyTransition.opacity.combined(with: .move(edge: .trailing)), removal: .move(edge: .trailing)))
            .cornerRadius(30)
            .padding(.top, 30)
            .padding(.bottom, 30)
            .shadow(radius: 10)
            .gesture(
                DragGesture(minimumDistance: 50)

                    .onEnded { value in
                        self.toggleHide.toggle()

                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                            if self.mainArray == self.array {
                                self.mainArray = self.secondArray
                            } else {
                                self.mainArray = self.array
                            }
                        }

                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.9) {
                            self.toggleHide.toggle()
                        }
                }
            )
        }
        .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height + 50, alignment: .top)
        .background(Color.gray.aspectRatio(contentMode: .fill))
        .padding(.top, 120)
    }
}

struct CurrencyComparison_Previews: PreviewProvider {
    @State static var staticBool = true
    static var previews: some View {
        CurrencyComparison(triggerAnimation: true)
    }
}


extension View {
    func isHidden(_ bool: Bool) -> some View {
        modifier(HiddenModifier(isHidden: bool))
    }
}

private struct HiddenModifier: ViewModifier {

    fileprivate let isHidden: Bool

    fileprivate func body(content: Content) -> some View {
        Group {
            if isHidden {
                content.hidden()

            } else {
                content
                    .transition(.asymmetric(insertion: AnyTransition.opacity.combined(with: .slide), removal: .move(edge: .trailing)))

            }
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM