IOS UICollectionview Динамически меняет высоту ячеек

Я работаю над проектом Collection-view Based, на котором Numberofitem будет изменен и увеличен в соответствии с пользователем, нажмите на Partical Index. все отлично работает в моем проекте, но я не могу установить размер ячейки в соответствии с количеством ячеек в виде коллекции. Кроме того, просмотр коллекции не будет прокручиваться во всех ячейках с учетом размера. Здесь я прикрепил все изображение.

1) Просмотр раскадровки

StoryboardView

2) Результат с четырьмя ячейками

Результат с четырьмя ячейками

3), когда количество ячеек увеличивается

при увеличении количества ячеек

В настоящее время я сделал настройку своей ячейки таким образом с помощью следующего кода. но я хочу установить это, если в коллекции есть четыре ячейки, размер каждой ячейки увеличивается и подбирается в соответствии с размером коллекции и размером устройства (iphone 5s, iphone 6, iphone 6plus).

Вот мой Try,

-(CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section{
    return 5.0;
}
-(CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{
    return 5.0;
}
- (CGSize)collectionView:(UICollectionView *)collectionView
              layout:(UICollectionViewLayout *)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
        ////@property NSInteger count;////
 if (_count == 0)  {
    //  width = ((width - (span*5))/4);
    //        return CGSizeMake(self.view.frame.size.width/4,  self.view.frame.size.height/4);
    return CGSizeMake(self.view.frame.size.width/2.5, self.view.frame.size.height/5);
}
if (_count == 1 || _count == 2)
{
    return CGSizeMake(self.view.frame.size.width/2.5, self.view.frame.size.height/5);
    // return CGSizeMake(100.0, 100.0);
}
if (  _count == 3 || _count == 4 || _count == 5)
{
    // return CGSizeMake(100.0, 100.0);
    return CGSizeMake(self.view.frame.size.width/3.5, self.view.frame.size.height/6.5);
}
if (  _count == 6 || _count == 7 || _count == 8 || _count == 9)
{
    //return CGSizeMake(90.0, 90.0);
    return CGSizeMake(self.view.frame.size.width/4, self.view.frame.size.height/8);
}
if (  _count == 10 || _count == 11 || _count == 12 || _count == 13 || _count == 14)
{
    //  return CGSizeMake(80.0, 80.0);
    return CGSizeMake(self.view.frame.size.width/4, self.view.frame.size.height/8);
}
if (  _count == 15 || _count == 16 || _count == 17 || _count == 18 || _count == 19 || _count ==20)
{
    //return CGSizeMake(70.0, 70.0);
    return CGSizeMake(self.view.frame.size.width/4.75, self.view.frame.size.height/9.5);
}
if (_count ==21 || _count == 22 || _count == 23 || _count == 24 || _count == 25 || _count == 26 || _count == 27) {
    // return CGSizeMake(60.0, 60.0);
    return CGSizeMake(self.view.frame.size.width/6, self.view.frame.size.height/12);
}
if (_count ==28 || _count == 29  ) {
    //  return CGSizeMake(50.0, 50.0);
    return CGSizeMake(self.view.frame.size.width/6.25, self.view.frame.size.height/12.5);
}
else
    return CGSizeMake(0, 0);
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return itemincollectionview.count;
}

Примечание: -    Я также пробовал этот метод.

  - (void)viewDidLayoutSubviews
  {
    self.automaticallyAdjustsScrollViewInsets = NO;
    [self.collectionView layoutIfNeeded];
    NSArray *visibleItems = [self.collectionView indexPathsForVisibleItems];
    NSIndexPath *currentItem = [visibleItems objectAtIndex:0];
    NSIndexPath *nextItem = [NSIndexPath indexPathForItem:_setRandomIndex inSection:currentItem.section];

    [self.collectionView scrollToItemAtIndexPath:nextItem atScrollPosition:UICollectionViewScrollPositionNone animated:YES];
 }

 - (void)viewWillLayoutSubviews
 {
    [super viewWillLayoutSubviews];
    [self.collectionView.collectionViewLayout invalidateLayout];
 }

 -(void)viewWillAppear:(BOOL)animated
 {
     [super viewWillAppear:YES];
     [self.view layoutIfNeeded];
 }

Ответ 1

Насколько я понимаю, вы хотите воспроизвести макет этого теста.

Вам нужно лучше понять, как UICollectionView работает как здесь

Вам придется изменить количество элементов в UICollectionView в этом методе делегата:

- (NSInteger)numberOfItemsInSection:(NSInteger)section;

Здесь вы хотите вернуть 4 в начале теста, затем 4 * 2, 4 * 2 * 2 и т.д. Это даст вам правильное количество элементов.

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

Вам нужно быть осторожным с интервалом, потому что это может вызвать принуждение ячейки в следующей строке

Вы уже отлично справились, разделив фрейм, чтобы получить максимальную высоту и ширину ячейки, но ваш

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

Метод действительно грязный.

Поскольку у вас не будет неограниченного количества элементов в UICollectionView, вы можете использовать switch statement, и в каждом коммутаторе вы возвращаете вычисленный CGSize ячейки.

Например, вы можете использовать его следующим образом:

    switch (numberOfHorizontalItems) {
      case 2:
            return CGSizeMake(self.collectionView.frame.size.width/2.5,self.collectionView.frame.size.width/2.5);
                break;

    case 4:
                return CGSizeMake(self.collectionView.frame.size.width/4.5,self.collectionView.frame.size.width/4.5);
                break;
    case 8:
                CGSizeMake(self.collectionView.frame.size.width/8.5,self.collectionView.frame.size.width/8.5);
                break;
(And so on)

      default:
                break;
        }

Вы должны заметить, что вычисленный здесь CGSize должен включать интервал/слияние между items

Вам также не нужны viewWillLayoutSubviews и viewDidLayoutSubviews, вам просто нужно вызвать [self.collectionView reloadData], когда пользователь постучал по ячейке (или в методе обработки логики после того, как пользователь нажал на ячейку)

Наконец, если вы не хотите прокручивать UICollectionView, просто установите свойство self.collectionView.scrollEnabled = NO;

Ответ 2

Следуйте этой ссылке в блоге, которая очень легко иллюстрируется с пример кода: http://www.fantageek.com/1468/ios-dynamic-table-view-cells-with-varying-row-height-and-autolayout/

Верхняя ссылка предназначена для просмотра таблицы, но таким же образом вы можете работать с представлением коллекции и достичь желаемого результата.

Примечание. Все это касается приоритета сжатия содержимого и приоритета сжатия содержимого.

Ответ 3

Итак, я добавляю ответ в swift, но это решение работает только при условии, что у вас есть значение минимальной ширины.

/**
Calculates the CollectionView Cell Size when the parent view is loaded. It happens only once per VC Lifecycle.
- returns: `width` - The cell width calculated from the current screen size. <p/> `height` - The cell height, which is fixed for now.
*/
private class func getCellSize() -> (size: CGSize) {

    var cellWidth: CGFloat, cellHeight: CGFloat

    //Notes: CellSpacing you want to have
    let CellSpacing: CGFloat = 5    

    // Notes: Minimum Cell Width that renders for all the screens        
    let MinCellWidth:CGFloat = 130      

    let screenWidth: CGFloat = UIScreen.mainScreen().bounds.size.width
    let numberOfCellsPerRow: Int = Int((screenWidth + CellSpacing) / (MinCellWidth + CellSpacing))
    let totalSpaceTaken: Int = (Int(MinCellWidth + CellSpacing) * numberOfCellsPerRow)
    let remainingWidth = Int(screenWidth + CellSpacing) - totalSpaceTaken

    cellWidth = MinCellWidth + CGFloat((remainingWidth/numberOfCellsPerRow))

    //Now calculate the height based on the Width:Height Ratio. 
    // Assuming it is 1:1.5

    cellHeight = cellWidth * 1.5

    return CGSizeMake(cellWidth, FixedCellHeight)
}

Это можно легко преобразовать в Objective-C. Все, что мы делаем, это получение ширины экрана и проверка количества ячеек, в которые мы можем поместиться, и подгонки их с правильным интервалом между ячейками.

Примечание. Вам нужно только один раз вызвать метод getCellSize() и использовать тот же CGSize в методе ниже.

//In your viewDidLoad 
CGSize cellSize = [self getCellSize];

//In this function you pass the property you initialised above
- (CGSize)collectionView:(UICollectionView *)collectionView
              layout:(UICollectionViewLayout *)collectionViewLayout
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath 
 {
    return self.cellSize;
 }

Примечание.. Работает только в том случае, если ваш collectionView.width = viewController.width, т.е. ширина вашего коллекционного просмотра обнимает контроллер представления, или размер коллекцииView равен размеру экрана, как то, как оно было задано в вопросе.

Ответ 4

Используйте этот GitHub CHTCollectionViewWaterfallLayout - это подкласс UICollectionViewLayout, и он пытается максимально имитировать использование UICollectionViewFlowLayout.

Этот макет вдохновлен Pinterest. Он также совместим с PSTCollectionView.

Ответ 5

Все в вашем проекте прекрасно, просто вам нужно добавить новый метод делегата следующим образом:

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsMake(15, 20, 20, 20);
}

Изменяйте этот метод в соответствии с количеством ваших учетных записей. установка вставки будет распространена для:

self.view.frame.size.width/2.5

и отличается для:

self.view.frame.size.width/3.5

поэтому проблема с дополнительным интервалом будет решена.