When a view is getting too big even after extracting some parts in small files, it's a good idea to create a ViewModel in order to separate the business logic from the view. The ViewModel will store all the propeties and the functions related to the models.
The ViewModel will be created in a different file called ContentViewViewModel.swift.
import SwiftUI
@Observable
class ContentViewViewModel {
var shoppingList: [String] = [
"Potato",
"Tomato",
"Chicken",
"Salmon"
]
func removeAt(index: Int) {
guard index < shoppingList.count else {
return
}
shoppingList.remove(at: index)
}
}
Let's highlight the main differences:
- In order to use our ViewModel as a
@State
variable later, we need to tag it as@Observable
. - We'll create this object as a
class
. - Variables don't need to be tagged as
State
.
Then we can declare the viewModel
variable in our ContentView
, and add the view components using viewModel
this time.
import SwiftUI
struct ContentView: View {
@State var viewModel = ContentViewViewModel()
var body: some View {
List(0..<viewModel.shoppingList.count, id: \.self) { index in
Button {
viewModel.removeAt(index: index)
} label: {
Text(viewModel.shoppingList[index])
}
}
}
}
#Preview {
ContentView()
}
Result
You can find all this code together in our samples repository, here.
Be the first to comment