TableView在CoreData更改后不使用FRC Swift 3更新(reloadData) [英] TableView doesn't update(reloadData) after CoreData change using FRC Swift 3

查看:335
本文介绍了TableView在CoreData更改后不使用FRC Swift 3更新(reloadData)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我更新了这个问题,因为我发现这个问题的另一个关键。看来,当我添加一些东西到CoreData,tableview不重新加载数据,即使我可以打印出CoreData已保存的对象。所以我知道数据是正确的,但是函数
func tableView(_ tableView:UITableView,cellForRowAt indexPath:IndexPath) - > UITableViewCell 永远不会被调用。



这也值得注意,如果我停止应用程序并重新打开它,表视图显示正确的单元格数量和信息。所以看来数据只加载初始构建的属性。



我有一个 UITableView 正在填充 CoreData 并使用 FetchedResultsController 。我添加了FRC委托方法,我试图强制 tableView.reloadData()方法,但是似乎不工作。



这里是我使用的委托方法:

  func controllerWillChangeContent(_ controller:NSFetchedResultsController< NSFetchRequestResult>){
tableView.beginUpdates()
}

func controller (_ controller:NSFetchedResultsController< NSFetchRequestResult> ;, didChange anObject:Any,在indexPath:IndexPath?,类型:NSFetchedResultsChangeType,newIndexPath:IndexPath?){

开关类型{
case .insert:
tableView.insertRows(at:[newIndexPath!],with:.automatic)
case .delete:
tableView.deleteRows(at:[indexPath!],with:.automatic)
case .update:
tableview.reloadData()
case .move:
tableView.deleteRows(at:[indexPath!],with:.automatic)
tableView.insertRows (at:[newIndexPath!],with:.automatic)
}
}

func controllerDidChangeContent(_ controller:NSFetchedResultsController< NSFetchRequestResult>){
tableView.endUpdates ()
}



当我回到这个View我想强制tableview

ViewwillAppear方法:

  override func viewWillAppear (_ animated:Bool){
//加载数据

let fetchRequest:NSFetchRequest< Person> = Person.fetchRequest()
fetchRequest.predicate = NSPredicate(format:statement。@ sum.amountOwed> = 0)
let sort = NSSortDescriptor(key:#keyPath(Person.name) ascending:true)
fetchRequest.sortDescriptors = [sort]
positiveFetchedResultsController = NSFetchedResultsController(fetchRequest:fetchRequest,managedObjectContext:coreDataStack.managedContext,sectionNameKeyPath:nil,cacheName:nil)

{
try positiveFetchedResultsController.performFetch()
} catch let错误为NSError {
print(Fetching error:\(error),\(error.userInfo))
}


let negativFetchRequest:NSFetchRequest< Person> = Person.fetchRequest()
negativFetchRequest.predicate = NSPredicate(format:statement。@ sum.amountOwed< 0)
let negativeSort = NSSortDescriptor(key:#keyPath(Person.name) :true)
negativFetchRequest.sortDescriptors = [negativeSort]
negativeFetchedResultsController = NSFetchedResultsController(fetchRequest:negativFetchRequest,managedObjectContext:coreDataStack.managedContext,sectionNameKeyPath:nil,cacheName:nil)

do {
try negativeFetchedResultsController.performFetch()
} catch let错误为NSError {
print(Fetching error:\(error),\(error.userInfo))
}

positiveFetchedResultsController.delegate = self
negativeFetchedResultsController.delegate = self

print(\(positiveFetchedResultsController.fetchedObjects!.count)positive fetch count)
//print(\"\(positiveFetchedResultsController.fetchedObjects![0].statement!.count)肯定语句计数)
print(\(negativeFetchedResultsController.fetchedObjects!.count)negative fetch count )
//print(\"\(negativeFetchedResultsController.fetchedObjects![0].statement!.count)negative statements count)

tableView.reloadData()
}

这里是我的cellForRowAt方法:

  func tableView(_ tableView:UITableView,cellForRowAt indexPath:IndexPath) - > UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier:personCell,for:indexPath)as! PersonTableViewCell

switch(indexPath.section){
case 0:
// print(this is section 0)
let person = positiveFetchedResultsController.object :indexPath)
cell.personName.text = person.name
//print(\"\(person.name!)是名称)
// print(\ person.statement!.count)postive person statement count)

if(person.statement!.count == 0){
print(default)
cell。 statementAmount.text =$ 0.00
}
else {
//print(\"\(person.name!)has \(person.statement!.count)statement count)
let amountTotal = person.value(forKeyPath:statement。@ sum.amountOwed)as?十进制
// print(\(amountTotal!)this is the total)
cell.statementAmount.text = convertStringToDollarString(amountToConvert:String(描述:amountTotal!))

}

case 1:

print(this is section 1)
//print(\"\(negativeFetchedResultsController.object(at: indexPath.row,0]))objects fetched)
//print(\"\(indexPath.section)section number)
//print(\"\(indexPath.row)row number )

let person = negativeFetchedResultsController.fetchedObjects![indexPath.row]
cell.personName.text = person.name

print(\ .name!)是名称)
print(\(person.statement!.count)negative person statement count)

if(person.statement!.count == 0){
cell.statementAmount.text =$ 0.00
}
else {
//print(\"\(person.name!)has \(person。语句.count)语句计数)
let amountTotal = person.value(forKeyPath:statement。@ sum.amountOwed)as?十进制
print(\(amountTotal!)this is the total)
cell.statementAmount.text = String(描述:amountTotal!)

cell.statementAmount.text = convertStringToDollarString(amountToConvert:String(描述:amountTotal!))
}

