[英]UICollectionView doesn't update immediately when calling reloadData, but randomly after 30-60 seconds
As the title implies, my UICollectionView
doesn't update and display the cells immediately after calling reloadData
. 正如标题所暗示的那样,我的
UICollectionView
在调用reloadData
后不会立即更新并显示单元格。 Instead, it seems to eventually update my collection view after 30-60 seconds. 相反,它似乎最终在30-60秒后更新我的集合视图。 My setup is as follows:
我的设置如下:
UICollectionView
added to view controller in Storyboard with both delegate
and dataSource
setup for the view controller and standard outlet setup numberOfSectionsInRow
& cellForItemAtIndexPath
are both implemented and reference the prototyped cell and the imageView
inside of it UICollectionView
加入与两个故事板,以查看控制器delegate
和dataSource
设置为视图控制器和标准出口设置numberOfSectionsInRow
& cellForItemAtIndexPath
都实现并引用试制的电池和imageView
在它的内部
Here is the code that goes to Twitter, get's a timeline, assigns it to a variable, reloads a table view with the tweets and then goes through the tweets to find photos and reloads the collection view with those items. 以下是转到Twitter的代码,获取时间轴,将其分配给变量,使用推文重新加载表格视图,然后通过推文查找照片并使用这些项目重新加载集合视图。
Even if I comment out the code to display the image, it still doesn't change anything. 即使我注释掉显示图像的代码,它仍然不会改变任何东西。
SLRequest *timelineRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:timelineURL parameters:timelineParams];
[timelineRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
if(responseData) {
JSONDecoder *decoder = [[JSONDecoder alloc] init];
NSArray *timeline = [decoder objectWithData:responseData];
[self setTwitterTableData:timeline];
for(NSDictionary *tweet in [self twitterTableData]) {
if(![tweet valueForKeyPath:@"entities.media"]) { continue; }
for(NSDictionary *photo in [[tweet objectForKey:@"entities"] objectForKey:@"media"]) {
[[self photoStreamArray] addObject:[NSDictionary dictionaryWithObjectsAndKeys:
[photo objectForKey:@"media_url"], @"url",
[NSValue valueWithCGSize:CGSizeMake([[photo valueForKeyPath:@"sizes.large.w"] floatValue], [[photo valueForKeyPath:@"sizes.large.h"] floatValue])], @"size"
, nil]];
}
}
[[self photoStreamCollectionView] reloadData];
}
}];
This is a classic symptom of calling UIKit methods from a background thread. 这是从后台线程调用UIKit方法的经典症状。 If you view the
-[SLRequest performRequestWithHandler:]
documentation , it says the handler makes no guarantee of which thread it will be run on. 如果你查看
-[SLRequest performRequestWithHandler:]
文档 ,它说处理程序不保证它将在哪个线程上运行。
Wrap your call to reloadData
in a block and pass this to dispatch_async()
; 在块中包含对
reloadData
的调用并将其传递给dispatch_async()
; also pass dispatch_get_main_queue()
as the queue argument. 还将
dispatch_get_main_queue()
作为队列参数传递。
You need to dispatch the update to the main thread: 您需要将更新分派给主线程:
dispatch_async(dispatch_get_main_queue(), ^{
[self.photoStreamCollectionView reloadData];
});
or in Swift: 或者在Swift中:
dispatch_async(dispatch_get_main_queue(), {
self.photoStreamCollectionView.reloadData()
})
Apple say:You should not call this method in the middle of animation blocks where items are being inserted or deleted. Apple说:你不应该在插入或删除项目的动画块中间调用此方法。 Insertions and deletions automatically cause the table's data to be updated appropriately.
插入和删除会自动使表的数据得到适当更新。
In face: You should not call this method in the middle of any animation (include UICollectionView in the scrolling). 面对:你不应该在任何动画的中间调用这个方法(在滚动中包含UICollectionView)。
so, you can: 所以你可以:
[self.collectionView setContentOffset:CGPointZero animated:NO];
[self.collectionView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
or mark sure not any animation, and then call reloadData; 或者确定没有任何动画,然后调用reloadData; or
要么
[self.collectionView performBatchUpdates:^{
//insert, delete, reload, or move operations
} completion:nil];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.