UICollectionView 自定义单元格布局
UICollectionView custom cell layout
我有一个 UICollectionView,我正在尝试对其进行一些自定义。
这是我想要的:
这是我的资料:
我认为从 UICollectionViewDelegate 实现 sizeForItemAtIndexPath 就足够了。
这是我正在做的事情:
- 我为所有单元格的宽度返回屏幕宽度的一半
- 对于第一个和第三个单元格,我返回 50 的高度
- 对于第二个单元格,我返回 100 的高度。
我做错了什么?
用简单的 UICollectionViewDelegateFlowLayout
方法无法做到这一点。您有来自 UICollectionViewFlowLayout
.
的子class
这里是非常脏的例子,你可以如何做到这一点
@interface CVFlowLayout1 : UICollectionViewFlowLayout
@property (nonatomic, strong) NSDictionary *layoutInfo;
@end
@implementation CVFlowLayout1
- (instancetype)init
{
if (self = [super init])
{
self.minimumLineSpacing = 0;
self.minimumInteritemSpacing = 0;
}
return self;
}
- (void)prepareLayout
{
NSMutableDictionary *newLayoutInfo = [NSMutableDictionary dictionary];
NSMutableDictionary *cellLayoutInfo = [NSMutableDictionary dictionary];
NSInteger sectionCount = [self.collectionView numberOfSections];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
for (NSInteger section = 0; section < sectionCount; section++) {
NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];
for (NSInteger item = 0; item < itemCount; item++) {
indexPath = [NSIndexPath indexPathForItem:item inSection:section];
UICollectionViewLayoutAttributes *itemAttributes =
[UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
itemAttributes.frame = CGRectMake(item == 1 ? [UIScreen mainScreen].bounds.size.width/2.0 : 0, section == 0 ? 0 : 50, [UIScreen mainScreen].bounds.size.width/2.0, item == 1 ? 100 : 50);
cellLayoutInfo[indexPath] = itemAttributes;
}
}
newLayoutInfo[@"Cell"] = cellLayoutInfo;
self.layoutInfo = newLayoutInfo;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
return self.layoutInfo[@"Cell"][indexPath];
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray *allAttributes = [NSMutableArray arrayWithCapacity:self.layoutInfo.count];
[self.layoutInfo enumerateKeysAndObjectsUsingBlock:^(NSString *elementIdentifier,
NSDictionary *elementsInfo,
BOOL *stop) {
[elementsInfo enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath,
UICollectionViewLayoutAttributes *attributes,
BOOL *innerStop) {
if (CGRectIntersectsRect(rect, attributes.frame)) {
[allAttributes addObject:attributes];
}
}];
}];
return allAttributes;
}
@end
只需将 class 的实例设置为您的 collectionView.flowLayout 属性
CVFlowLayout1 *layout = [[CVFlowLayout1 alloc] init];
[_collectionView setCollectionViewLayout:layout];
我有一个 UICollectionView,我正在尝试对其进行一些自定义。
这是我想要的:
这是我的资料:
我认为从 UICollectionViewDelegate 实现 sizeForItemAtIndexPath 就足够了。
这是我正在做的事情: - 我为所有单元格的宽度返回屏幕宽度的一半 - 对于第一个和第三个单元格,我返回 50 的高度 - 对于第二个单元格,我返回 100 的高度。
我做错了什么?
用简单的 UICollectionViewDelegateFlowLayout
方法无法做到这一点。您有来自 UICollectionViewFlowLayout
.
这里是非常脏的例子,你可以如何做到这一点
@interface CVFlowLayout1 : UICollectionViewFlowLayout
@property (nonatomic, strong) NSDictionary *layoutInfo;
@end
@implementation CVFlowLayout1
- (instancetype)init
{
if (self = [super init])
{
self.minimumLineSpacing = 0;
self.minimumInteritemSpacing = 0;
}
return self;
}
- (void)prepareLayout
{
NSMutableDictionary *newLayoutInfo = [NSMutableDictionary dictionary];
NSMutableDictionary *cellLayoutInfo = [NSMutableDictionary dictionary];
NSInteger sectionCount = [self.collectionView numberOfSections];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
for (NSInteger section = 0; section < sectionCount; section++) {
NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];
for (NSInteger item = 0; item < itemCount; item++) {
indexPath = [NSIndexPath indexPathForItem:item inSection:section];
UICollectionViewLayoutAttributes *itemAttributes =
[UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
itemAttributes.frame = CGRectMake(item == 1 ? [UIScreen mainScreen].bounds.size.width/2.0 : 0, section == 0 ? 0 : 50, [UIScreen mainScreen].bounds.size.width/2.0, item == 1 ? 100 : 50);
cellLayoutInfo[indexPath] = itemAttributes;
}
}
newLayoutInfo[@"Cell"] = cellLayoutInfo;
self.layoutInfo = newLayoutInfo;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
return self.layoutInfo[@"Cell"][indexPath];
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray *allAttributes = [NSMutableArray arrayWithCapacity:self.layoutInfo.count];
[self.layoutInfo enumerateKeysAndObjectsUsingBlock:^(NSString *elementIdentifier,
NSDictionary *elementsInfo,
BOOL *stop) {
[elementsInfo enumerateKeysAndObjectsUsingBlock:^(NSIndexPath *indexPath,
UICollectionViewLayoutAttributes *attributes,
BOOL *innerStop) {
if (CGRectIntersectsRect(rect, attributes.frame)) {
[allAttributes addObject:attributes];
}
}];
}];
return allAttributes;
}
@end
只需将 class 的实例设置为您的 collectionView.flowLayout 属性
CVFlowLayout1 *layout = [[CVFlowLayout1 alloc] init];
[_collectionView setCollectionViewLayout:layout];