web-dev-qa-db-ja.com

データが設定された後、UICollectionViewセルのサイズを変更します

UICollectionViewセルには、複数行のテキストを含むUILabelsが含まれています。テキストがラベルに設定されるまで、セルの高さはわかりません。

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

これは、セルのサイズを決定するための最初の方法でした。ただし、これはセルがストーリーボードから作成される前に呼び出されます。

コレクションをレイアウトし、レンダリングされた後にセルのサイズを変更する方法はありますか?また、セルの実際のサイズを知っていますか?

48
Shocks

UICollectionViewの.collectionViewLayoutプロパティで呼び出すことができるinvalidateLayoutメソッドを探していると思います。このメソッドはレイアウトを再生成します。この場合、-collectionView: layout: sizeForItemAtIndexPath:を呼び出すことも意味します。これは、目的のアイテムのサイズを反映する適切な場所です。ジルネはそれらの計算方法について正しい方向を示しています。

invalidateLayoutの使用例は here にあります。また、そのメソッドのUICollectionViewLayoutドキュメントを参照してください。

現在のレイアウトを無効にし、レイアウトの更新をトリガーします。

議論:

いつでもこのメソッドを呼び出して、レイアウト情報を更新できます。このメソッドは、コレクションビュー自体のレイアウトを無効にし、すぐに戻ります。したがって、複数のレイアウト更新をトリガーすることなく、同じコードブロックからこのメソッドを複数回呼び出すことができます。実際のレイアウト更新は、次のビューレイアウト更新サイクル中に発生します。

編集:

自動レイアウト制約を含むストーリーボードコレクションビューの場合、viewDidLayoutSubviewsUIViewControllerメソッドをオーバーライドし、このメソッドでinvalidateLayoutコレクションビューレイアウトを呼び出す必要があります。

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    [yourCollectionView.collectionViewLayout invalidateLayout];
}
72
Ignatius Tremor

uICollectionViewCellをサブクラス化し、layoutSubviewsをオーバーライドします

これにより、anchor cell leading and trailing Edge to collectionView

override func layoutSubviews() {
        super.layoutSubviews()

        self.frame = CGRectMake(0, self.frame.Origin.y, self.superview!.frame.size.width, self.frame.size.height)
    }
5
János

上記のdelegateメソッド自体で、以下のトリッキーな方法を使用してUILabelサイズを計算し、その計算に基づいてUICollectionViewCellsizeを返すことができます。

    // 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];
4
Jirune
- (void)viewDidLoad {
    self.collectionView.prefetchingEnabled = NO;
}

IOS 10では、prefetchingEnabledはデフォルトでYESです。 YESの場合、コレクションビューはセルが表示される前にセルを要求します。 iOS 10でクラッシュする

2
Sakshi Jain