Вынесите HomeState в ObservableObject, а представление подпишите на его изменения. При владении моделью используйте StateObject, при получении извне — ObservedObject.
Перемещение состояния экрана во внешний объект
Вынесите HomeState в ObservableObject, а представление подпишите на его изменения. При владении моделью используйте StateObject, при получении извне — ObservedObject.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Перенесите управление состоянием главного экрана из представления во внешний объект — например, во ViewModel или Service. Такой объект будет выступать в роли единственного источника правды и сможет передаваться по иерархии компонентов.
enum HomeState {
case loading
case loaded(Int)
case error(String)
}
struct HomeView: some View {
@State private var homeState: HomeState = .loading
var body: some View {
ZStack {
switch homeState {
case .loading:
ProgressView()
case .loaded(let number):
Text("Number is: \(number)")
case .error(let error):
Text("Oops! \(error)")
}
}
}
}
Ответ
Вынесите HomeState в ObservableObject, а представление подпишите на его изменения. При владении моделью используйте StateObject, при получении извне — ObservedObject.
В исходнике есть ошибка объявления: нужно struct HomeView: View, а не : some View.
import SwiftUI
@MainActor
final class HomeViewModel: ObservableObject {
@Published var state: HomeState = .loading
}
@MainActor
struct HomeView: View {
@StateObject private var model = HomeViewModel()
var body: some View {
switch model.state {
case .loading: ProgressView()
case .loaded(let number): Text("Number is: \(number)")
case .error(let error): Text("Oops! \(error)")
}
}
}
Дочернему экрану передают тот же model как @ObservedObject, либо явно внедряют через environment. Сетевые операции и переходы состояния размещают в модели; для каждого экрана не создают независимую копию источника истины.