我的UICollectionView单元格包含带有多行文字的UILabel。在标签上设置文本之前,我不知道单元格的高度。
-(CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
这是我查看细胞大小的初始方法。但是,这是在故事板之外创建单元格之前调用的。
有没有办法布置集合并在渲染后调整单元格大小,我知道单元格的实际大小?
答案 0 :(得分:72)
我认为您正在寻找可以在UICollectionView的invalidateLayout
属性上调用的.collectionViewLayout
方法。此方法会重新生成您的布局,在您的情况下,这也意味着调用-collectionView: layout: sizeForItemAtIndexPath:
,这是反映所需项目大小的正确位置。 Jirune指出了如何计算它们的正确方向。
可以找到使用invalidateLayout
的示例here。另请参阅有关该方法的UICollectionViewLayout文档:
使当前布局无效并触发布局更新。
<强>讨论:强>
您可以随时调用此方法来更新布局信息。此方法使集合视图本身的布局无效并立即返回。因此,您可以从同一代码块多次调用此方法,而不会触发多个布局更新。实际布局更新发生在下一个视图布局更新周期中。
修改:
对于包含自动布局约束的storyboard集合视图,您需要覆盖viewDidLayoutSubviews
的{{1}}方法,并在此方法中调用UIViewController
集合视图布局。
invalidateLayout
答案 1 :(得分:5)
子类UICollectionViewCell并覆盖layoutSubviews
,就像这样
因此,您将将单元格前导和后沿锚定到collectionView
override func layoutSubviews() {
super.layoutSubviews()
self.frame = CGRectMake(0, self.frame.origin.y, self.superview!.frame.size.width, self.frame.size.height)
}
答案 2 :(得分:4)
嘿,在上面的delegate
方法中,您可以使用以下棘手的方式计算UILabel
大小,并根据该计算返回UICollectionViewCell
size
。
// Calculate the expected size based on the font and
// linebreak mode of your label
CGSize maximumLabelSize = CGSizeMake(9999,9999);
CGSize expectedLabelSize =
[[self.dataSource objectAtIndex:indexPath.item]
sizeWithFont:[UIFont fontWithName:@"Arial" size:18.0f]
constrainedToSize:maximumLabelSize
lineBreakMode:NSLineBreakByWordWrapping];
答案 3 :(得分:2)
- (void)viewDidLoad {
self.collectionView.prefetchingEnabled = NO;
}
在iOS 10中,prefetchingEnabled
默认为YES
。当YES
时,集合视图会在它们显示的时间之前请求单元格。它导致iOS 10崩溃