UICollectionView 布局不一致,UICollectionViewFlowLayout
Posted
技术标签:
【中文标题】UICollectionView 布局不一致,UICollectionViewFlowLayout【英文标题】:UICollectionView not consistent layout, UICollectionViewFlowLayout 【发布时间】:2013-04-01 18:32:20 【问题描述】:我无法以一致的方式在 UICollectionView 中显示单元格。单元格的初始显示是正确的,但是每次用户滚动过去然后返回到一组单元格时,显示都是不正确的。行应该只包含 2 或 1 个单元格。 2 个单元格各占显示宽度的一半,1 个单元格占全宽。
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
return [self preferredSizeForIndexPath:indexPath];
- (CGSize)preferredSizeForIndexPath:(NSIndexPath *)indexPath
BOOL isLastObjectInSection = NO;
NSString *sectionKey = [[arrCollectionData[indexPath.section] allKeys] objectAtIndex:0];
DLog(@"SectionKey: %@", sectionKey);
NSArray *arrSection = [arrCollectionData[indexPath.section] objectForKey:sectionKey];
DLog(@"ArrSection: %@", arrSection);
if ( arrSection[indexPath.row] == arrSection.lastObject )
if( arrSection.count % 2 != 0 )
isLastObjectInSection = YES;
CGSize cellSize = CGSizeZero;
if (UIDeviceOrientationIsLandscape([[UIDevice currentDevice] orientation]))
if (isLastObjectInSection == YES)
cellSize = CGSizeMake(IPAD_BADGE_WIDTH_LANDSCAPE_WIDE, IPAD_BADGE_HEIGHT_LANDSCAPE_WIDE);
else
cellSize = CGSizeMake(IPAD_BADGE_WIDTH_LANDSCAPE, IPAD_BADGE_HEIGHT_LANDSCAPE);
else
if (isLastObjectInSection == YES)
cellSize = CGSizeMake(IPAD_BADGE_WIDTH_WIDE, IPAD_BADGE_HEIGHT_WIDE);
else
cellSize = CGSizeMake(IPAD_BADGE_WIDTH, IPAD_BADGE_HEIGHT);
DLog(@"CellSize: %@", NSStringFromCGSize(cellSize));
return cellSize;
以下是收集数据的示例。
Printing description of self->arrCollectionData:
<__NSArrayI 0x94bbc40>(
"March 12, 2013" = (
"<FMLeafTimelineContainer: 0x94b2430>",
"<FMLeafTimelineContainer: 0x94b3670>"
);
,
"February 25, 2013" = (
"<FMLeafTimelineContainer: 0x94b4500>"
);
,
"February 14, 2013" = (
"<FMLeafTimelineContainer: 0x94b48f0>",
"<FMLeafTimelineContainer: 0x94b3a60>"
);
,
"February 12, 2013" = (
"<FMLeafTimelineContainer: 0x94b3ce0>",
"<FMLeafTimelineContainer: 0x94b2b00>"
);
,
"February 4, 2013" = (
"<FMCommunityTimelineContainer: 0x94b4e90>",
"<FMCommunityTimelineContainer: 0x94b5050>",
"<FMCommunityTimelineContainer: 0x94b5f70>"
);
,
"January 30, 2013" = (
"<FMCommunityTimelineContainer: 0x94b6ad0>",
"<FMCommunityTimelineContainer: 0x94b5a90>"
);
,
"January 24, 2013" = (
"<FMCommunityTimelineContainer: 0x94b5d00>",
"<FMCommunityTimelineContainer: 0x94b6d90>"
);
,
"January 22, 2013" = (
"<FMCommunityTimelineContainer: 0x94b6440>"
);
,
"January 21, 2013" = (
"<FMCommunityTimelineContainer: 0x94b6260>",
"<FMCommunityTimelineContainer: 0x94b62e0>",
"<FMCommunityTimelineContainer: 0x94b70c0>",
"<FMCommunityTimelineContainer: 0x94b55a0>",
"<FMCommunityTimelineContainer: 0x94b82d0>",
"<FMCommunityTimelineContainer: 0x94b78b0>"
);
,
"December 20, 2012" = (
"<FMCommunityTimelineContainer: 0x94b53f0>"
);
,
"December 6, 2012" = (
"<FMCommunityTimelineContainer: 0x94b7200>"
);
,
"December 4, 2012" = (
"<FMCommunityTimelineContainer: 0x94b72b0>"
);
,
"November 19, 2012" = (
"<FMCommunityTimelineContainer: 0x94b7ae0>"
);
)
下面的图片都展示了集合视图的同一部分。
【问题讨论】:
【参考方案1】:问题是由在实例化时分配了固定帧大小的父子视图引起的。 Overrode setFrame: 用于 UICollectionView 子类分配子视图帧的值,并且每次单元格出列和重新入队时调用 setFrame: 进行相应调整。
【讨论】:
【参考方案2】:您可以尝试动态计算项目宽度。
CGFloat fullItemWidth = self.collectionView.bounds.size.width;
NSInteger itemsPerRow = 2;
CGFloat itemWidth = (fullItemWidth - (itemsPerRow-1)*self.collectionView.collectionViewLayout.minimumInteritemSpacing)/itemsPerRow;
if (UIDeviceOrientationIsLandscape([[UIDevice currentDevice] orientation]))
if (isLastObjectInSection == YES)
cellSize = CGSizeMake(fullItemWidth, IPAD_BADGE_HEIGHT_LANDSCAPE_WIDE);
else
cellSize = CGSizeMake(halfItemWidth, IPAD_BADGE_HEIGHT_LANDSCAPE);
else
if (isLastObjectInSection == YES)
cellSize = CGSizeMake(fullItemWidth, IPAD_BADGE_HEIGHT_WIDE);
else
cellSize = CGSizeMake(halfItemWidth, IPAD_BADGE_HEIGHT);
【讨论】:
以上是关于UICollectionView 布局不一致,UICollectionViewFlowLayout的主要内容,如果未能解决你的问题,请参考以下文章