![First example of custom layout](https://i.stack.imgur.com/f9WIQ.gif)
在步骤2中,我什么时候能获得小区大小如何和? 您需要计算prepareLayout()方法中每个单元的高度。每个单元格的计算结果应该分配给UICollectionViewLayoutAttributes变量,并将其放入集合NSDictionary中,其中键为NSIndexPath(每个单元格),值为UICollectionViewLayoutAttributes变量。
例子:
- (void)prepareLayout {
[_layoutMap removeAllObjects];
_totalItemsInSection = [self.collectionView numberOfItemsInSection:0];
_columnsYoffset = [self initialDataForColumnsOffsetY];
if (_totalItemsInSection > 0 && self.totalColumns > 0) {
[self calculateItemsSize];
NSInteger itemIndex = 0;
CGFloat contentSizeHeight = 0;
while (itemIndex < _totalItemsInSection) {
NSIndexPath *targetIndexPath = [NSIndexPath indexPathForItem:itemIndex inSection:0];
NSInteger columnIndex = [self columnIndexForItemAtIndexPath:targetIndexPath];
// you need to implement this method and perform your calculations
CGRect attributeRect = [self calculateItemFrameAtIndexPath:targetIndexPath];
UICollectionViewLayoutAttributes *targetLayoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:targetIndexPath];
targetLayoutAttributes.frame = attributeRect;
contentSizeHeight = MAX(CGRectGetMaxY(attributeRect), contentSizeHeight);
_columnsYoffset[columnIndex] = @(CGRectGetMaxY(attributeRect) + self.interItemsSpacing);
_layoutMap[targetIndexPath] = targetLayoutAttributes;
itemIndex += 1;
}
_contentSize = CGSizeMake(self.collectionView.bounds.size.width - self.contentInsets.left - self.contentInsets.right,
contentSizeHeight);
}
}
不要忘记实现以下方法:当你调用reloadData()mehtod或的invalidateLayout()
- (NSArray <UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
NSMutableArray<UICollectionViewLayoutAttributes *> *layoutAttributesArray = [NSMutableArray new];
for (UICollectionViewLayoutAttributes *layoutAttributes in _layoutMap.allValues) {
if (CGRectIntersectsRect(layoutAttributes.frame, rect)) {
[layoutAttributesArray addObject:layoutAttributes];
}
}
return layoutAttributesArray;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
return _layoutMap[indexPath];
}
这些方法将被触发。
在步骤3中,我如何以及何时可以通知更改的布局? 只需调用self.collectionView.collectionViewLayout.invalidateLayout()和prepareLayout()方法就会再次被调用,因此您可以重新计算所需的所有参数。
你可以找到我的有关自定义UICollectionViewLayout完全教程这里:https://octodev.net/custom-collectionviewlayout/
教程包含两种语言实现:斯威夫特和Objective-C。 会很乐意回答你所有的问题。
嗨根据你的问题,你可以创建[UICollectionView](http://www.appcoda.com/ios-programming-uicollectionview-tutorial/)。 但用[自定义单元格](http://corsarus.com)创建自定义[UICollectionViewLayout](http://www.raywenderlich.com/22324/beginning-uicollectionview-in-ios-6-part-12)/2015 /收集 - 视图 - 用自施胶细胞/)。 –