Подвиды ячеек 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 ];