我使用UICollectionView
显示从远程服务器收到的一些数据,并且我在短时间内拨打了两个reloadData
电话,第一个用于显示微调器(实际上是UIActivityIndicatorView
中的UICollectionViewCell
,第二个是从服务器检索数据后的。我存储基于其在self.models
NSArray中创建集合视图单元格的模型,并在cellForItemAtIndexPath
中基于此模型使单元格出列。我的问题是,当我在请求完成后(第二次)调用reloadData
时,集合视图似乎仍在为第一个reloadData
调用创建单元格,它只显示前两个细胞和一个大的空白区域,其余的细胞应该出现在那里。
我写了一些日志,以便了解发生了什么以及当前的工作流程:
我使用spinner单元格的模型填充self.models
,然后在UICollectionView上调用reloadData
。
numberOfItemsInSection
被调用,它只是返回[self.models count]
。返回值为2,这很好(一个单元格像标题+第二个单元格,里面是UIActivityIndicator)。
我正在向服务器发出请求,我得到了响应,并使用从远程服务器收到的新模型填充self.models
(删除了微调单元的模型,但保留了标题单元格)。我在UICollectionView实例上调用reloadData
。
numberOfItemsInSection
,现在返回从远程服务器检索的项目数+标题单元格的模型(假设返回的值为21)。 / p>
刚刚调用cellForItemAtIndexPath
时只是两次(这是numberOfItemsInSection
首次调用时返回的值)。
当我第二次调用此方法时,似乎集合视图正忙于第一个reloadData
。如何告诉集合视图停止加载第一个reloadData
调用的单元格?我尝试[self.collectionView.collectionViewLayout invalidateLayout]
似乎有效,但问题再次出现,所以它没有做到这一点。
我的代码中的一些片段:
- (void)viewDidLoad {
[super viewDidLoad];
[ ...... ]
self.models = @[];
self.newsModels = [NSMutableArray array];
[self.collectionView.collectionViewLayout invalidateLayout];
[self buildModel:YES]; // to show the loading indicator
[self.collectionView reloadData];
[self updateNewsWithBlock:^{
dispatch_async(dispatch_get_main_queue(), ^{
[self.collectionView.collectionViewLayout invalidateLayout];
[self buildModel:NO];
[self.collectionView reloadData];
});
}];
}
- (void) buildModel:(BOOL)showSpinnerCell {
NSMutableArray *newModels = [NSMutableArray array];
[newModels addObject:self.showModel]; // self.showModel is the model for the cell which acts as a header
if ([self.newsModels count] != 0) {
// self.newsModels is populated in [self updateNewsWithBlock], see below
[newModels addObjectsFromArray:self.newsModels];
} else if (showSpinnerCell) {
[newModels addObject:[SpinnerCellModel new]];
}
self.models = [NSArray arrayWithArray:newModels];
}
- (void) updateNewsWithBlock:(void (^)())block {
// Here I'm performing a GET request using `AFHTTPSessionManager` to retrieve
// some XML data from a backend, then I'm processing it and
// I'm instantiating some NewsCellModel objects which represents the models.
[ ..... ]
for (NSDictionary *item in (NSArray*)responseObject) {
NewsCellModel *model = [[NewsCellModel alloc] init];
model.itemId = [item[@"id"] integerValue];
model.title = item[@"title"];
model.headline = item[@"short_text"];
model.content = item[@"text"];
[self.newsModels addObject:model];
}
block();
}