Мой код не добавляет значения из оператора while
для UIViewController
в массив UITableViewController
.
Это функция получения, позволяющая мне видеть все дочерние значения вдругие детские.Теперь я собираюсь быть более конкретным:
Мой узел базы данных состоит из:
Автомобили -> 0, 1, 2, 3, ... -> Модель,Цена, ... -> Строка
Как видите, число детей не определено, поэтому я должен использовать этот метод управления:
while let child = snapshotChildren.nextObject() as? DataSnapshot {
// Get code node key and save it to cars array
}
Прежде всегоВ загрузке ViewController
я получаю кодовые ключи узлов автомобилей и сохраняю их в переменную автомобилей типа NSMutableArray
из TableViewController
.Затем я сделаю то же самое в TableViewController
, чтобы получить все indexpath.row
дочерние значения.
let rootRef = Database.database().reference()
let carconditionalRef = rootRef.child("Cars")
carconditionalRef.observe(.value) {(snap: DataSnapshot) in
//Get all the children from snapshot you got back from Firebase
let snapshotChildren = snap.children
//Loop over all children (code) in Firebase
while let child = snapshotChildren.nextObject() as? DataSnapshot {
// Get code node key and save it to cars array
let carvc = Cars_Table();
carvc.cars.add(child.key)
}
}
В результате с этим кодом у меня все еще будет пустое NSMutableArray
.Как я могу решить эту проблему?
Изменить 1
Я исправил этот фрагмент к этому:
import UIKit
import FirebaseDatabase
class Loading: UIViewController {
@IBOutlet weak var loading: UIActivityIndicatorView!
var mother: NSMutableArray = []
override func viewDidLoad() {
super.viewDidLoad()
start()
}
func start() {
loading.startAnimating()
if #available(iOS 10.0, *) {
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: false) { (timer) in
//let's dance
self.loading.startAnimating()
//call data from database
let rootRef = Database.database().reference()
let conditionalRef = rootRef.child("Cars")
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 (code) in Firebase
while let child = snapshotChildren.nextObject() as? DataSnapshot {
// Get code node key and save it to cars array
self.mother.add(child.key)
}
self.move()
self.loading.stopAnimating()
self.performSegue(withIdentifier: "loadingfinish", sender: nil)
}
}
} else {
// Fallback on earlier versions
}
}
func move() {
let vc = Cars_Table()
vc.cars = self.mother
}
}
Редактировать 2
Я пытался использовать рекурсивный метод, но он не работал.Поэтому я попробовал еще раз с итерационным методом на этот раз, используя оператор while
.
Здесь моя новая функция, на этот раз прямо в Car_TableView.swift
:
func loadData() {
//call data from database
let rootRef = Database.database().reference()
let conditionalRef = rootRef.child("Cars")
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 (code) in Firebase
while let child = snapshotChildren.nextObject() as? DataSnapshot {
// Get code node key and save it to cars array
self.populateTable.append(child.key)
}
var counter = 0
while counter > -self.populateTable.count {
counter -= 1
let rootRef = Database.database().reference()
let userRef = rootRef.child("Cars").child("\(self.populateTable.count+counter)")
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 year1 = userDict["Year"] as! String
self.year.add(year1)
let carPrice1 = userDict["Price"] as! String
self.price.add(carPrice1)
let carimageURL1 = userDict["imageURL"] as! String
self.imagePathString.add(carimageURL1)
}) //end observeSingleEvent
}
}
}
Когда яиди, чтобы сделать while
, observeSingleEvent
будет работать, но это будет повторяться n ^ 2 раза.Почему это происходит?
Редактировать 3
Поскольку проблема, кажется, изменилась с самого начала, я отредактировал, чтобы дать все соответствующие детали.Итак, проблема теперь другая и теперь две:
- Когда я загружаю базу данных, у меня есть n ^ 2 повторных инструкций
- Чтобы увидеть таблицу, заполненную данными базы данных, я долженнажмите кнопку панели вкладок, чтобы перейти к следующему
ViewController
, затем нажмите кнопку панели вкладок, чтобы вернуться к Car_TableView.swift
Для первой проблемы ... в общем, я понятия не имею, почему это происходит ?
Для второй проблемы я подумал использовать SVProgressHUD
для перезагрузки данных, но он не работает с функцией loadData()
, и если я пытаюсь использовать метод экземпляра tableView.reloadData()
, он вылетает.
переменныевсе NSMutableArray
с тех пор, как я должен загрузить много вещей, которые могут измениться во времени
Моя viewDidLoad()
функция очень проста, как вы можете видеть:
override func viewDidLoad() {
super.viewDidLoad()
loadData()
}
Этомой источник данных табличного представления в нашем Car_TableView.swift
:
override func numberOfSections(in tableView: UITableView) -> Int {
return populateTable.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return populateTable.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "carTableCell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as! Car_Cell
cell.carLabel?.text = "\(self.model[indexPath.row])"
cell.carSubtitle?.text = "Year: \(self.year[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.carImage.contentMode = .scaleAspectFit
cell.carImage.image = UIImage(data : imageData!)
}
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ShowcarDetails" {
let myIndexPath = self.tableView.indexPathForSelectedRow!
//save detail page url in UserDefault
let SVDetail = self.detailpage[myIndexPath.row]
let SVDetaildefaults = UserDefaults.standard
SVDetaildefaults.set(SVDetail, forKey: "sv_detail")
SVDetaildefaults.synchronize()
_ = segue.destination
as! Car_Detail
}
}
//SET CELLS SIZE
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
switch indexPath.row {
case 0,1,2,3,4:
return 100
default:
return 100
}
}
Я также повторно опубликовал функцию loadData()
, потому что я упростил операцию только в операторе while:
func loadData() {
//call data from database
let rootRef = Database.database().reference()
let conditionalRef = rootRef.child("Cars")
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 (code) in Firebase
while let child = snapshotChildren.nextObject() as? DataSnapshot {
// Get code node key and save it to cars array
self. populateTable.append(child.key)
let userRef = rootRef.child("Cars").child("\(child.key)")
userRef.observeSingleEvent(of: .value, with: { snapshot in
let userDict = snapshot.value as! [String: Any]
let address1 = userDict["Address"] as! String
self.address.add(address1)
let detail1 = userDict["Detail"] as! String
self.detailpage.add(detail1)
let carnumberOfRooms1 = userDict["numberOfRooms"] as! String
self.numberOfRooms.add(carnumberOfRooms1)
let carPrice1 = userDict["Price"] as! String
self.price.add(carPrice1)
let carimageURL1 = userDict["imageURL"] as! String
self.imagePathString.add(carimageURL1)
}) //end observeSingleEvent
} //end while
} //end snap
}//end func