#swift #swiftui
#swift #swiftui
Вопрос:
Я загружаю данные из FireStore. Данные извлекаются идеально. У меня есть данные, и я могу распечатать информацию. Проблема в том, что когда я нажимаю на текст / метку, чтобы перейти к предполагаемому виду, я выполняю функцию, используя .onAppear
функцию. Мои переменные, из моего ObservableClass
являются @Published
. У меня есть данные, и я даже могу устанавливать элементы на основе полученных данных. Я использую подход MVVM и делал это множество раз на протяжении всего моего проекта. Тем не менее, это первый раз, когда у меня возникает эта конкретная проблема. Я даже использовал функции, которые работают в других представлениях совершенно нормально, но в этом конкретном представлении эта проблема сохраняется. Когда я загружаю / нажимаю это представление, данные отображаются в течение доли секунды, а затем вид / холст пуст. Если элементы не являются статическими, т.е. Text("Hello World")
элементы исчезнут. Я не могу понять, почему данные просто решают исчезнуть.
Это мой код:
struct ProfileFollowingView: View {
@ObservedObject var profileViewModel = ProfileViewModel()
var user: UserModel
func loadFollowing() {
self.profileViewModel.loadCurrentUserFollowing(userID: self.user.uid)
}
var body: some View {
ZStack {
Color(SYSTEM_BACKGROUND_COLOUR)
.edgesIgnoringSafeArea(.all)
VStack(alignment: .leading) {
if !self.profileViewModel.isLoadingFollowing {
ForEach(self.profileViewModel.following, id: .uid) { user in
VStack {
Text(user.username).foregroundColor(.red)
}
}
}
}
} .onAppear(perform: {
self.profileViewModel.loadCurrentUserFollowing(userID: self.user.uid)
})
}
}
Это моя loadFollowers
функция:
func loadCurrentUserFollowing(userID: String) {
isLoadingFollowing = true
API.User.loadUserFollowing(userID: userID) { (user) in
self.following = user
self.isLoadingFollowing = false
}
}
Я просмотрел свой код, который извлекает данные, и он точно такой же, как другие функции, которые у меня уже есть. Это просто происходит в этом представлении.
Комментарии:
1. Не могли бы вы удалить
VStack(alignment: .leading)
код и, пожалуйста, попробовать его. Я еще не пробовал, но у меня было много такого необычного поведения, когда я использовалVstack
несколько раз. Поэтому, пожалуйста, попробуйте.2. @Sona Я устал. Все та же проблема. Я даже использовал DispatchMain. Qeue для моей функции.
3. Когда я пробовал со статическими значениями, ваш код работал отлично. Пожалуйста, отладьте вашу функцию вызова API, чтобы проверить,
self.following
равно нулю или нет. У меня нет никаких проблем в вашем коде: (4. @Sona У меня была такая же проблема. Со статическими переменными все в порядке. Я использовал / вызывал другие функции, которые отлично работают в моем приложении, и та же проблема сохраняется. Я использую навигационную ссылку, которая открывает представление. И при появлении я вызываю функцию.
Ответ №1:
Изменить @ObservedObject
на @StateObject
Обновление: ObservedObject легко уничтожается / создается заново при каждом повторном создании представления, в то время как StateObject остается / существует даже при повторном создании представления. Для получения дополнительной информации посмотрите это видео: https://www.youtube.com/watch?v=VLUhZbz4arg
Ответ №2:
Похоже, API.User.loadUserFollowing(userID:)
может быть асинхронным — может выполняться в фоновом режиме. Вам необходимо обновить все @Published
переменные в основном потоке:
func loadCurrentUserFollowing(userID: String) {
isLoadingFollowing = true
API.User.loadUserFollowing(userID: userID) { (user) in
DispatchQueue.main.async {
self.following = user
self.isLoadingFollowing = false
}
}
}
Комментарии:
1. Просто пытался, и безуспешно. Я действительно пробовал это делать, но на . На мой взгляд, метод Appear().
2. @SwiftUser Ваш код в onAppear в любом случае выполняется в основном потоке. Просто ищите асинхронные функции, которые задают
@Published
/@State
свойства.3. Есть идеи, зачем мне сейчас нужны асинхронные функции? Все это время они мне не были нужны. Это просто кажется странным.
4. @SwiftUser Я просто говорю, что
API.User.loadUserFollowing(userID:)
выглядит как асинхронная функция — как и большинство функций API.5. Да, я пытался. Не повезло. Думаю, это серьезная ошибка в SwiftUI
Ответ №3:
Возможно, вам потребуется добавить примерно так: «DispatchQueue.main.asyncAfter».
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() 1.0) {
self.profileViewModel.loadCurrentUserFollowing(userID: self.user.uid)
}
}