Если ваш UICollectionView
использует макет, который может иметь динамические ячейки c, макет будет переоцениваться при каждом обновлении ячейки. Это означает, что cellForItemAtIndexPath будет вызываться для большого количества ячеек.
Обратите внимание, однако, что с вашим кодом только элемент 0,0 фактически обновляется.
Измените свой код на это (обратите внимание, я изменил ваше время отправки на 3 секунды, чтобы нам не пришлось так долго ждать обновления):
@interface WithCollectionViewController ()<UICollectionViewDelegate, UICollectionViewDataSource>
@property (nonatomic, strong) IBOutlet UICollectionView* collectionView;
@property (nonatomic, strong) NSArray *colors;
@end
@implementation WithCollectionViewController
- (void)viewDidLoad {
[super viewDidLoad];
// start with colors array of red and blue
self.colors = @[[UIColor redColor], [UIColor blueColor]];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Hello"];
[self.collectionView setDataSource:self];
[self.collectionView setDelegate:self];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"calling RELOAD");
// change colors array to green and yellow
self.colors = @[[UIColor greenColor], [UIColor yellowColor]];
[self.collectionView reloadItemsAtIndexPaths:@[ [NSIndexPath indexPathForItem:0 inSection:0]]];
});
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 20;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"RELOADING %ld", indexPath.row);
NSString* identifier = @"Hello";
UICollectionViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
cell.backgroundColor = self.colors[indexPath.row % self.colors.count];
return cell;
}
@end
Сначала вы получите красный / синий узор. При срабатывании reloadItemsAtIndexPaths
массив цветов будет изменен на зеленый / желтый ... вы увидите отладочный вывод для всех 20 ячеек, но изменится только первая ячейка цвет (зеленый).
Если вы не хотите повторных вызовов, присвойте макету фиксированный размер элемента:
@interface WithCollectionViewController ()<UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
@property (nonatomic, strong) IBOutlet UICollectionView* collectionView;
@property (nonatomic, strong) NSArray *colors;
@end
@implementation WithCollectionViewController
- (void)viewDidLoad {
[super viewDidLoad];
// start with colors array of red and blue
self.colors = @[[UIColor redColor], [UIColor blueColor]];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Hello"];
[self.collectionView setDataSource:self];
[self.collectionView setDelegate:self];
UICollectionViewFlowLayout *layout = [UICollectionViewFlowLayout new];
layout.itemSize = CGSizeMake(50, 50);
[self.collectionView setCollectionViewLayout:layout];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"calling RELOAD");
// change colors array to green and yellow
self.colors = @[[UIColor greenColor], [UIColor yellowColor]];
[self.collectionView reloadItemsAtIndexPaths:@[ [NSIndexPath indexPathForItem:0 inSection:0]]];
});
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 20;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"RELOADING %ld", indexPath.row);
NSString* identifier = @"Hello";
UICollectionViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
cell.backgroundColor = self.colors[indexPath.row % self.colors.count];
return cell;
}
@end
Тот же результат, но cellForItemAtIndexPath
вызывается только для указанного вами пути индекса 0,0.