Я заканчиваю свое первое приложение SwiftUI и столкнулся с этой проблемой, которую, похоже, не могу решить. У меня есть горизонтальный ScrollView, который отображает массив созданных пользователем Categories , и у меня есть кнопка на панели навигации, которая открывает представленное представление «Toast»; позволяя пользователю добавить категорию . После нажатия кнопки в представлении «Toast» представление закрывается, добавляет новую Category в коллекцию документов категорий, которые есть в моей базе данных Firebase, а затем обновляет глобальные category массив в моем приложении на основе онлайн-данных. Все это сделано успешно (я вижу, что в моей онлайн-базе данных документ создан, и по завершении обновления глобального массива category я распечатал его содержимое, и оно также было извлечено). Однако ScrollView остается неизменным, даже если он отображает массив, который был обновлен. Единственный раз, когда обновления ScrollView обновляются, когда я перезагружаю приложение или когда я выхожу из системы и снова вхожу в нее. В основном я хочу сделать следующее:
Как сделать Я правильно обновляю ScrollView мгновенно, зная, что мои данные (глобальный массив category ) были обновлены? Нужно ли сделать массив category наблюдаемым объектом? И если да, то как мне это реализовать?
Дополнительное примечание: массив category находится в моем локальном файле данных вместе с функциями, которые соответственно обновляют его, например, как функция getUserCategories в представлении Toast ниже.
Вот мое представление категорий:
struct CategoriesView: View {
@State var showToast: Bool = false
var body: some View {
NavigationView {
Background{
VStack{
ScrollView(.horizontal, showsIndicators: false){
HStack(spacing: 20){
ForEach(categories){ category1 in
GeometryReader{ geometry in
CategoryCardView(
category: category1
)
.rotation3DEffect(Angle(degrees: Double(geometry.frame(in: .global).minX) - 40) / -20, axis: (x: 0, y: 10.0, z: 0))
}.frame(width: 300, height: 550)
}
}.padding(.leading, 40).padding(.trailing, 40)
}
}
.frame(width: UIScreen.main.bounds.width, height: 460)
.navigationBarTitle("Categories").navigationBarItems(trailing: Button(action: {
withAnimation {
self.showToast.toggle()
}
}){
Image(systemName: "folder.fill.badge.plus").resizable()
.frame(width:50, height:35)
})
}.onTapGesture(perform: endEditing)
}.toast(isShowing: self.$showToast)
}
private func endEditing() {
UIApplication.shared.endEditing()
showToast = false
}
}
А вот мое представление «Toast» (это не так) Это не имеет отношения к проблеме, но я подумал, что я все равно включу ее в качестве двух представлений go (рука об руку):
struct Toast<Presenting>: View where Presenting: View {
/// The binding that decides the appropriate drawing in the body.
@Binding var isShowing: Bool
/// The view that will be "presenting" this toast
let presenting: () -> Presenting
/// The text to show
@State private var text: String = ""
var body: some View {
GeometryReader { geometry in
ZStack(alignment: .center) {
self.presenting()
.blur(radius: self.isShowing ? 3 : 0)
VStack {
TextField("Category Name", text: self.$text)
.padding(.leading)
.padding(.trailing)
.frame(width: 200, height: 40)
.border(Color.black, width: 1)
.cornerRadius(3)
.frame(width: 200, height: 40)
.padding(.bottom)
Button(action:{
withAnimation{
let cUser = Firebase.Auth.auth().currentUser
let db = Firestore.firestore()
//NEW CATEGORY IS ADDED TO DATABASE
let newCategory = db.collection("users").document(cUser!.uid).collection("categories").document()
newCategory.setData(["id":newCategory.documentID, "name": self.text])
//GLOBAL ARRAY UDPATES HERE
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
getUserCategories()
}
UIApplication.shared.endEditing()
self.isShowing = false
}
}){
Text("Create Category")
.font(.headline)
.fontWeight(.heavy)
.padding()
.frame(width: 200, height: 30) .background(Color.black)
.foregroundColor(Color.white)
.cornerRadius(10)
}
}
.frame(width: geometry.size.width / 1.5,
height: geometry.size.height / 5)
.background(Color.primary.colorInvert())
.foregroundColor(Color.secondary)
.cornerRadius(20)
.transition(.slide)
.opacity(self.isShowing ? 1 : 0)
}
}
}
}
Заранее благодарю за любую помощь, которую вы можете оказать мне. Всем хорошего дня и удачного кодирования!