简体   繁体   English

在 SwiftUI 中动画添加/删除视图

[英]Animate Addition/Removal of View in SwiftUI

I have created a bottom alert that I want to animate when it is to be presented or removed.我已经创建了一个底部警报,我想在显示或删除它时设置动画。 Currently it is not doing any animation, only showing up and removing itself when needed.目前它没有做任何动画,只在需要时显示和删除自己。

I've tried using .transition(.move(edge: .bottom)) on the actual view but no animation is shown.我试过在实际视图上使用.transition(.move(edge: .bottom))但没有显示动画。

How can I add a slide up/down animation for this view?如何为此视图添加向上/向下滑动动画?

var body: some View {
    ZStack {
        VStack {
            toolbar
            Spacer()
            switch viewModel.status {
            case .loading:
                LoadingView(isAnimating: $isLoading)
            case .loaded(_):
                productView
            case .error(_):
                Text("Please Retry.")
                    .onAppear {
                        buildBottomAlert(type: .error)
                    }
            }
        }
        
        VStack {
            Spacer()
            if let bottomView = bottomAlertView {
                bottomView
                    .transition(.move(edge: .bottom))
            }
        }
        }
}

Bottom Alert Builder底部警报生成器

func buildBottomAlert(type: BottomAlertType) {
    self.bottomAlertView = BottomAlert(type: type)
    self.showBottomAlert = true
    DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
        self.removeBottomAlert()
    }
}

func removeBottomAlert() {
    bottomAlertView = nil
    showBottomAlert = false
}

For animation, you need to add your show/hide code inside body of withAnimation function.对于动画,您需要在withAnimation函数体内添加显示/隐藏代码。

withAnimation {
    buildBottomAlert(type: .error)
}

Also, update your buildBottomAlert function like this.另外,像这样更新您的buildBottomAlert函数。

func buildBottomAlert(type: BottomAlertType) {
    self.bottomAlertView = BottomAlert(type: type)
    self.showBottomAlert = true
    Task {
        //Sleep for 2 seconds
        try await Task.sleep(nanoseconds: 2_000_000_000)
        withAnimation {
            removeBottomAlert()
        }
    }
}

Note: I have used sleep(nanoseconds:) instead of asyncAfter(deadline:execute:) .注意:我使用sleep(nanoseconds:)而不是asyncAfter(deadline:execute:)

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

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