Как обновить sh представление контейнера (перезагрузить табличное представление) после получения данных из firebase: Swift - PullRequest
0 голосов
/ 20 июня 2020

Я работаю над приложением. Я новичок, поэтому не обращайте внимания на любые ошибки.

Проблема в том, что у меня есть контроллер представления, который имеет 2 контроллера представления контейнера, управляемых сегментированным элементом управления.

введите описание изображения здесь

Все три из них имеют отдельные классы: (скажем)

  1. MainViewController
  2. FirstViewController
  3. SecondViewController

В главном контроллере представления я получаю некоторые данные от firebase, которые я храню в массиве, и этот массив должен быть передан в первое и второе представления контейнера, у которых есть свои представления таблиц, которые будут загружаться данные, основанные на переданном массиве.

Теперь, прежде чем данные вернутся в MainViewController, контроллеры первого и второго представления уже передаются с пустым массивом, и никакие данные не загружаются в их представления таблиц (очевидно, поскольку массив пуст).

Я хочу, чтобы контроллеры представления контейнера загружались после получения данных, и массив загружен. Любая помощь?, Спасибо

Ps Я не выполняю никаких переходов, потому что это представления контейнера, и они автоматически загружаются при загрузке контейнера основного представления.

РЕДАКТИРОВАТЬ: Более точный и понятный исходный код: изначально у меня было 3 контроллера представления

  1. SearchResultsScreenViewController (Main V C)
  2. GuidesListSearchScreenViewController (First Container V C)
  3. ServicesListSearchScreenViewController (Второй контейнер V C)

В основном V C я использовал сегментированный элемент управления, чтобы увидеть контейнер v c на экран, здесь:

import UIKit
import Firebase

class SearchResultsScreenViewController: UIViewController
{
    
    @IBOutlet weak var GuideListView: UIView!
    @IBOutlet weak var ServicesListView: UIView!
    
    var searchQueryKeyword: String?
    var guidesDataArray = [GuideDM]()
    
    override func viewDidLoad()
    {
        super.viewDidLoad()
        
        ServicesListView.isHidden = true
        populateGuidesList()
    }
   
    
    @IBAction func SegmentChanged(_ sender: UISegmentedControl)
    {
        switch sender.selectedSegmentIndex
            {
            case 0:
                GuideListView.isHidden = false
                ServicesListView.isHidden = true
                break
            case 1:
                GuideListView.isHidden = true
                ServicesListView.isHidden = false
                break
            default:
                break
            }
    }
    
    func populateGuidesList()
    {
        let dbRef = Firestore.firestore().collection("guide")
        dbRef.getDocuments
        { (snapshot, error) in
            if let err = error
            {
                print(err.localizedDescription)
                print("Error: Unable to find guides list")
            }
            else
            {
                if let snap = snapshot
                {
                    print("List is started now")
                    for doc in snap.documents
                    {
                        if doc.exists
                        {
                            let data = doc.data()
                            let city = data["city"] as? String ?? ""
                            let province = data["province"] as? String ?? ""
                            let country = data["country"] as? String ?? ""
                            if city.localizedCaseInsensitiveContains(self.searchQueryKeyword!) || province.localizedCaseInsensitiveContains(self.searchQueryKeyword!) || country.localizedCaseInsensitiveContains(self.searchQueryKeyword!)
                            {
                                let guideId = doc.documentID
                                let guideEmail = data["email"] as? String ?? ""
                                let name = data["name"] as? String ?? ""
                                let dob = data["dob"] as? String ?? ""
                                let feeCurrency = data["feeCurrency"] as? String ?? ""
                                let status = data["status"] as? String ?? ""
                                let totalReviews = data["totalReviews"] as? Int ?? 0
                                let rating = data["rating"] as? Int ?? 0
                                let baseFee = data["baseFee"] as? Int ?? 0
                                let isGuideFeatured = data["isGuideFeatured"] as? Bool ?? false

                                //make a model of guide and append in array
                                let guide = GuideDM(id: guideId, email: guideEmail, name: name, dob: dob, city: city, province: province, country: country, feeCurrency: feeCurrency, status: status, baseFee: baseFee, rating: rating, totalReviews: totalReviews, isGuideFeatured: isGuideFeatured)
                                self.guidesDataArray.append(guide)
                            }
                        }
                    }
                    print("list is finalized now")
                }
            }
        }
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?)
    {
        
       if segue.identifier == "searchScreentoGuideListSegment"
       {
           let guidesListContainerVC = segue.destination as! GuidesListSearchScreenViewController
           guidesListContainerVC.guidesDataArray = self.guidesDataArray
       }
        
    }

}