cell.backgroundColor = Styles.redColor

let bgColorView = UIView()
bgColorView.backgroundColor = Styles.darkRedColor()
cell.selectedBackgroundView = bgColorView

默认值:cell.personName。 text =hello
}
return cell
}


解决方案

可以尝试这样:

  override func viewDidAppear(_ animated:Bool){
super.viewDidAppear(animated)
self.tableView.reloadData()
}


I have updated this question as I found another key to this problem. It seems that when I add something to CoreData, the tableview does not reload the data, even though I can print out the objects that CoreData has saved. So I know the data is correct, but the function func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell never gets called.

It's also worth noting that if I stop the application and reopen it , the table view displays the correct amount of cells and information. So it seems the the data only loads property on initial build.

I have a UITableView that is being populated by CoreData and also using a FetchedResultsController. I added the FRC delegate methods and I tried to force the tableView.reloadData() method, but that doesn't seem to work. The data shows up, if I stop the build and rebuild the project.

Here are my delegate methods that I am using:

    func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView.beginUpdates()
}

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {

    switch type {
    case .insert:
        tableView.insertRows(at: [newIndexPath!], with: .automatic)
    case .delete:
        tableView.deleteRows(at: [indexPath!], with: .automatic)
    case .update: 
       tableview.reloadData()
    case .move:
        tableView.deleteRows(at: [indexPath!], with: .automatic)
        tableView.insertRows(at: [newIndexPath!], with: .automatic)
    }
}

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    tableView.endUpdates()
}

When I come back to this View I would like to force the tableview to reload its data.

ViewwillAppear method:

override func viewWillAppear(_ animated: Bool) {
    // load the data

    let fetchRequest: NSFetchRequest<Person> = Person.fetchRequest()
    fetchRequest.predicate = NSPredicate(format:"statement.@sum.amountOwed >= 0")
    let sort = NSSortDescriptor(key: #keyPath(Person.name), ascending: true)
    fetchRequest.sortDescriptors = [sort]
    positiveFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: coreDataStack.managedContext, sectionNameKeyPath: nil, cacheName: nil)

    do{
     try positiveFetchedResultsController.performFetch()
     }catch let error as NSError{
        print("Fetching error: \(error), \(error.userInfo)")
    }


    let negativFetchRequest: NSFetchRequest<Person> = Person.fetchRequest()
    negativFetchRequest.predicate = NSPredicate(format:"statement.@sum.amountOwed < 0")
    let negativeSort = NSSortDescriptor(key: #keyPath(Person.name), ascending: true)
    negativFetchRequest.sortDescriptors = [negativeSort]
    negativeFetchedResultsController = NSFetchedResultsController(fetchRequest: negativFetchRequest, managedObjectContext: coreDataStack.managedContext, sectionNameKeyPath: nil, cacheName: nil)

    do{
        try negativeFetchedResultsController.performFetch()
    }catch let error as NSError{
        print("Fetching error: \(error), \(error.userInfo)")
    }

    positiveFetchedResultsController.delegate = self
    negativeFetchedResultsController.delegate = self

    print("\(positiveFetchedResultsController.fetchedObjects!.count) positive fetch count")
    //print("\(positiveFetchedResultsController.fetchedObjects![0].statement!.count) positive statements count")
    print("\(negativeFetchedResultsController.fetchedObjects!.count) negative fetch count")
    //print("\(negativeFetchedResultsController.fetchedObjects![0].statement!.count) negative statements count")

    tableView.reloadData()
}

Here is my cellForRowAt method:

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "personCell", for: indexPath) as! PersonTableViewCell

    switch(indexPath.section) {
    case 0:
        //print("this is section 0")
        let person = positiveFetchedResultsController.object(at: indexPath)
        cell.personName.text = person.name
        //print("\(person.name!) is the name")
        //print("\(person.statement!.count) postive person statement count")

        if(person.statement!.count == 0){
            print("default")
            cell.statementAmount.text = "$0.00"
        }
        else{
            //print("\(person.name!) has \(person.statement!.count) statement count")
            let amountTotal = person.value(forKeyPath: "statement.@sum.amountOwed") as? Decimal
            //print("\(amountTotal!) this is the total")
            cell.statementAmount.text = convertStringToDollarString(amountToConvert: String(describing: amountTotal!))

        }

    case 1:

        print("this is section 1")
        //print("\(negativeFetchedResultsController.object(at: [indexPath.row,0])) objects fetched")
        //print("\(indexPath.section) section number")
        //print("\(indexPath.row) row number")

        let person = negativeFetchedResultsController.fetchedObjects![indexPath.row]
        cell.personName.text = person.name

        print("\(person.name!) is the name")
        print("\(person.statement!.count) negative person statement count")

        if(person.statement!.count == 0){
            cell.statementAmount.text = "$0.00"
        }
        else{
            //print("\(person.name!) has \(person.statement!.count) statement count")
            let amountTotal = person.value(forKeyPath: "statement.@sum.amountOwed") as? Decimal
            print("\(amountTotal!) this is the total")
            cell.statementAmount.text = String(describing: amountTotal!)

            cell.statementAmount.text = convertStringToDollarString(amountToConvert: String(describing: amountTotal!))
        }

        cell.backgroundColor = Styles.redColor();

        let bgColorView = UIView()
        bgColorView.backgroundColor = Styles.darkRedColor()
        cell.selectedBackgroundView = bgColorView

    default: cell.personName.text = "hello"
    }
    return cell
}

解决方案

maybe try this:

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    self.tableView.reloadData()
}

这篇关于TableView在CoreData更改后不使用FRC Swift 3更新(reloadData)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