Rob*_*egg 20 iphone objective-c uicollectionview
我正在使用带有两个自定义布局的UICollectionView - 它们是子类 UICollectionViewFlowLayout
当我的视图首次加载时,我使用以下命令将其设置为默认视图:
[self.collectionView setCollectionViewLayout:self.tableViewLayout];
Run Code Online (Sandbox Code Playgroud)
这叫: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];
}
}
Run Code Online (Sandbox Code Playgroud)
在此呼叫之后 - numberOfItemsInSection被呼叫.我已在调试器中检查了返回帐户不为零.
在那次调用之后,没有其他任何东西被调用,我的UICollectionView改变了布局但是因为cellForItemAtIndexPath没有被调用 - 单元格没有正确设置.
如果我把[self.collectionView roloadData]里面numberOfItemsInSection-那么cellForItemAtIndexPath被称为和细胞设置.
我不需要手动调用来重新加载数据numberOfItemsInSection.谁能告诉我发生了什么事?
编辑
我忘了提到我正在为两个不同的单元格使用两个不同的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
Run Code Online (Sandbox Code Playgroud)
Gride Layout - 头文件中没有代码. - 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
Run Code Online (Sandbox Code Playgroud)
然后在ViewController我的UICollectionView- 我声明两个自定义布局,如下所示:
@property (strong, nonatomic) BBTradeFeedTableViewLayout *tableViewLayout;
@property (strong, nonatomic) BBTradeFeedGridViewLayout *grideLayout;
Run Code Online (Sandbox Code Playgroud)
然后我为collectionView注册了两个.xib文件:
[self.tradeFeedCollectionView registerNib:[UINib nibWithNibName:@"BBItemTableViewCell" bundle:nil] forCellWithReuseIdentifier:@"TableItemCell"];
[self.tradeFeedCollectionView registerNib:[UINib nibWithNibName:@"BBItemGridViewCell" bundle:nil] forCellWithReuseIdentifier:@"GridItemCell"];
Run Code Online (Sandbox Code Playgroud)
然后,我有一个更改布局的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]];
}
Run Code Online (Sandbox Code Playgroud)
最后 - 当Web服务调用完成时 - 它调用 [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;
}
Run Code Online (Sandbox Code Playgroud)
上面代码的问题
上面的代码确实有效.然而,细胞没有很好的动画,它看起来很奇怪,几乎就像刷新了一样.这是由于致电:
[self.tradeFeedCollectionView reloadItemsAtIndexPaths:[self.tradeFeedCollectionView indexPathsForVisibleItems]];
但这是我能让它接近我想要的唯一方法.
liu*_*ong 21
-setCollectionViewLayout:或-setCollectionViewLayout:animated:不会导致您的UICollectionView重新加载.
[self.collectionView reloadData]和UICollectionViewDataSource协议方法. UICollectionView布局更改为其他布局,请致电-setCollectionViewLayout:.或者,如果您想更新UICollectionView布局,请致电[self.collectionView.collectionViewLayout invalidateLayout]. 单元格布局和数据是两个不同的东西UICollectionView.
更新
你应该丢弃所有陈旧的数据,可能是-reloadData.并为UICollectionViewLayout子类中的每个单元格计算新帧.覆盖- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath和- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect.
你决定新的contentOffset.举例来说,你可以保留一些可见单元的indexPath并决定滚动到indexPath或setContentOffset:在frame.origin同一新小区indexPath后,你的布局改变.
Art*_*eyn 16
reloadData 在切换布局之前简单地打电话(performBatchUpdates呼叫不是强制性的):
[self.collectionView reloadData];
[self.collectionView.collectionViewLayout invalidateLayout];
[self.collectionView setCollectionViewLayout:yourLayout animated:YES];
Run Code Online (Sandbox Code Playgroud)
在Swift中:
self.collectionView?.reloadData()
self.collectionView?.collectionViewLayout.invalidateLayout()
self.collectionView?.setCollectionViewLayout(yourLayout, animated: true)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
27990 次 |
| 最近记录: |