首页 > 解决方案 > 视图第二次出现后,Swift UITableView cellForRowAt indexPath 不会在 tableView.reloadData() 上被调用

问题描述

我的问题的总结是;当在tableView.reloadData()第一次加载视图时调用firestore的本地更改时,它会按预期工作并更新。但是,在我与其他 viewController 来回切换之后,虽然最初在viewDidAppear()tableView 上重新加载了,但在本地更改后它不再这样做。

我已经包含了我的项目的一个更简单的版本,以更好地解释并使其可重现;

类项目

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

@IBOutlet weak var switchBar: UISegmentedControl!

override func viewDidLoad() {
    super.viewDidLoad()
}

@IBAction func switchBarChanged(_ sender: UISegmentedControl) {
    let storyBoard = UIStoryboard(name: "Main", bundle: nil)
    switch switchBar.selectedSegmentIndex {
    case 0:
        let vc = storyBoard.instantiateViewController(identifier: "firstViewController")
        show(vc, sender: self)
    default:
        break
    }
}

现在这是我遇到问题的流程;

我在这里想念什么?谢谢大家的回复。

标签: swiftuitableviewgoogle-cloud-firestoreuiviewcontrollerviewdidappear

解决方案


推荐阅读