UITableView中的数据在特定情况下不刷新

时间:2017-07-22 11:54:01

标签: ios swift uitableview reloaddata

看起来很奇怪,因为我的tableView中的数据大部分都是刷新的,但是在一个特定但非常重要的情况下,它不会被刷新。

所以,我有2个结构:

struct ItemsStructure {
    var itemId: Int
    var code: String
    var externalId: Int
    var manufactureName: String
    var price: Double
    var weight: Int
}

和包含第一个的结构:

struct ListStructure {
    var listId: Int
    var createdDate: Date
    var wasSent: Bool
    var items: [ItemsStructure]
}

我也有2 UITableViewController秒。第一个显示ListStructure数组,第二个显示特定选定List的内容。此外,第二个控制器允许删除列表中的项目。问题就在于我所拥有的例如带有3个项目的List。当我从List中删除第一个和第二个Item并返回到第一个控制器时,我可能会看到结果:List包含更少的Items。但是,删除最后一个项目看起来不同。回到第一个tableView,我仍然看到List包含一个Item,而它是空的。只有关闭并重新打开应用程序才会显示空列表(没有任何项目)。

是的,我已经读过将tableView.reloadData()放入DispatchQueue.main.async,但结果与我在没有DispatchQueue时调用tableView.reloadData()的结果相同。

列表中的项目的任何操作都是通过代表进行的。并且列表的打印显示列表为空。

Bellow是ListViewController的代码

class ListsViewController: UIViewController {
    var dataSource: ListViewDataSource!

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.estimatedRowHeight = tableView.rowHeight
        tableView.rowHeight = UITableViewAutomaticDimension
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        tableView.dataSource = dataSource
        DispatchQueue.main.async {
            self.tableView.reloadData()
        }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "ShowParticularItem" {
            if let listVC = segue.destination as? ParticularListViewController {
                let listNumberToPass = tableView.indexPathForSelectedRow!.row
                let listToPass = dataSource.stateController.lists[listNumberToPass]
                listVC.listNumber = listNumberToPass
                listVC.list = listToPass
                listVC.delegate = dataSource.self
            }
        }
    }
}

protocol ParticularListViewControllerDelegate: class {
func delete(listNumber: Int, itemNumber: Int)

}

class ParticularListViewController: UITableViewController {
var listNumber: Int!
var list: ListStructure!
weak var delegate: ParticularListViewControllerDelegate?


@IBOutlet weak var creationTimeLabel: UILabel!
@IBOutlet weak var sentStatusLabel: UILabel!
@IBOutlet weak var weightLabel: UILabel!
@IBOutlet weak var totalCostLabel: UILabel!
@IBOutlet weak var sentListButtonOutlet: UIButton!
@IBAction func sentListButton(_ sender: UIButton) {
    sentList()
    markListAsSent()
    refreshData()
}

func refreshData(){
    self.creationTimeLabel.text = "The list was created at \(list.createdDate)"
    if list.wasSent {
        self.sentStatusLabel.text = "The list has been already sent"
        self.sentListButtonOutlet.isEnabled = false
    } else {
        self.sentStatusLabel.text = "The list hasn't been sent yet"
        self.sentListButtonOutlet.isEnabled = true
    }
    let totalWeight: Int = list.items.reduce(0, {$0 + $1.weight})
    self.weightLabel.text = "The list contains \(list.items.count) items with total weight \(totalWeight) gramms"
    self.totalCostLabel.text = "The total cost is: \(list.totalCost) ₽"
    tableView.reloadData()
}

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

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    refreshData()
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return list.items.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! ParticularListTableViewCell
    let index = indexPath.row
    cell.item = list.items[index]

    return cell
}

func delete(itemNumber: Int){
    delegate?.delete(listNumber: listNumber, itemNumber: itemNumber)
    self.refreshData()
}

}

extension ListViewDataSource: ParticularListViewControllerDelegate {
func delete(listNumber: Int, itemNumber: Int) {
    stateController.delete(fromList: listNumber, itemNumber: itemNumber)
}

}

class ListViewDataSource: NSObject{
var stateController: StateController

init(stateController: StateController) {
    self.stateController = stateController
}

}

extension ListViewDataSource: UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return stateController.lists.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "ListsCell", for: indexPath) as! ListsTableViewCell
    let index = indexPath.row
    let listToPass = stateController.lists[index]
    cell.listToShow = ListsTableViewCell.ListModel(model: listToPass)

    return cell
}

}

class StateController{
fileprivate let storageController: StorageController
fileprivate(set) var lists: [ListStructure]
fileprivate let context: NSManagedObjectContext

init(storageController: StorageController, context: NSManagedObjectContext) {
    self.storageController = storageController
    self.context = context
    self.lists = storageController.fetchAllLists(inContext: context)
}

}

正如我在ListViewController.ViewWillAppear中打印之前所说的那样,显示stateController.lists.Items是空的

1 个答案:

答案 0 :(得分:0)

由于Array和Structs是值类型,因此不会反映您对副本所做的更改。更新数据源后,请确保也更新源视图控制器的数据源。您可能需要为此实现委托。其他方式是通过单例获得通用数据源,但我不建议这样做。