Add a dynamic List to display downloaded coins | SwiftUI Crypto App #5
EnviornmentObject
생성import Foundation
class HomeViewModel: ObservableObject {
@Published var allCoins: [CoinModel] = []
@Published var portfolioCoins: [CoinModel] = []
init() {
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
self.allCoins.append(DeveloperPreview.shared.coin)
self.portfolioCoins.append(DeveloperPreview.shared.coin)
}
}
}
ObservableObject
로 선언한 HomeViewModel
@Published
프로토콜을 따르는 allCoins
, portfolioCoins
등 변수의 값의 변화를 뷰에서 감지 가능import SwiftUI
@main
struct CryptoAppBootCampApp: App {
@StateObject private var viewModel = HomeViewModel()
var body: some Scene {
WindowGroup {
NavigationView {
HomeView()
.toolbar(.hidden)
}
.environmentObject(viewModel)
}
}
}
environmentObject
import SwiftUI
struct HomeView: View {
@EnvironmentObject private var viewModel: HomeViewModel
@State private var showPortfolio: Bool = false
...
environmentObject
를 관리하기 위해 @EnvironmentObject
를 선언 private var allCoinsList: some View {
List {
ForEach(viewModel.allCoins) { coin in
CoinRowView(coin: coin, showHoldingsColumn: false)
.listRowInsets(.init(top: 10, leading: 0, bottom: 0, trailing: 10))
}
}
.listStyle(.plain)
}
allCoins
데이터를 통해 동적 리스트를 그리는 UICoinRowView
뷰를 셀로 사용private var portfolioCoinsList: some View {
List {
ForEach(viewModel.portfolioCoins) { coin in
CoinRowView(coin: coin, showHoldingsColumn: true)
.listRowInsets(.init(top: 10, leading: 0, bottom: 0, trailing: 10))
}
}
}
portfolioCoins
데이터를 활용private var columnTitles: some View {
HStack {
Text("Coin")
Spacer()
if showPortfolio {
Text("Holdings")
}
Text("Prices")
.frame(width: UIScreen.main.bounds.width / 3.5, alignment: .trailing)
}
.font(.caption)
.foregroundColor(Color.theme.secondaryText)
.padding(.horizontal)
}
import SwiftUI
struct HomeView: View {
@EnvironmentObject private var viewModel: HomeViewModel
@State private var showPortfolio: Bool = false
var body: some View {
ZStack {
// background layer
Color.theme.background
.ignoresSafeArea()
// content layer
VStack {
homeHeader
columnTitles
if !showPortfolio {
allCoinsList
.transition(.move(edge: .leading))
}
if showPortfolio {
portfolioCoinsList
.transition(.move(edge: .trailing))
}
Spacer(minLength: 0)
}
}
}
}
showPortfolio
변수 값에 따라 리스트 종류를 변경