Как исправить класс UITableView, который дважды повторяет чтение элементов в базе данных Firebase и при загрузке таблица пуста? - PullRequest
0 голосов
/ 13 мая 2019

Я пытаюсь прочитать из базы данных Firebase в реальном времени ряд инструкций.

У меня есть неизвестное количество информации о моем узле Транспортные средства, поэтому я просто использую метод nextObject, чтобы получить количество раз, которое функция должна повторить.

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

Здесь мой UITableView файл:

import UIKit
import FirebaseDatabase
import Alamofire




class Vehicles: UITableViewController,
UISearchResultsUpdating, UISearchBarDelegate {

    //variables
    var model: NSMutableArray = []
    var numberOfVehicles: NSMutableArray = []
    var price: NSMutableArray = []
    var imagePathString: NSMutableArray = []
    var detailpage: NSMutableArray = []



    var populator: NSMutableArray = []
    var searching = false
    var matches = [Int]()
    let searchController = UISearchController(searchResultsController: nil)

    @IBOutlet weak var InfoTableView: UITableView!

    var InfoList: [String] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        loadData()
        //this should reload but, it didn't.
        self.InfoTableView.reloadData()
        //then the searchbar that is good and don't have any problem.
        searchingField()
    }



    func loadData() {
        //read data from database
        let rootRef = Database.database().reference()
        let conditionalRef = rootRef.child("Vehicles")
        conditionalRef.observe(.value) {(snap: DataSnapshot) in
            // Get all the children from snapshot you got back from Firebase
            let snapshotChildren = snap.children
            // Loop over all children in Firebase
            while let child = snapshotChildren.nextObject() as? DataSnapshot {
                // Get code node key and save it to they array
                self.populator.add(child.key)
                if self.populator.contains("\(child.key)") {
                    let userRef = rootRef.child("Vehicles").child("\(child.key)")

                    userRef.observeSingleEvent(of: .value, with: { snapshot in
                        let userDict = snapshot.value as! [String: Any]

                            let model1 = userDict["Model"] as! String
                            self.model.add(model1)

                            let detail1 = userDict["Detail"] as! String
                            self.detailpage.add(detail1)

                            let numberOfVehicles1 = userDict["numberOfVehicles"] as! String
                            self.numberOfVehicles.add(numberOfVehicles1)

                            let Price1 = userDict["Price"]  as! String
                            self.price.add(Price1)

                            let imageURL1 = userDict["imageURL"]  as! String
                            self.imagePathString.add(imageURL1)
                    }) //end second observeSingleEvent

                }
              else {
                    let alert = UIAlertController(title: "Error", message: "No one vehicle found", preferredStyle: UIAlertController.Style.alert)
                    alert.addAction(UIAlertAction(title: "ok", style: UIAlertAction.Style.default, handler: nil))
                self.present(alert, animated: true, completion: nil)
                }

            } //end searching object in Vehicles node



            } //end first observeSingleEvent

      }//end func


    func searchingField() {
        //setup searchbar
        tableView.estimatedRowHeight = 50
        navigationController?.navigationBar.prefersLargeTitles = true

        searchController.searchBar.delegate = self
        searchController.searchResultsUpdater = self
        searchController.searchBar.backgroundColor = UIColor.white
        searchController.obscuresBackgroundDuringPresentation = false
        searchController.searchBar.placeholder = "Search"
        navigationItem.searchController = searchController
        definesPresentationContext = true
        let attributes = [
            NSAttributedString.Key.foregroundColor : UIColor.black,
            NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 17)
        ]
        UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes(attributes, for: .normal)
        UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).title = "Dismiss"
        UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self])
    }





    // MARK: Search Controller
    func updateSearchResults(for searchController: UISearchController) {
        var regArray = self.model as NSArray as! [String]
        if let searchText = searchController.searchBar.text,
            !searchText.isEmpty { 
            matches.removeAll()

            for index in 0..<model.count {
                if regArray[index].lowercased().contains(
                    searchText.lowercased()) {
                    matches.append(index)
                }
            }
            searching = true
        } else {
            searching = false
        }
        tableView.reloadData()
    }

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        searching = false
        tableView.reloadData()
    }



    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        return searching ? matches.count : model.count
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return searching ? matches.count : model.count
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cellIdentifier = "TableCell"

        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as! Vehicles_cell



        let row = indexPath.row
        var regArray = self.model as NSArray as! [String]
        cell.Label.text = searching ? regArray[matches[row]] : model[row] as! String
        cell.Subtitle?.text = "N. Vehicles: \(self.numberOfVehicles[indexPath.row]) - Price: \(self.price[indexPath.row])$"


        Alamofire.request("\(self.imagePathString[indexPath.row])").response { response in
            guard let image = UIImage(data:response.data!) else {
                // Handle error
                return
            }
            let imageData = image.jpegData(compressionQuality: 1.0)
            cell.Image.contentMode = .scaleAspectFit
            cell.Image.image = UIImage(data : imageData!)
        }

        return cell
    }



    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "ShowrentDetails" {

            let myIndexPath = self.tableView.indexPathForSelectedRow!

            //save detail1 in UserDefault
            let SVDetail = self.detailpage[myIndexPath.row]
            let SVDetaildefaults = UserDefaults.standard
            SVDetaildefaults.set(SVDetail, forKey: "sv_detail")
            SVDetaildefaults.synchronize()
            _ = segue.destination
                as! Vehicles_Detail
        }
    }

    //IMPOSTA LE DIMENSIONI DELLE CELLE
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        switch indexPath.row {
        default:
            return 100
        }
    }


}

Я ожидаю, что таблица покажет при открытии все данные из базы данных, хотя на самом деле и не повторится, если я не нажму на панель поиска. И стол не должен повторяться дважды.


Редактировать (решение дубликатов)

Это так неловко. Ответ на эту проблему прост

В функции numberOfSections я использовал address.count вместо 1 Section. Итак, я увидел не дублирующиеся ячейки, а новые секции блоков model.count

1 Ответ

0 голосов
/ 13 мая 2019

Ваше табличное представление не перезагружает данные, как только они выбраны во время наблюдения Firebase, но находится в updateSearchResults(). Устраняет ли проблему добавление self.InfoTableView.reloadData() внутри loadData() между //end searching object in Vehicles node и //end first observeSingleEvent закрывающими скобками?

Edit: Причина, по которой ваша перезагрузка данных таблицы не устраняет проблему в viewDidLoad(), заключается в том, что она вызывается до того, как функция loadData() начинает перебирать объекты данных Firebase. Делая это в конце наблюдения Firebase, вы гарантируете, что загрузили все свои данные из Firebase до вызова перезагрузки.

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