I have a UICollectionView inside a scrollview which has cell with dynamic width and static height.
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return tagArray.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
TagsCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"tagsCollectionViewCell" forIndexPath:indexPath ];
[cell bindWithModel:tagArray[indexPath.row]];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGSize yourLabelSize = [tagArray[indexPath.row] sizeWithAttributes:#{NSFontAttributeName : [UIFont systemFontOfSize:17.0f]}];
return CGSizeMake(yourLabelSize.width+20+40, 40);
}
I could calculate height using :
CGFloat height = self.collectionView.collectionViewLayout.collectionViewContentSize.height;
I am getting higher value than actual height.
collectionView:layout:sizeForItemAtIndexPath:
Asks the delegate for the size of the specified item’s cell.
CGFloat height = self.collectionView.collectionViewLayout.collectionViewContentSize.height
This will return the collectionView height not the collectionView Cell's height.
Related
I have a UICollectionViewwith custom height and width but when i launch the app, all those cells which are initially visible to screen are perfectly set with respect to my give Height and Width but when i scroll down it reduce the cell width.
Here are the methods for setting Height and Width, Spacing etc.
- (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.0f;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
[self.collectionView setNeedsLayout];
[self.collectionView layoutIfNeeded];
CGFloat width = self.collectionView.frame.size.width;
return CGSizeMake((width/2)-5, 220);
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return [listOfRetailers_ count];
}
-(void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{
BDRetailerCollectionViewCell *newCell = (BDRetailerCollectionViewCell*)cell;
UIFont *font = newCell.brandName.font;
[newCell.brandName setFont:[font fontWithSize:12]];
[newCell setNeedsLayout];
[newCell layoutIfNeeded];
}
Remove this line from this method
(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
[self.collectionView setNeedsLayout];
[self.collectionView layoutIfNeeded];
I am working on Collectionvew with Paging . I am Successfully able to done collectionview with Paging. and It's work perfectly.
But the problem is i need only 10 cell in 1 page , then another 10 cell 2nd page and Next 10 cell in 3rd page. but I dont know How can i achive it when page changed.And i also want to change the title when page changed like , Easy ,Medium and Hard(Levels).
Currently i take 30 cells in collectionview . Here is my methods for collectionview ,
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section
{
return kNumberOfCells;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"GameCollectionViewCell";
GameCollectionViewCell *cell = (GameCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
if (cell == nil)
{
NSArray *xib = [[NSBundle mainBundle] loadNibNamed:#"HomeCollectionViewCell" owner:self options:nil];
cell = [xib objectAtIndex:0];
}
cell.lblLevel.text=[NSString stringWithFormat:#"%d",indexPath.item+1];
cell.lblLevelPoints.text=#"points";
return cell;
}
#pragma mark – UICollectionViewDelegateFlowLayout
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
float width = collectionView.frame.size.width/6.4;//120
float height = collectionView.frame.size.height/4;//120
return CGSizeMake(width,width);
}
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(8.0, 14.0, 5.0, 14.0);//TOP , LEFT ,BOTTOM ,RIGHT
}
Output Currently i am getting :-
There are two solutions :
Solution 1 :
You can take number of section 3. Each section with 10 items. With each section you have change current page of UIPageControl and change title too.
Solution 2:
Place PageControl in your view or set by Code.
Set UIScrollViewDelegate
In Collectionview-> cellForItemAtIndexPath (Method) add the
below code for calculate the Number of pages,
int pages =floor(ImageCollectionView.contentSize.width/ImageCollectionView.frame.size.width);
[pageControl setNumberOfPages:pages];
Add the ScrollView Delegate method
pragma mark - UIScrollVewDelegate for UIPageControl
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
CGFloat pageWidth = ImageCollectionView.frame.size.width;
float currentPage = ImageCollectionView.contentOffset.x / pageWidth;
if (0.0f != fmodf(currentPage, 1.0f))
{
pageControl.currentPage = currentPage + 1;
}
else
{
pageControl.currentPage = currentPage;
}
NSLog(#"finishPage: %ld", (long)pageControl.currentPage);
}
Reference Link :
Collectionview + Pagecontrol
Update:
There is one sample code also made by me on Github. It help you :
https://github.com/maniyarpayal/PagingWithCollectionView
try this delegate methods,
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake((self.view.frame.size.width / 5) , self.view.frame.size.height / 2);
}
- (NSUInteger)maximumNumberOfColumnsForCollectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout
{
return 5;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
return 0.0;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return 0.0;
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
return UIEdgeInsetsMake(0, 0, 0, 0);
}
i have also same problem, then use the above methods its will working for me, hope its helpful.
you can use this delegate method but you have to customise according to your requirement because i did not mention distance between cells and x-origin .and you have to do minus those distance from view width. hope this will help you.
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake((self.view.frame.size.width / 10) , self.view.frame.size.height / 2);
}
I am use ScrollView . In my scroll view there is Collection View. My collection view last 3 element hide inside white space. On scrolling ScrollView they not show.They Shown on scrolling CollectionView. I want to show shown all Collection Cell On Scroll ScrollView. Not Scrolling CollectionView.
-(NSInteger)numberOfSectionsInCollectionView:
(UICollectionView *)collectionView {
return 1; // The number of sections we want
}
-(NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section {
return 5; // the number of cells we want
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionViewd
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CollectionCell* cell =
[collectionViewd dequeueReusableCellWithReuseIdentifier:#"collectionView2CellIdentifier"
forIndexPath:indexPath]; // Create the cell from the storyboard cell
cell.layer.cornerRadius = 4;
cell.layer.borderWidth = 1;
cell.layer.borderColor = [UIColor grayColor].CGColor;
cell.yellow.layer.cornerRadius=4;
cell.red.layer.cornerRadius=4;
cell.title.text =[titleArray objectAtIndex:indexPath.row];
cell.date.text =[dateArray objectAtIndex:indexPath.row];
cell.incomeText.text =[netIncomeArray objectAtIndex:indexPath.row];
cell.expenseText.text =[netExpenseArray objectAtIndex:indexPath.row];
cell.saving.text =[savingArray objectAtIndex:indexPath.row];
cell.expensePecentageText.text =[expensePercentage objectAtIndex:indexPath.row];
cell.savingPercentage.text =[netProfitPercentage objectAtIndex:indexPath.row];
return cell; // Return the cell
}
- (CGFloat)collectionView:(UICollectionView *) collectionView
layout:(UICollectionViewLayout *) collectionViewLayout
minimumInteritemSpacingForSectionAtIndex:(NSInteger) section {
return 2.0;
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
return UIEdgeInsetsMake(2, 2, 2, 2);
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(155, 158);
}
[scrollView setContentSize:CGSizeMake(0, expenseButton.frame.origin.y+expenseButton.frame.size.height+collection.frame.size.height+16)];
First of all count the height of collectionview By :
For Example
titleArray.count * 160 (158px cell height + 2px cell space)
Then assign this height to collectionview frame
also assign this to scrollview content size height.
This will surely do the trick for you.
In my collection view I want to scale the collection view cell that is selected. Along with that I also want to maintain same interItemSpacing between cells before the selection and after the selection, including enlarged cell. But if I just scale the cell by setting cell.transform property scaled cell overlaps on the neighbor cell.Other cells should adjust themselves to maintain the space. How do I solve this ?
i.e,
cell -50pix- cell -50pix- cell
cell -50pix- scaled cell -50pix- cell
By applying a transform, you are just scaling the view up in size. To adjust the size and allow the rest of the UICollectionView to adjust you will need to return a new size in sizeForItemAtIndexPath:
When the item is selected, you should reload that item at that indexPath using:
[collectionView reloadItemAtIndexPath:selectedIndexPath]
Replace selectedIndexPath with name of your variable storing the selected indexPath.
You don't want to invalidateLayout because you're just changing the appearance of one item.
I don't know whether this is the best solution,
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CollectionViewCell *cell = (CollectionViewCell*)[collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor redColor];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
if ([indexPath isEqual:selectedIndexPath]) {
return CGSizeMake(175, 175); // return enlarged size if selected cell
}
return CGSizeMake(150, 150);
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
selectedIndexPath = indexPath; // set selected indexPath
[collectionView performBatchUpdates:^{
[collectionView.collectionViewLayout invalidateLayout];
} completion:^(BOOL finished) {
}];
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
return UIEdgeInsetsMake(0, 0,0, 0);
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{
return 20;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section{
return 20;
}
I am attempting to lay my UICollectionView out such that it is a 2x3 grid per page. Here is what I am getting so far:
As you can see, the next "page" is peeping in from the right, which I don't want. I figured if I know my width is always going to be 320pts (iPhone only), then I would want my cells to be 130pts in width with 15pts on either side.
Code for layout delegate:
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(130, 130);
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(20.0f, 15.0f, 20.0f, 15.0f);
}
And also cellForItemAtIndexPath:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CustCollectionViewCell *cell =
[collectionView dequeueReusableCellWithReuseIdentifier:kReuseID
forIndexPath:indexPath];
//Set up list name label
cell.LblListName.font = [self getDefaultFontWithSize:15.0f];
cell.LblListName.textColor = fontAndTertiaryColor;
cell.LblListName.textAlignment = NSTextAlignmentCenter;
cell.LblListName.text = #"Failtron";
//cell.LblListName.adjustsFontSizeToFitWidth = YES;
cell.backgroundColor = secondaryColor;
cell.parallaxIntensity = kParallaxMotion;
[Utilities createViewBorder:cell];
return cell;
}
I thought an inset would act like padding in CSS but I believe I'm off the mark with that one, I should also note that in the UIStoryboard my layout is set to flow. Please let me know if I am missing any relevant code, this is my first attempt with a UICollectionView. I would like this to scroll horizontally as well.
Ok, there are tons of ways to manipulate layouts for a UICollectionView, but sounds like since you are using "flow" you can just implement <UICollectionViewDelegateFlowLayout> in your .h and then use the following methods to tweak your layout to your liking:
#pragma mark – UICollectionViewDelegateFlowLayout
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
// Size of the cell
CGSize retval = CGSizeMake(130,130);
return retval;
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
insetForSectionAtIndex:(NSInteger)section {
//top, left, bottom, right
return UIEdgeInsetsMake(0, 20, 0, 20);
}
- (CGFloat)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
//Minimum spacing between cells
CGFloat interimSpacing = 0.0f;
return interimSpacing;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
minimumLineSpacingForSectionAtIndex:(NSInteger)section {
// Minimum spacing between lines. In your case,
this is the distance between columns
// If your scroll direction was vertical,
this would be the distance between rows
CGFloat lineSpacing = 20.0f;
return lineSpacing;
}
I've prepopulated this code with some values that should be pretty darn close to what you wanted to accomplish.
Alternatively, all of this can be done in Interface Builder by selecting the UICollectionView and adjusting the values in the Size Inspector, albeit more confusing in my opinion.