在设置数据后调整UICollectionView单元格的大小

时间:2012-12-06 18:48:48

标签: objective-c uicollectionview uicollectionviewcell

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

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

这是我查看细胞大小的初始方法。但是,这是在故事板之外创建单元格之前调用的。

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

4 个答案:

答案 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崩溃