UICollectionViewセルには、複数行のテキストを含むUILabelsが含まれています。テキストがラベルに設定されるまで、セルの高さはわかりません。
-(CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
これは、セルのサイズを決定するための最初の方法でした。ただし、これはセルがストーリーボードから作成される前に呼び出されます。
コレクションをレイアウトし、レンダリングされた後にセルのサイズを変更する方法はありますか?また、セルの実際のサイズを知っていますか?
UICollectionViewの.collectionViewLayout
プロパティで呼び出すことができるinvalidateLayout
メソッドを探していると思います。このメソッドはレイアウトを再生成します。この場合、-collectionView: layout: sizeForItemAtIndexPath:
を呼び出すことも意味します。これは、目的のアイテムのサイズを反映する適切な場所です。ジルネはそれらの計算方法について正しい方向を示しています。
invalidateLayout
の使用例は here にあります。また、そのメソッドのUICollectionViewLayoutドキュメントを参照してください。
現在のレイアウトを無効にし、レイアウトの更新をトリガーします。
議論:
いつでもこのメソッドを呼び出して、レイアウト情報を更新できます。このメソッドは、コレクションビュー自体のレイアウトを無効にし、すぐに戻ります。したがって、複数のレイアウト更新をトリガーすることなく、同じコードブロックからこのメソッドを複数回呼び出すことができます。実際のレイアウト更新は、次のビューレイアウト更新サイクル中に発生します。
編集:
自動レイアウト制約を含むストーリーボードコレクションビューの場合、viewDidLayoutSubviews
のUIViewController
メソッドをオーバーライドし、このメソッドでinvalidateLayout
コレクションビューレイアウトを呼び出す必要があります。
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[yourCollectionView.collectionViewLayout invalidateLayout];
}
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)
}
上記の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];
- (void)viewDidLoad {
self.collectionView.prefetchingEnabled = NO;
}
IOS 10では、prefetchingEnabled
はデフォルトでYES
です。 YES
の場合、コレクションビューはセルが表示される前にセルを要求します。 iOS 10でクラッシュする