如何在 SwiftUI 中为其设置动画?

问题描述 投票:0回答:1

我是 iOS 开发新手,一直在使用 SwiftUI 开发一个项目。我有一张可以买卖一些股票的表格。交易成功后,我应该显示一个带有成功消息的绿屏。问题是我的实现只是突然显示绿屏,而不是动画/淡入。这就是我的意思: 这就是我的应用程序的行为方式并且这就是我希望它的行为方式

这是该表的代码:

//
//  TradingSheetView.swift
//  Stock Search
//
//  Created by Kishan  on 4/29/24.
//

import SwiftUI
import SimpleToast

struct TradingSheetView: View {
    
    @EnvironmentObject var root: ToastViewModel
    @StateObject var viewModel = TradingSheetViewModel()
    
    @Binding var isTrading: Bool
    @Binding var company: Company?
    @Binding var portfolio: Portfolio?
    @Binding var wallet: Wallet?
    
    private var tradingQuantity: Int {
        let tradingQuantityInt = Int(viewModel.tradingQuantity)
        //      if tradingQuantityInt == nil {
        //          root.showToast(saying: "Please enter a valid amount")
        //      }
        return tradingQuantityInt ?? 0
    }
    
    private var tradingAmount: Double {
        return (viewModel.quote?.c ?? 0) * Double(tradingQuantity)
    }
    
    var body: some View {
        ZStack {
            VStack {
                HStack {
                    Spacer()
                    Button {
                        isTrading.toggle()
                    } label: {
                        Image(systemName: "xmark")
                            .foregroundStyle(Color(.label))
                    }
                }
                
                Text("Trade \(company?.name ?? "") shares")
                    .bold()
                
                Spacer()
                
                HStack {
                    TextField("0",
                                        text: $viewModel.tradingQuantity)
                    .font(.system(size: 100, weight: .light))
                    .keyboardType(.numberPad)
                    
                    Text(tradingQuantity > 1 ? "Shares" : "Share")
                        .font(.largeTitle)
                        .offset(y: 20)
                }
                
                HStack {
                    Spacer()
                    
                    Text("x $\((viewModel.quote?.c ?? 0).getTwoPointsString())/share = $\(tradingAmount.getTwoPointsString())")
                }
                
                Spacer()
                
                Text("$\((wallet?.amount ?? 0).getTwoPointsString()) available to buy \(company?.ticker ?? "")")
                    .font(.caption)
                    .foregroundStyle(.secondary)
                    .padding()
                
                HStack(spacing: 20) {
                    Button {
                        Task {
                            if tradingAmount > (wallet?.amount ?? 0) {
                                root.showToast(saying: "Not enough money to buy")
                                return
                            }
                            if tradingQuantity <= 0 {
                                root.showToast(saying: "Cannot buy non-positive shares")
                                return
                            }
                            await viewModel.buy(tradingQuantity,
                                                                    of: company?.ticker,
                                                                    at: viewModel.quote?.c,
                                                                    called: company?.name)
                        }
                    } label: {
                        PortfolioDetailsButton(title: "Buy")
                    }
                    Button {
                        Task {
                            if tradingQuantity > (portfolio?.quantity ?? 0) {
                                root.showToast(saying: "Not enough shares to sell")
                                return
                            }
                            if tradingQuantity <= 0 {
                                root.showToast(saying: "Cannot sell non-positive shares")
                                return
                            }
                            await viewModel.sell(tradingQuantity,
                                                                     of: company?.ticker,
                                                                     at: viewModel.quote?.c)
                        }
                    } label: {
                        PortfolioDetailsButton(title: "Sell")
                    }
                }
            }
            .padding()
            .onAppear() {
                Task {
                    await viewModel.fetchCurrentQuote(for: company?.ticker ?? "")
                }
            }
            
            if viewModel.transactionSuccess {
                withAnimation(.easeInOut.speed(5)) {
                    ZStack {
                        Color.green.ignoresSafeArea()
                        
                        VStack() {
                            Spacer()
                            
                            Text("Congratulations!")
                                .bold()
                                .font(.largeTitle)
                                .foregroundStyle(.white)
                            
                            Text(viewModel.transactionMessage)
                                .font(.callout)
                                .foregroundStyle(.white)
                                .padding(.vertical, 1)
                            
                            Spacer()
                            
                            Button {
                                isTrading.toggle()
                            } label: {
                                Text("Done")
                                    .bold()
                                    .frame(width: 350, height: 50)
                                    .background(in: .capsule)
                                    .foregroundStyle(.green)
                            }
                        }
                        .padding()
                    }
                }
            }
        }
        .simpleToast(isPresented: $root.isToastVisible,
                 options: root.toastOptions) {
            ToastView(message: $root.toastMessage)
        }
    }
}

#Preview {
    TradingSheetView(isTrading: .constant(true),
                                     company: .constant(mockCompany),
                                     portfolio: .constant(mockPortfolio),
                                     wallet: .constant(mockWallet))
}

Edit:
正如下面@Sweeper 所说,我尝试复制视图。我不确定它是否完全复制它,但这是代码:

//
//  TestView.swift
//  Stock Search
//
//  Created by Kishan  on 4/29/24.
//

import SwiftUI

struct TestView: View {
    
    @State var success = false
    
    var body: some View {
        ZStack {
            
            Button("Press here to perform transaction") {
                Task {
                    await performTransaction()
                }
            }
            
            if success {
                ZStack {
                    Color.green.ignoresSafeArea()
                    
                    VStack {
                        Text("Congratulations!")
                            .bold()
                            .font(.title)
                            .foregroundStyle(.white)
                            .padding(.vertical)
                        
                        Button {
                            Task {
                                await performTransaction()
                            }
                        } label: {
                            Text("Done")
                                .bold()
                                .frame(width: 300, height: 50)
                                .background(in: .capsule)
                                .foregroundStyle(.green)
                        }
                    }
                }
            }
        }
    }
    
    func performTransaction() async {
        // Perform some transaction
        success.toggle()
    }
}

#Preview {
    TestView()
}

我也尝试过使用

.animation
修饰符和
withAnimation
,但似乎不起作用。是否有什么可能与动画的执行方式相冲突?

ios swift swiftui swiftui-animation
1个回答
0
投票
func performTransaction() async {
    // Perform some transaction
    withAnimation(.easeIn.speed(0.6)) {
        success.toggle()
    }
}

阅读有关动画的更多信息https://www.hackingwithswift.com/quick-start/swiftui,向下滚动到动画

© www.soinside.com 2019 - 2024. All rights reserved.