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;
}
Related
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.
I've a strange behavior with UICollectionView.
In Figure 1 is shown the correct behavior when the user scroll up the collection: the items goes under header view.
[FIGURE 1]
When I reload Items after a search, some items goes over header during scroll.
I've no idea about the cause...
Any ideas or suggestions?
Thanks.
EDIT
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
return CGSizeMake(CGRectGetWidth([UIScreen mainScreen].bounds), CGRectGetWidth([UIScreen mainScreen].bounds) * 0.612f);
}
What worked for me is to call reloadData() instead of trying to reload with animation (reloadSections()).
In my case, I had a show/hide button to toggle the number of rows in section between item count and 0 (expand the content of the section).
When I replaced
collectionView?.reloadSections([section])
with
collectionView?.reloadData()
I no longer had the issue.
My working code for UICollectionView along with HeaderView inside UIViewController:
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 20;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor blueColor];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(100, 100);
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
UICollectionReusableView *view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"header" forIndexPath:indexPath];
return view;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
return CGSizeMake(self.view.frame.size.width, 100);
}
Storyboard:
Output:
Please check this. Hope this will help you in some other way.
You can try to set sectionHeadersPinToVisibleBounds = true property on your UICollectionViewFlowLayout. Because every UICollectionView has own layout.
Apple doc
A Boolean value indicating whether headers pin to the top of the collection view bounds during scrolling.
Maybe it will help. Add this code into viewDidLoad.
(self.yourCollectionView.collectionViewLayout as! UICollectionViewFlowLayout).sectionHeadersPinToVisibleBounds = true
After trying many solutions in my case that works,
collectionView.clipsToBounds = true
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.
I would like to have a UICollectionView that, in the first row there is a cell with all the row's width, and the second row has 3 cells.
I have researched the documentation but I'm not able to do it. Something like this:
Thanks in advance
Make 2 Cell prototypes in collection view in your storyboard, and set them reuse identifiers
In your ViewController's .m file implement this functions
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 6;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell;
if (/*condition for small cell*/)// e.g. indexPath.row % 3 != 0
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"smallCell" forIndexPath:indexPath];
else
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"bigCell" forIndexPath:indexPath];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
if (/*condition for small cell*/) // e.g. indexPath.row % 3 != 0
return CGSizeMake(65, 50);
return CGSizeMake(318, 50);
}
After doing this you will have something like this:
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.