Динамически установить ContentSize в UICollectionView

У меня есть UICollectionView, который был создан программно. После создания представления коллекции я хотел бы динамически определить высоту представления коллекции, основываясь на количестве ячеек, которые она должна удерживать. Я не хочу включать прокрутку самого представления коллекции, скорее это представление коллекции добавляется в виде подсмотра в представление, которое содержится внутри вертикального UIScrollView.

Например, если UICollectionView имеет 10 UICollectionViewCells. Он может иметь высоту 200.0f, но если он имеет 20 ячеек, он может иметь высоту 300.0f и т.д.

Я попытался выполнить это, следуя документам Apple здесь, переопределив метод collectionViewContentSize.

Хотя этот метод возвращает верный CGSize, когда он вызывается, когда я создаю экземпляр коллекции, его frame всегда устанавливается в ноль.

Вот что я сделал до сих пор:

//subclass UICollectionViewFlowLayout

@interface LabelLayout : UICollectionViewFlowLayout

@property (nonatomic, assign) NSInteger cellCount;
@property (nonatomic) UIEdgeInsets sectionInset;
@property (nonatomic) CGSize itemSize;
@property (nonatomic) CGFloat minimumLineSpacing;
@property (nonatomic) CGFloat minimumInteritemSpacing;

@end

- (id)init
{
   self = [super init];
    if (self) {
        [self setup];
    }

return self;
}

-(void)prepareLayout
{
    [super prepareLayout];
    _cellCount = [[self collectionView] numberOfItemsInSection:0];
}

- (void)setup
{
    self.sectionInset = UIEdgeInsetsMake(10.0f, 0.0f, 10.0f, 0.0f);
    self.itemSize = CGSizeMake(245.0f, 45.0f);
    self.minimumLineSpacing = 10.0f;
    self.minimumInteritemSpacing = 20.0f;
}

- (CGSize)collectionViewContentSize
{
   CGFloat collectionViewWidth = 550;
   CGFloat topMargin = 10;
   CGFloat bottomMargin = 10;
   CGFloat collectionViewHeight = (self.cellCount * (self.itemSize.height +    
   self.minimumLineSpacing*2)) + topMargin + bottomMargin;

   //THIS RETURNS A VALID, REASONABLE SIZE, but the collection view frame never gets set with it!
   return CGSizeMake(collectionViewWidth, collectionViewHeight);
 }

//create collectionView in viewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self makeLabels]; //determines the number of cells

    LabelLayout *layout = [[LabelLayout alloc]init];
    self.collectionView = [[UICollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:layout];   
    self.collectionView.backgroundColor = [UIColor redColor];

    self.collectionView.dataSource = self;
    self.collectionView.delegate = self;

    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:cellIdentifier];
    [self.collectionView reloadData];
    [self.view addSubview:self.collectionView];
}

Кроме того, когда я явно определяю статический фрейм для UICollectionView, он создается как ожидалось, поэтому я знаю, что моя единственная проблема заключается в использовании метода collectionViewContentSize.

Итак, мой вопрос: как я могу динамически установить высоту моего UICollectionView?

Ответ 1

Вид коллекции представляет собой вид прокрутки, поэтому ваш метод -collectionViewContentSize определяет размер содержимого, а не размер общего вида. Вам нужно установить свойство коллекции bounds или frame, чтобы установить размер самого представления коллекции.

Вы также можете установить для свойства scrollEnabled значение NO, пока вы на нем.

Ответ 2

Используйте метод sizeForItemAtIndexPath:.

В Swift:

func collectionView(_ collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize{
    return CGSizeMake(250, 150);
}

В Objective-C:

-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return CGSizeMake(250, 150);
}