Подвиды ячеек UICollectionView не меняют размер

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

В настоящее время ячейка инициализируется из кончика, содержащего ячейку с изображением; перо ячейки связано с обычаем UICollectionViewCell подкласс, который только делает init. Авторазмер подпредставлений проверен.

CollectionView сказано изменить размер ячейки значением, полученным и возвращенным в sizeForItemAtIndexPath:, Я подкласс FlowLayout, но он только указывает ScrollDirection а также Insets,

Все это работает нормально. Проблема: Как мне добавить подпредставление / слой в ячейку, чтобы она также правильно меняла размеры? Я попытался добавить подпредставления и слои с translatesAutoresizingMaskIntoConstraints выключено, но они не изменяют размер автоматически. Также попытался использовать кодовую рамку / представление вместо пера.

Лучшее, что я получил сейчас, это cell.contentView.layer подслой, который я добавляю в cellForItemAtIndexPath:; "вручную" изменен размер путем сохранения ячейки frame.size от sizeForItemAtIndexPath:, который не только уродлив, но и заканчивается подслоя, имеющего различные размеры для разных ячеек.

Любая помощь приветствуется!

10 ответов

Решение

Решение состояло в том, чтобы отключить AutoConstraints для xib ячейки и активировать гибкие стрелки ширины / высоты в AutoResize для изображений.

Я столкнулся с той же проблемой только сейчас.

При использовании метода UICollectionViewFlowLayoutDelegate для установки размера ячейки в зависимости от устройства и ориентации устройства размер будет рассчитываться правильно, но подпредставления не будут изменять размер, чтобы заполнить ячейку нового размера. В результате получилась большая пустая ячейка с небольшими подпредставлениями, которые не заполняют границы ячейки / сохраняют размер, равный их текущему значению в файле xib.

Я решил это, сделав следующее в awakeFromNib:

- (void)awakeFromNib
{
    [super awakeFromNib];

    self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    self.contentView.translatesAutoresizingMaskIntoConstraints = YES;
}

До этого маска contentView была nil,

*override func awakeFromNib() {
    super.awakeFromNib()

    self.contentView.autoresizingMask.insert(.FlexibleHeight)
    self.contentView.autoresizingMask.insert(.FlexibleWidth)
}

Это сработало для меня.. Этот код находится внутри вашего подкласса файла UICollectionViewCell.swift (где находится ваш код с пользовательской ячейкой)

Быстрое решение *

В качестве альтернативы включению AutoResizingMask для пользовательских UICollectionViewLayouts, которые имеют переменную высоту, например, где вы устанавливаете некоторые ограничения вручную и нуждаетесь в translatesAutoresizingMaskIntoConstraints, чтобы оставаться НЕТ, вы можете добавить следующее к layoutSubviews в ячейке:

self.contentView.frame = self.bounds;

Это работало, чтобы исправить все мои пользовательские макеты представления коллекции, которые имели проблемы с Xcode 6.

В другом проекте без XIBS я подклассифицировал UICollectionViewCell и сделал это для того же эффекта:

#import "CVcell.h"

@implementation CVcell

@synthesize cellImage;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {

        CGFloat cellSize = self.contentView.bounds.size.width;
        cellImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, cellSize, cellSize)];
        [cellImage setClipsToBounds:YES];

        cellImage.translatesAutoresizingMaskIntoConstraints = NO;
        cellImage.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
        [self.contentView addSubview:cellImage];

    }
    return self;
}

@end

Простое решение автоматической компоновки - установить ограничения для представления контейнера.

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

Автоматические ограничения макета для изменения размера с родительским представлением

Я всегда предпочитаю autolayout, когда это возможно. Но иногда использование фреймов и границ просто экономит время, когда представление определяется непосредственно только его суперпредставлением.

В случае UICollectionViewCell я установил изображение в качестве рамки ячеек + self.imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

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

Поэтому я перешел к работе с границами ячеек и - у вас все получилось нормально.

Так, может, попробовать?

Согласно этой статье, решение @Alfie Hanssen ( здесь) не работает для меня должным образом:

Размер представления ячеек в XIB составляет 50 x 50 точек, что является размером по умолчанию для ячеек представления сбора, установленным в макете потока. Даже если в Интерфейсном Разработчике работать с такой маленькой ячейкой довольно сложно, лучше не менять размер по умолчанию. Проблема в том, что Auto Layout считает установленный вручную размер фиксированным и генерирует ошибку NSAutoresizingMaskLayoutConstraint, когда пытается автоматически настроить высоту ячеек

Я проверил UICollectionViewCell и обнаружил, что между ячейкой и contentView существует представление, которое имеет внутренние ограничения ширины и высоты. Вместо AutoresizingMask я просто обновляюсь, как показано ниже, и, кажется, работает для меня.

override func layoutSubviews() {
    contentView.superview?.frame = bounds
    super.layoutSubviews()
}

Я добавляю subView и ограничение программно, у меня работает следующий код:

lazy var imageView: UIImageView = { [unowned self] in
    let imageView = UIImageView(frame: self.contentView.frame)
    imageView.contentMode = .scaleAspectFill
    imageView.clipsToBounds = true

    return imageView
}() 

func updateCellWith(image: UIImage) {

    contentView.subviews.forEach { $0.removeFromSuperview() }

    contentView.addSubview(imageView)
    imageView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0).isActive = true
    imageView.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 0).isActive = true
    imageView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: 0).isActive = true
    imageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0).isActive = true

    self.imageView.autoresizingMask.insert(.flexibleHeight)
    self.imageView.autoresizingMask.insert(.flexibleWidth)

    imageView.image = image

}

У меня такая же проблема. Переключение между двумя макетами не изменило размеры изображений (UIImage) внутри моих ячеек. Мои Клетки, где строят без XIB. И я использовал два разных класса ячеек для каждого CollectionViewCustomLayout.

Я исправил это программно с этим:

self.autoresizesSubviews = YES;

в моих подклассах UICollectionViewCell.

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

cell.backgroundView[[UIImageView alloc] initWithImage: SumDummyImage ];
Другие вопросы по тегам