在选项卡之间切换时 UITableView 不更新

Posted

技术标签:

【中文标题】在选项卡之间切换时 UITableView 不更新【英文标题】:UITableView not updating when switching between tabs 【发布时间】:2015-10-23 12:10:37 【问题描述】:

前言:我尝试将tableView.reloadData() 添加到未更新的viewWillAppear(...和viewDidLoadviewDidAppear 等)。我也为 S 和 G 提供了 setNeedsDisplay

我有一个UITabBarController,上面有 3 个标签。每个选项卡都是一个 TableViewController,由 Core Data 提供支持,并填充有来自一个 NSManagedObjectContextNSManagedObjects

TableViewController1 中,我对单元格进行了更改,tableView 正确重新加载并反映了更改。如果我单击TableViewController2 的选项卡,则不会反映对TVC1 所做的更改。

TVC1 上所做的更改在启动之间仍然存在,当我关闭应用程序并重新启动它时,我在 TVC2 上看到它们。

我错过了什么?任何想法将不胜感激。

更新

这是有问题的代码:

func markFavorite(sender: AnyObject) 
    // Store the sender in case you need it later. Might not need this.
    clickedFavoriteButton = sender as! UIButton

    if resultsSearchController.active 
        let indexPath = sender.tag
        let selectedSound = self.filteredSounds[indexPath]
        print("markFavorite's sender tag is \(indexPath)")
        if selectedSound.favorite == 1 
            selectedSound.favorite = 0
         else 
            selectedSound.favorite = 1
        

        saveManagedObjectContext()

     else 
        let indexPath = sender.tag
        let selectedSound = self.unfilteredSounds[indexPath]
        print("markFavorite's sender tag is \(indexPath)")
        if selectedSound.favorite == 1 
            selectedSound.favorite = 0
         else 
            selectedSound.favorite = 1
        

        saveManagedObjectContext()
    


func saveManagedObjectContext() 

    if managedObjectContext.hasChanges 
        do 
            try self.managedObjectContext.save()
         catch 
            // catch error here
        
    
    self.tableView.reloadData()

【问题讨论】:

粘贴一些代码,以便在您的代码出现错误时帮助您 【参考方案1】:

应该始终使用NSFetchedResultsController 在表格视图中显示Core Data 项。它带有委托方法,可以在基础数据更改时更新您的表(甚至在保存之前)。

要开始使用,请检查 Xcode 模板(Master-Detail)实现。一旦你掌握了它的窍门,你就会爱上它。一切都是开箱即用的。

【讨论】:

谢谢。过去有人告诉我,在较小的项目中,没有fetchedResultsController 就可以逃脱,但这似乎是个坏建议。我将实施 FRC。我确信这将解决问题。感谢您的洞察力。 我实现了一个frc。显示frc 时,除了按钮之外,一切正常。 ***.com/questions/33313674/… 我也回答了你的其他问题。使用tags 来识别单元格按钮不是一个好方法。【参考方案2】:

您可能必须手动触发 context.save(),因为 core-data 不会立即保存数据。

let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext!

runOnMain() 
    do 
        try! self.context.save()
     catch let error as NSError 
        //Handle any upcoming errors here.
    

在主线程上运行该方法很重要,否则会出错。

这个方法应该可以完成工作:

func runOnMain(block: dispatch_block_t) 
    if NSThread.isMainThread() 
        block()
    else
        dispatch_sync(dispatch_get_main_queue(), block)
    

如果这种方法对您有用,请告诉我。

【讨论】:

请不要随便把fatalError 扔进你的catch 块中...不要将崩溃引入完全可恢复的情况... 这就是我写“处理错误”的原因。 :) 但为了让你开心,我编辑了代码...... 有办法写“处理错误”。没有引入崩溃。例如:// handle the errorprint("Handle the error: \(error.localizedDescription)") 您应该永远使用除NSManagedObjectContext API 以外的任何东西来确保对上下文的适当访问。这包括 GCD 在主线程上运行一个块。这会导致大量未来的错误。 总是使用performBlock 适当地同步对上下文的访问,即使您知道它是一个主队列上下文。唯一合适的例外是从已知已在主运行循环中运行的 UI 元素进行访问。【参考方案3】:

您不应该在视图控制器生命周期的任何时候尝试重新加载数据。而是为每个选项卡栏控制器创建委托,正确设置它们并仅在数据源中确实发生变化时调用委托方法。如果您对委托不熟悉,可以了解更多关于它的信息here

【讨论】:

以上是关于在选项卡之间切换时 UITableView 不更新的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式切换到 UITabBarController 中的另一个选项卡?

在选项卡之间切换时获取核心数据

切换标签时弹出键盘,破坏一切

在选项卡之间切换时如何创建交叉溶解动画

UITableViewCellAccessibilityElement 发布在选项卡切换时崩溃

在 UITabController 中的选项卡之间切换时使用“pushViewController”动画