Свойство размера ячейки прототипа iOS UICollectionView игнорируется

Я использую UICollectionView с двумя прототипами ячеек. Ячейки прототипа имеют разную ширину и содержат разные элементы управления (просмотр изображений и веб-просмотр). Я определенно возвращаю правильную ячейку прототипа для данного индекса (все ячейки отображают правильное содержимое), но размер ячейки прототипа игнорируется и вместо этого используется размер элемента представления коллекции. Не то чтобы я вручную выставлял размер. Какой смысл разрешать размер ячейки прототипа в раскадровке, если свойство просто игнорируется, когда оно фактически отображается?


person minerat    schedule 24.01.2013    source источник


Ответы (9)


Размер ячейки в редакторе раскадровки нужен только для того, чтобы помочь вам спроектировать ячейку. Поскольку каждая ячейка прототипа может иметь разный размер, UICollectionView не знает, какой размер ячейки выбрать для всех ячеек. Вот почему вы устанавливаете фактический размер, который хотите использовать для своих ячеек отдельно. Вы можете сделать это в дизайнере, выбрав представление коллекции и установив для него ширину и высоту ячеек в инспекторе размеров под заголовком «Размер представления коллекции».

Или вы можете переопределить следующий метод и вернуть объект CGSize, который указывает размер, который вы хотите использовать для каждой ячейки. Используя этот метод, вы можете фактически иметь каждую ячейку разного размера:

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

Пример:

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

Ваш контроллер представления должен быть делегатом UICollectionViewDelegateFlowLayout для вызова этого метода. Поэтому не забудьте добавить это объявление делегата в файл .h вашего контроллера представления, например:

@interface MyViewController () <UICollectionViewDelegateFlowLayout>

Swift

extension MyViewController : UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 100, height: 100)
    }
}
person Alex the Ukrainian    schedule 29.01.2013
comment
Я использовал настраиваемый drawrect для добавления слоев градиента, uilabel и uiimage в мою ячейку uicollectionview, и он не рисовал правильного размера в моем представлении uicollection. Размещение этого кода в моем основном контроллере представления устранило проблему. - person MGM; 04.06.2013
comment
Если все ячейки имеют одинаковый размер, более эффективный способ указать размер - установить его в UICollectionViewFlowLayout. например flow.itemSize = CGSizeMake(50,100); - person Jason Moore; 02.05.2014
comment
Но есть ли способ программно получить доступ к ячейке прототипа из метода -collectionView:layout:sizeForItemAtIndexPath:? (Удаление ячейки из очереди с использованием идентификатора повторного использования не работает, потому что это приводит к вызову метода определения размера, что приводит к бесконечному циклу.) - person erikprice; 14.08.2014
comment
Чтобы еще больше запутать ситуацию, изменение размера ячейки прототипа в раскадровке путем перетаскивания ее маркеров изменения размера иногда приводит к изменению Cell Size контроллера, а ручной ввод размера прототипа - нет. - person Andreas; 16.10.2015

Если все ячейки одинакового размера и вы можете установить itemSize на UICollectionViewFlowLayout

Пример:

((UICollectionViewFlowLayout *) self.collectionViewLayout).itemSize = CGSizeMake(100, 100);
person Sam    schedule 11.08.2014
comment
Кажется, collectionViewLayout.itemSize недоступен в IOS6 - person Sam; 12.08.2014
comment
Он доступен в реализации UICollectionViewLayout по умолчанию, то есть - UICollectionViewFlowLayout (как упоминается в ответе). Просто забрось и пользуйся. (collectionViewLayout как? UICollectionViewFlowLayout) ?. itemSize - person Yitzchak; 15.05.2018

Swift, работает на последней версии iOS.

(collectionView.collectionViewLayout as! UICollectionViewFlowLayout).itemSize = cellSize

У меня недостаточно очков, чтобы ответить Сэму, но главное в том, что это не UICollectionViewLayout, а UICollectionViewFlowLayout.

person mxwt    schedule 02.03.2016

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

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

Выбрав макет потока в раскадровке

Затем установите Размер ячейки и Расчетный размер в инспекторе размеров.

Это помогло мне решить мою проблему.

Однако размер ячейки не будет зависеть от того, что находится в вашем sizeForItemAt.

person Roshan    schedule 22.10.2019
comment
В моем случае для параметра Estimate Size было установлено значение Automatic, также важно установить для него значение None. - person Glorfindel; 04.11.2019

Вы можете установить размер UICollectionViewCell в свойствах UICollectionView.

В раскадровке выберите Collection View в Document Outline, затем отредактируйте свой Cell Size в Size Inspector.

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

person Wanbok Choi    schedule 19.01.2015

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

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

        if indexPath.row == 0 {
                // Set the size for cell no. 0
         }else if indexPath.row == 1 {
               // Set the size for cell no. 1
        }
    }

Надеюсь, это поможет. Спасибо!

person S E    schedule 14.05.2016

Попробуйте использовать метод UICollectionViewDelegateFlowLayout. В Xcode 11 или более поздней версии вам необходимо установить для параметра Estimate Size значение none в Storyboard.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: 
UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
      let padding: CGFloat =  170
      let collectionViewSize = advertCollectionView.frame.size.width - padding
      return CGSize(width: collectionViewSize/2, height: collectionViewSize/2)
}
person Muhammad Shariq Hasnain    schedule 12.03.2020

Если все ваши ячейки имеют одинаковый размер, вы должны просто установить свойства размера ячейки UICollectionView такими же, как свойства размера UICollectionViewCell.

person theDuncs    schedule 24.04.2014

Используйте его делегата по умолчанию. . .

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    CGSize mElementSize;
    mElementSize = CGSizeMake(SCREEN_WIDTH , SCREEN_HEIGHT *0.60);
    return mElementSize;
}   
person Naman Vaishnav    schedule 17.02.2017