Я использую UICollectionView с двумя настраиваемыми макетами, которые подклассы из UICollectionViewFlowLayout
Когда мой просмотр сначала загружается, я задал его по умолчанию, используя:
[self.collectionView setCollectionViewLayout:self.tableViewLayout];
Это вызывает: cellForItemAtIndexPath
- поэтому проблем нет. Это находится в методе viewWillAppear
.
Затем я использую UIButton для изменения макета из текущего вида на следующий макет, например:
-(void)changeViewLayoutButtonPressed
{
self.changeLayout = !self.changeLayout;
if (self.changeLayout){
[self.tradeFeedCollectionView setCollectionViewLayout:self.grideLayout animated:YES];
}
else {
[self.tradeFeedCollectionView setCollectionViewLayout:self.tableViewLayout animated:YES];
}
}
После вызова этого вызова - numberOfItemsInSection
. Я проверил в отладчике, что возвращаемая учетная запись не равна нулю.
После этого вызова ничего не вызывается, и мой UICollectionView меняет макет, но поскольку cellForItemAtIndexPath
не вызывается - ячейки не настроены правильно.
если я помещаю [self.collectionView roloadData]
внутри numberOfItemsInSection
- тогда вызывается cellForItemAtIndexPath
и устанавливаются ячейки.
Мне не нужно выполнять ручной вызов для перезагрузки данных в numberOfItemsInSection
. Может кто-нибудь сказать мне, что происходит?
Edit
Я забыл упомянуть, что я использую два разных UINib для двух разных ячеек, поскольку им нужны несколько разные макеты, применяемые к ним. Будет ли это проблемой? Спасибо!
Изменить 2
Правильно, поэтому я получил работу почти так, как хочу. Вот весь код, используемый для представления коллекции и как я изменяю его макеты.
Пользовательские макеты
Они подклассифицированы из UICollectionViewFlowLayout
. Причина, по которой я подклассифицирован, просто из-за лица, которому мой UICollectionView
должен выглядеть и вести себя очень близко к готовому макету Apple. Однако разные размеры ячеек.
TableViewLayout - Нет кода в файле заголовка. - BBTradeFeedTableViewLayout.m
@implementation BBTradeFeedTableViewLayout
-(id)init
{
self = [super init];
if (self){
self.itemSize = CGSizeMake(320, 80);
self.minimumLineSpacing = 0.1f;
}
return self;
}
@end
Макет Gride - Нет кода в файле заголовка. - BBTradeFeedGridViewLayout.m
@implementation BBTradeFeedGridViewLayout
-(id)init
{
self = [super init];
if (self){
self.itemSize = CGSizeMake(159, 200);
self.minimumInteritemSpacing = 0.1f;
self.minimumLineSpacing = 0.1f;
}
return self;
}
@end
Затем в ViewController
, у которого есть мой UICollectionView
- я объявляю два пользовательских макета, например:
@property (strong, nonatomic) BBTradeFeedTableViewLayout *tableViewLayout;
@property (strong, nonatomic) BBTradeFeedGridViewLayout *grideLayout;
Затем я регистрирую два .xib файла для коллекции:
[self.tradeFeedCollectionView registerNib:[UINib nibWithNibName:@"BBItemTableViewCell" bundle:nil] forCellWithReuseIdentifier:@"TableItemCell"];
[self.tradeFeedCollectionView registerNib:[UINib nibWithNibName:@"BBItemGridViewCell" bundle:nil] forCellWithReuseIdentifier:@"GridItemCell"];
Затем у меня есть UIButton, который меняет макет:
-(void)changeViewLayoutButtonPressed
{
if (!self.gridLayoutActive){
self.gridLayoutActive = YES;
[self.tradeFeedCollectionView setCollectionViewLayout:self.grideLayout animated:YES];
self.lastLayoutUsed = @"GridLayout";
}
else {
self.gridLayoutActive = NO;
[self.tradeFeedCollectionView setCollectionViewLayout:self.tableViewLayout animated:YES];
self.lastLayoutUsed = @"TableLayOut";
}
[self.tradeFeedCollectionView reloadItemsAtIndexPaths:[self.tradeFeedCollectionView indexPathsForVisibleItems]];
}
Наконец - когда вызов веб-службы завершен - он вызывает [self.tradeFeedCollectionView reloadData];
Итак, мой UICollectionView
получает перезагрузку и последний метод:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{ static NSString *tableCellIdentifier = @"TableItemCell";
static NSString *gridCellIdentifier = @"GridItemCell";
if (indexPath.item < [self.tradeSearchArray count]){
if (self.gridLayoutActive == NO){
BBItemTableViewCell *tableItemCell = [collectionView dequeueReusableCellWithReuseIdentifier:tableCellIdentifier forIndexPath:indexPath];
if ([self.tradeSearchArray count] > 0){
self.toolBarButtomItem.title = [NSString stringWithFormat:@"%d Results", self.searchResult.searchResults];
tableItemCell.gridView = NO;
tableItemCell.backgroundColor = [UIColor whiteColor];
tableItemCell.item = self.tradeSearchArray[indexPath.row];
}
return tableItemCell;
}else
{
BBItemTableViewCell *gridItemCell= [collectionView dequeueReusableCellWithReuseIdentifier:gridCellIdentifier forIndexPath:indexPath];
if ([self.tradeSearchArray count] > 0){
self.toolBarButtomItem.title = [NSString stringWithFormat:@"%d Results", self.searchResult.searchResults];
gridItemCell.gridView = YES;
gridItemCell.backgroundColor = [UIColor whiteColor];
gridItemCell.item = self.tradeSearchArray[indexPath.row];
}
return gridItemCell;
}
Проблема с приведенным выше кодом
Вышеприведенный код действительно работает. Тем не менее, клетки не ожидают красиво, и это выглядит странно, почти как если бы произошло обновление. Который вызван:
[self.tradeFeedCollectionView reloadItemsAtIndexPaths:[self.tradeFeedCollectionView indexPathsForVisibleItems]];
Но это единственный способ заставить его быть ближе к тому, что я хочу.