В приведенном выше классе мой код вызывает функцию populateGuidesList (), которая выполняет сетевой вызов для получения данных и в то же время загружает мои представления контейнера. Проблема в том, что до того, как сетевой вызов вернет данные, пустой массив передается моему «GuidesListSearchScreenViewController», то есть (первый контейнер V C), который является табличным представлением, и загружает пустую таблицу, потому что массив еще не заполнен.

Мой первый контейнер V C класс:

import UIKit
import Firebase

class GuidesListSearchScreenViewController: UIViewController
{

    @IBOutlet weak var guidesListTableView: UITableView!
    var guidesDataArray = [GuideDM]()
    
    override func viewDidLoad()
    {
        super.viewDidLoad()

        guidesListTableView.delegate = self
        guidesListTableView.dataSource = self
        
        guidesListTableView.register(UINib(nibName: "GuidesListCellSearchScreenTableViewCell", bundle: nil), forCellReuseIdentifier: "guidesListCell")
    }
    
}


extension GuidesListSearchScreenViewController: UITableViewDataSource, UITableViewDelegate
{
    
    // below functions are to setup the table view
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return guidesDataArray.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let cell = guidesListTableView.dequeueReusableCell(withIdentifier: "guidesListCell") as! GuidesListCellSearchScreenTableViewCell
        //adding properties to cell and then returning cell
        return cell
    }
    
}

ЦЕЛЬ: либо загрузить представление контейнера после получения данных в массиве, либо обновить sh таблицу, снова передав массив в контейнер V C и перезагрузив таблицу.

Другое решение: я попытался загрузить все эти данные массива внутри класса First container V C и перезагрузить оттуда данные представления таблицы, что отлично работает, но для меня это очень неэффективный подход , поскольку мне нужен этот массив в обоих представлениях контейнера, поэтому выполнение сетевых вызовов для каждого контейнера v c кажется очень неэффективным. Поэтому я пытаюсь получить данные один раз и передать оба представления контейнера. Пожалуйста, поправьте меня, если вы меня не правы.

Ps Я удалил другие функции и упростил код. И помощь будет очень признательна.

Ответы [ 2 ]

0 голосов
/ 20 июня 2020
• 1000 свойство, относящееся к FirstViewController (для пояснения предположим, что оно называется «firstVC»). Что вы хотите сделать: go, firstVC.view.isHidden = true

Сделайте то же самое с SecondViewController.

Почему? Это скроет контейнер VC (ViewController) из представления MainViewController.

Теперь то, что вы хотите сделать, это в том месте, где вы получаете данные от Firebase (при закрытии), добавьте следующее: firstVC.view.isHidden = false Сделайте то же самое с SecondViewController.

Это возвращает его к просмотру с данными, которые вы уже выбрали.

Надеюсь, это поможет вам как-нибудь.

0 голосов
/ 20 июня 2020

Контроллеры представления контейнера загружаются, когда загружается контроллер основного представления. Поэтому вам нужно будет обновить контроллеры представления контейнера, когда контроллер основного представления получит данные.

Простой способ сделать это - обновить массивы в контроллерах представления контейнера и использовать a didSet в массивах, чтобы заставить контроллеры представления контейнера перезагружаться.

Например, если ваш FirstViewController отображает данные массива в виде таблицы, вы можете сделать это:

var array: [ArrayItem] {
    didSet {
        tableView.reloadData()
    }
}

Затем в вашем контроллере основного представления, когда данные будут получены, установите это свойство:

getData() { resultArray in 
    firstViewController.array = resultArray
}

Обратите внимание, поскольку вы не предоставили никакого кода, это всего лишь примеры, и вам нужно будет настроить они должны соответствовать вашей конкретной c ситуации.

РЕДАКТИРОВАТЬ: Согласно приведенному ниже комментарию, вы должны быть осторожны, чтобы не установить массив в вашем FirstViewController до того, как его представление загрузится, или вызов tableView.reloadData() заставит ваше приложение cra sh.

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