Как обновить ScrollView в SwiftUI при обновлении массива отображаемых объектов? - PullRequest
0 голосов
/ 13 марта 2020

Я заканчиваю свое первое приложение 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)

            }

        }

    }

}

Заранее благодарю за любую помощь, которую вы можете оказать мне. Всем хорошего дня и удачного кодирования!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...