Краткое изложение моей проблемы: когда tableView.reloadData()
вызывается при локальных изменениях в firestore при первой загрузке представления, оно работает и обновляется, как и положено. Однако после того, как я переключаюсь назад и назад с другими viewControllers, хотя изначально на viewDidAppear()
tableView get перезагружается, при локальных изменениях он больше не делает этого.
Я включил более простую версию своего проекта, чтобы лучше объяснить и сделать его воспроизводимым;
Элемент класса
let db = Firestore.firestore()
static var list = [String:[String:Any]]()
static var listenerSet = Bool()
static var listener: ListenerRegistration!
func setListener(completion: @escaping (String) -> Void) {
if !Item.listenerSet {
print("Attaching item document listener.")
Item.listener = db.collection("Items").document("default").addSnapshotListener({ (document, error) in
let source = document!.metadata.hasPendingWrites ? "Local" : "Server"
print("Updating item data from the \(source).")
Item.listenerSet = true
Item.list = document?.get("List") as! [String:[String:Any]]
completion("Item data is set")
})
} else {
completion("Item listener already exists")
}
}
func add(itemID:String) {
let itemRef = db.collection("Items").document("default")
itemRef.setData([
"List": [
itemID : [
"Count": FieldValue.increment(1.0),
]]
], merge:true)
}
FirstViewController: UIViewController
let item = Item()
var itemList = [[String:Any]]()
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var switchBar: UISegmentedControl!
override func viewDidLoad() {
super.viewDidLoad()
// Setting the table views
tableView.delegate = self
tableView.dataSource = self
}
override func viewDidAppear(_ animated: Bool) {
print("View Did appear") // prints OK
item.setListener() { (result) in
print(result)
loadData()
}
}
func loadData() {
itemList.removeAll()
var counter = 0
for (id,data) in Item.list {
itemList.append(data)
itemList[counter]["ID"] = id
counter += 1
}
tableView.reloadData()
}
@IBAction func switchBarChanged(_ sender: UISegmentedControl) {
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
switch switchBar.selectedSegmentIndex {
case 1:
let vc = storyBoard.instantiateViewController(identifier: "secondViewController")
show(vc, sender: self)
default:
break
}
}
Расширение FirstViewController: UITableViewDataSource, UITableViewDelegate
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("These are items:\(itemList)")
print(itemList.count)
print(tableView.bounds.height)
return itemList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell") as! ItemCell
let itemID = itemList[indexPath.row]["ID"] as! String
let itemName = itemList[indexPath.row]["Name"] as! String
let itemCount = itemList[indexPath.row]["Count"] as! Double
cell.itemID = itemID
cell.itemName.text = itemName
cell.itemCount.text = String(itemCount)
print("Items within the tableView \(itemList)") // prints only in the first run whenever there is an upload, or when refreshed.
return cell
}
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let add = UIContextualAction(style: .normal, title: "Add", handler: { (action, view, completionHandler) in
item.add(itemID:(itemList[indexPath.row]["ID"] as! String))
completionHandler(true)
})
add.image = UIImage(systemName: "plus")
let configuration = UISwipeActionsConfiguration(actions: [add])
configuration.performsFirstActionWithFullSwipe = true
return configuration
}
Класс ItemCell: UITableViewCell
var itemID = String()
@IBOutlet weak var itemName: UILabel!
@IBOutlet weak var itemCount: UILabel!
SecondViewController: UIViewController
1030 *
Теперь у меня проблема с этим:
- Приложение загружает,
FirstViewController
загружает, viewDidAppear
запускает. tableView
загружает. - При смахивании вправо значение на сервере Firestore увеличивается на единицу, включается прослушиватель снимков, перезагружается таблица, и все работает, как и должно быть.
- После того, как я переключаюсь на
SecondViewController
и возвращаюсь к FirstViewController
viewDidAppear
пинает в * 10 45 * загружает. - Однако на этот раз, когда я снова проведу пальцем вправо, значение на сервере firestore все еще увеличивается на единицу, и прослушиватель моментальных снимков включается, обновляя
Item.list
. static var ItemList
обновляется, и tableView перезагружается, однако на этот раз работает только метод numberOfRowsInSection
, поскольку он печатает счетчик и обновленный itemList, тогда ничего не происходит cellForRowAt
не работает и строки не обновляются. - Теперь на этом этапе, если я go
SecondViewController
и возвращаюсь к FirstViewController
, строки обновляются, но при пролистывании вправо все равно бесполезно.
Чего мне здесь не хватает? Спасибо всем за ваши ответы.