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
поэтому проблема с дополнительным интервалом будет решена.