UICollectionView 刷新数据
Posted
技术标签:
【中文标题】UICollectionView 刷新数据【英文标题】:UICollectionView refresh data 【发布时间】:2014-04-16 10:03:55 【问题描述】:我正在使用一个显示对象数组的 CollectionView。 单击按钮时,我用一组新数据填充此数组。 我想用这些数据刷新 CollectionView。 是否有任何声明来更新它而不是比较每个项目并有选择地删除和添加? reloadData 通常会出现以下错误。
CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION
简而言之,我正在寻找以下步骤... 1)填充数据源数组,显示数据。 2)用新数据填充数据源数组,刷新CollectionView以显示数据。
提前致谢
【问题讨论】:
CollectionView 的行为类似于 tableView。您只需准备数据源,然后在加载时显示 collectionView。然后,您可以随时更改数据源,或者重新加载数据以完全重新加载,或者重新加载单个项目。因此,由于您的错误,您在数据源中做错了什么,无论是在 cellForItem 还是 numberOfItems/numberOfSections 中。只需调试它所在的位置。 我们为什么要使用 performBatchUpdates ? 【参考方案1】:试试- (void)performBatchUpdates:(void (^)(void))updates completion:(void (^)(BOOL finished))completion
。
在您的情况下,您想要“一组全新的数据”,可以这么说,例如:
[myCV performBatchUpdates:^
// one of:
// a)
[myCV deleteSection:someIndexSetForTheEntireSection];
[myRealDataSource empty:someIndexSetForTheEntireSection];
//
// OR b)
[myCV deleteItemsAtIndexPaths:someSetOfIndexPaths];
[myRealDataSource removeIndexPaths:someSetOfIndexPaths];
// Either case:
NSArray *indexPaths = [myRealDataSource getNewDataAndReturnIndexPaths];
// if a)
[myCV insertSections:newIndexSetForNewSection];
// Either case:
[myCV insertItemsAtIndexPaths:newIndexSetForInsertions];
completion:^(BOOL finished)
NSLog(@"Done.");
// Maybe signal something else if you want.
];
performBatchUpdates:completion:
将期望从原始数据源检查进入函数的删除和插入添加到离开方法的正确数据源大小。否则它会大声抱怨。
如果您只有一个部分(第 0 部分),如果您总是“删除所有内容”和“插入一个完整的新集合”,那么您可以比特定的索引路径更通用。
另一种使用 KVO 侦听数据源中的插入和删除的选项,只需 reloadData
、reloadItemsAtIndexPaths:
或 reloadSections:
(视情况而定)。
我更喜欢响应式 KVO 版本,因为我倾向于将集合视图与 Core Data 一起使用,而不是伪静态或内存中的 NSArray。
为了找出 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION 问题,我会在所有异常上设置断点,并尝试找出真正触发问题的原因。可能您的数据源已消失,并且当您尝试从中读取/写入时访问不正确。
【讨论】:
我正在寻找的完美答案!谢谢? 你能告诉我 myRealDataSource 变量的数据类型是什么吗? 随心所欲。如果你保留一个简单的 NSArray,那么它就是一个 NSArray。如果 Core Data 向您返回一个 NSOrderedSet,那么很可能是这样。它甚至可能不是集合类型,而是您自己编写的其他类。 你能发布一个快速版本吗?【参考方案2】:假设您到达您的视图,那么您可以使用viewDidLoad
方法将数据添加到您的数组中,如下所示:
-(void)viewDidLoad
[super viewDidLoad];
// If you have already data
self.arr_sample=(NSArray *)array;
/*
When you want to download data from server than you have to call reloadData
method of collection because all delegate method already called before view load.
So loading data will take time to load data than you have to call all delegate
method of collectionview by calling reloadData method.
*/
[self loadData];
// Do any additional setup after loading the view from its nib.
但首先你已经设置了 collectionview 的委托。 你想从服务器下载数据而不是调用集合视图的 reloaddata 方法。比如
-(void)loadData
// Do your downloading code her and call to reload data method of collectionview
[collectionview reloadData];
现在你想在你的按钮点击时用新数据重新填充你的数组而不是你可以做的
-(void)refillData
// Download new data code here and follow
[array removeAllObjects];
array=(NSArray *)newarray;
[collectionview reloadData];
【讨论】:
hmm ..理论上它应该可以工作...我使用相同的逻辑并且数组已正确填充..但仍然出现上述错误...使用上述逻辑有什么区别以及 performBatchUpdates 的逻辑......? [self.collectionView performBatchUpdates:^以上是关于UICollectionView 刷新数据的主要内容,如果未能解决你的问题,请参考以下文章