在选项卡之间切换时 UITableView 不更新
Posted
技术标签:
【中文标题】在选项卡之间切换时 UITableView 不更新【英文标题】:UITableView not updating when switching between tabs 【发布时间】:2015-10-23 12:10:37 【问题描述】:前言:我尝试将tableView.reloadData()
添加到未更新的viewWillAppear
(...和viewDidLoad
、viewDidAppear
等)。我也为 S 和 G 提供了 setNeedsDisplay
。
我有一个UITabBarController
,上面有 3 个标签。每个选项卡都是一个 TableViewController
,由 Core Data 提供支持,并填充有来自一个 NSManagedObjectContext
的 NSManagedObjects
。
在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/…
我也回答了你的其他问题。使用tag
s 来识别单元格按钮不是一个好方法。【参考方案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 error
或 print("Handle the error: \(error.localizedDescription)")
您应该永远使用除NSManagedObjectContext
API 以外的任何东西来确保对上下文的适当访问。这包括 GCD 在主线程上运行一个块。这会导致大量未来的错误。 总是使用performBlock
适当地同步对上下文的访问,即使您知道它是一个主队列上下文。唯一合适的例外是从已知已在主运行循环中运行的 UI 元素进行访问。【参考方案3】:
您不应该在视图控制器生命周期的任何时候尝试重新加载数据。而是为每个选项卡栏控制器创建委托,正确设置它们并仅在数据源中确实发生变化时调用委托方法。如果您对委托不熟悉,可以了解更多关于它的信息here
【讨论】:
以上是关于在选项卡之间切换时 UITableView 不更新的主要内容,如果未能解决你的问题,请参考以下文章
如何以编程方式切换到 UITabBarController 中的另一个选项卡?