49

我的 UICollectionView 单元格包含带有多行文本的 UILabel。在标签上设置文本之前,我不知道单元格的高度。

-(CGSize)collectionView:(UICollectionView *)collectionView
                 layout:(UICollectionViewLayout*)collectionViewLayout
 sizeForItemAtIndexPath:(NSIndexPath *)indexPath;

这是我研究单元格大小的初始方法。但是,这在从情节提要中创建单元之前调用。

有没有办法在渲染后布局集合和调整单元格的大小,并且我知道单元格的实际大小?

4

4 回答 4

75

我认为您正在寻找可以在UICollectionViewinvalidateLayout的属性上调用的方法。.collectionViewLayout此方法会重新生成您的布局,在您的情况下也意味着调用-collectionView: layout: sizeForItemAtIndexPath:,这是反映您所需项目大小的正确位置。Jirune 指出了如何计算它们的正确方向。

invalidateLayout可以在此处找到使用的示例。另请参阅有关该方法的 UICollectionViewLayout 文档:

使当前布局无效并触发布局更新。

讨论:

您可以随时调用此方法来更新布局信息。此方法使集合视图本身的布局无效并立即返回。因此,您可以从同一个代码块中多次调用此方法,而不会触发多次布局更新。实际的布局更新发生在下一个视图布局更新周期。

编辑:

对于包含自动布局约束的故事板集合视图,您需要覆盖该viewDidLayoutSubviews方法UIViewController并在该方法中调用invalidateLayout集合视图布局。

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    [yourCollectionView.collectionViewLayout invalidateLayout];
}
于 2012-12-09T11:05:47.460 回答
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)
    }
于 2014-09-03T09:52:52.460 回答
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];
于 2012-12-07T18:18:21.727 回答
2
- (void)viewDidLoad {
    self.collectionView.prefetchingEnabled = NO;
}

在 iOS 10 中,prefetchingEnabledYES默认设置。When YES,集合视图在显示单元格之前请求单元格。它导致 iOS 10 崩溃

于 2017-03-10T06:14:19.387 回答