#swiftui
#swiftui
Вопрос:
У меня есть простое приложение с TabView и 4 разными вкладками в нем. В моем втором представлении я хочу вызвать make API, чтобы получить больший тип данных.
Проблема у меня есть. Чтобы предотвратить множественные внутренние запросы, моя идея состояла в том, чтобы выполнить начальный вызов жизненного цикла Appear() вместо добавления его в ViewModel init() , потому что эта часть вызывается при каждом изменении TabView.
Однако отображаемый код не обновляется, если я вызываю сетевой запрос из onAppear.
Если я вызываю mockApiCall из ViewModel init(). затем данные обновляются, и представление также обновляется. Однако, как я упоминал ранее, я не хочу этого делать, потому что при каждом изменении вкладки будет много запросов
import SwiftUI
class TabsViewModel: ObservableObject {
var shopView: some View {
ViewsBuilder.makeShopView()
}
struct ViewsBuilder {
static func makeShopView() -> some View {
ShopView(viewModel: .init())
}
}
}
//To reproduce go to second tab, view is loaded, go to first tab and then again go to second one
struct TabsView: View {
@ObservedObject
var viewModel: TabsViewModel
@State
private var selection = 1
var body: some View {
TabView(
selection: $selection) {
Text("Tab Content 1")
.tabItem {
if selection == 1 {
Image(systemName: "star.fill")
} else {
Image(systemName: "star")
}
//it works if I set Image(systemName: "star.fill") instead of if statement
}
.tag(1)
viewModel
.shopView
.tabItem {
if selection == 2 {
Image(systemName: "star.fill")
} else {
Image(systemName: "star")
}
//it works if I set Image(systemName: "star.fill") instead of if statement
}
.tag(2)
}
}
}
struct ShopView: View {
@ObservedObject
var viewModel: ShopViewModel
var body: some View {
VStack {
ForEach(viewModel.mockedUser) { user in
Text(user.name)
}
}
.onAppear() {
viewModel.mockApiCall()
}
}
}
class ShopViewModel: ObservableObject {
@Published
var mockedUser: [TestUser] = []
func mockApiCall() {
print("API CALLED")
DispatchQueue.main.asyncAfter(deadline: .now() 1.0) {
self.mockedUser = [
TestUser(id: 1, name: "Test"),
TestUser(id: 2, name: "User2")
]
}
}
struct TestUser: Identifiable {
let id: Int
let name: String
}
}
Комментарии:
1. Он все равно должен работать, вызывая api из onAppear. Я запустил ваш код на iOS 14.2, и он работает.
2. Отлично работает с Xcode 12.1 / iOS 14.1. Я предполагаю, что проблема в каком-то другом коде. Не могли бы вы подробнее рассказать?
Ответ №1:
Не удалось найти правильное решение, поэтому решил продолжить с аннотацией StateObject для моделей просмотра