UITableView 不会更新数据

Posted

技术标签:

【中文标题】UITableView 不会更新数据【英文标题】:UITableView will not update data 【发布时间】:2018-10-15 19:41:38 【问题描述】:

我有下面的 TableView 显示产品和销售产品。当产品打折时,它旁边会有一张图片。 问题是当产品更新到销售时,CKSubscription 通知通过并被处理(一切都正确到达 ViewController。

问题是,当第一个通知通过时一切正常,但之后更新的待售商品不显示促销图片。这让我相信重新加载 tableView 存在问题。

我也在.recordUpdated 中尝试过tableView.reloadData(),但它没有更新。委托和数据源已在情节提要上设置。我做错了什么??

class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate 
 var array:[CKRecord] = []

@IBOutlet weak var tableView: UITableView!

override func viewDidLoad() 
    super.viewDidLoad()

     addNotificationObservers()
     getData()



@objc func getData() 
    self.array = []
    let predicate = NSPredicate(value: true)
    let query = CKQuery(recordType: “Product”, predicate: predicate)

    let queryOperation = CKQueryOperation(query: query)
    queryOperation.resultsLimit = 5
    queryOperation.qualityOfService = .userInitiated
    queryOperation.recordFetchedBlock =  record in
        self.array.append(record)
    
    queryOperation.queryCompletionBlock =  cursor, error in
        if error != nil
          print(error?.localizedDescription)

        
        else
            if cursor != nil 
                self.askAgain(cursor!)
            
        
        OperationQueue.main.addOperation 
            self.tableView.reloadData()
        
    
    Database.share.publicDB.add(queryOperation)


func askAgain(_ cursor: CKQueryOperation.Cursor) 
    let queryOperation = CKQueryOperation(cursor: cursor)
    queryOperation.resultsLimit = 5

    queryOperation.recordFetchedBlock = 
        record in
        self.array.append(record)
    
    queryOperation.queryCompletionBlock =  cursor, error in
        if error != nil
            (error?.localizedDescription)
        
        else
            if cursor != nil 
                self.askAgain(cursor!)
            
        
        OperationQueue.main.addOperation 
            self.tableView.reloadData()
        
    
    Database.share.publicDB.add(queryOperation)


  func addNotificationObservers() 
    NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: CloudKitNotifications.NotificationReceived), object: nil, queue: OperationQueue.main)  (notification) in
        let notification = notification.object as! CKQueryNotification
        if let recordID = notification.recordID 
            switch notification.queryNotificationReason
            case .recordCreated:
                Database.share.publicDB.fetch(withRecordID: recordID)  (record, error) in
                    if record != nil 
                        DispatchQueue.main.async 
                            self.tableView.beginUpdates()
                            self.array.insert(record!, at: 0)
                            let indexPath = NSIndexPath(row: 0, section: 0)
                            self.tableView.insertRows(at: [indexPath as IndexPath], with: .top)
                            self.tableView.endUpdates()
                        
                    
                

            case .recordDeleted:
                DispatchQueue.main.async 
                    self.array = self.array.filter $0.recordID != recordID 
                    self.tableView.reloadData()
                

            case .recordUpdated:
                Database.share.publicDB.fetch(withRecordID: recordID)  (record, error) in
                    if record != nil 

                  DispatchQueue.main.async 
                                    //gets the old record
                                    let getOldRecord = self.array.filter $0.recordID == recordID 
                               // gets position of old record
                                    let positionofOldRecord = self.array.firstIndex(of: getOldRecord[0])
                        print("here is the position of old record \(positionofOldRecord)")
                             //gets the array without the old record
                                    self.array = self.array.filter $0.recordID != recordID 

                                    //now go to the position of the old one and replace it with the new one
                                    var newArray = self.array

                            self.tableView.beginUpdates()
                            let indexPath = NSIndexPath(row: positionofOldRecord!, section: 0)
                            self.tableView.deleteRows(at: [indexPath as IndexPath], with: .automatic)
                            self.array.insert(record!, at: positionofOldRecord!)
                            self.tableView.insertRows(at: [indexPath as IndexPath], with: .automatic)
                            self.tableView.endUpdates()
                        
                                           
                 

            default:
                break
            
        
    
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return array.count

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell") as? TableViewCell else  return UITableViewCell() 
    let item = array[indexPath.row]
    if item[“whatsTheNumber”] == 0 
    cell.saleView.isHidden=true
    
    cell.configureCell(brandBame: item[“Name”]!. productName: item[“ProductName”]!)

    return cell


编辑:

class TableViewCell: UITableViewCell 

@IBOutlet weak var brandNameLabel: UILabel!
@IBOutlet weak var productNameLabel: UILabel!
@IBOutlet weak var saleImage: UIImageView!
@IBOutlet weak var saleView: UIView!

func configureCell(brandName: String, productName:String)
    self.brandNameLabel.text = brandName
    self.productNameLabel.text = productName


override func awakeFromNib() 
    super.awakeFromNib()
    // Initialization code


override func setSelected(_ selected: Bool, animated: Bool) 
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state


【问题讨论】:

cell.configureCell() 是做什么的? 查看编辑,我添加了TableViewCell 类的代码。 salesImage 在哪里设置? 我在故事板上设置了。 我希望某个地方有一个 if 语句,无论是在 configureCell 还是在 tableview.cellForItemAt 方法中,它可能会根据您从服务器获得的数据隐藏或显示 saleImage。那是哪里? 【参考方案1】:

您需要在cellForRowAt func 中执行类似的操作:

 cell.configureCell(brandBame: item[“Name”]!, productName: item[“ProductName”]!, isSaleItem: item[“Sale”]!)

item[“Sale”] 将是一个布尔标志

configureCell() 函数中:

func configureCell(brandName: String, productName:String, isSaleItem: Bool)
    self.brandNameLabel.text = brandName
    self.productNameLabel.text = productName
    self.saleImage.isHidden = !isSaleItem

【讨论】:

简单但没想到。正是我需要的!非常感谢! 很高兴它对你有用。感谢您的反馈 :: 编码快乐!

以上是关于UITableView 不会更新数据的主要内容,如果未能解决你的问题,请参考以下文章

reloadRowsAtIndexPaths 不会更新我的单元格数据

Restkit/CoreData - 更新实体的属性不会更新 UITableView

UITableView 单元格不会快速更新

静态 uitableview 中的 uitextfield 不会在容器视图中更新

UITableView 更新正确数量的 managedObjects,但不会显示值

更新 uitableview 数据源和更新标签栏