I had an application in which I am taking the width of the collection view cell as:
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(20, 20,20,20);
}
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGRect screenRect = collection.frame;
CGFloat screenWidth = screenRect.size.width;
float cellWidth = screenWidth / count;
}
But now I want on that count the width of the cell needs to be dependent on one parameter, like:
NSDictionary *dict=[arr objectAtIndex:indexPath.item];
float duration=([[dict valueForKey:#"duration"]floatValue]);
If duration is 45 then it needs to take 45% of the screen width and like that. Can anybody help me on This when i am trying screenWidth * (duration/100.0) it is looking like this
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGRect screenRect = collection.frame;
CGFloat screenWidth = screenRect.size.width;
NSDictionary *dict=[arr objectAtIndex:indexPath.item];
float duration=([[dict valueForKey:#"duration"]floatValue]);
float cellWidth = duration / 100;
return CGSize(cellWidth, 60);
}
It helps you.
If You collectionview just consist of this cells, then i would recommend you to go with section approach.
multiple section for each item , and each section has only one row . By this approach there will be only one row in section and as you wanted even if row size is 10% or less.
keep size approach like below.
NSDictionary *dict=[arr objectAtIndex:indexPath.item];
float duration=([[dict valueForKey:#"duration"]floatValue]);
float cellWidth = screenWidth * (duration/100.0);
Related
I'm trying to create a UICollectionView with 3 images per row.
For the start i used this code:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(110, 110);
}
And it's looking good but it only fits the iPhone X screen:
Then i tried to use this code so it will put 3 cells per row:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
float cellWidth = screenWidth / 3.0;
CGSize size = CGSizeMake(cellWidth, cellWidth);
return size;
}
But then the view is starting looking different:
This is the cell initialize method:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"TrendingCell";
TrendingCell *cell = (TrendingCell*)[collection dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
TrendingItem * item = [[[TrendingRep sharedTrending] trendingArray] objectAtIndex:indexPath.row];
cell.text.text = item.title;
cell.image.layer.cornerRadius = cell.image.frame.size.width / 2;
cell.image.clipsToBounds = YES;
[cell.image sd_setImageWithURL:[NSURL URLWithString:item.imageUrl]
placeholderImage:nil
options:SDWebImageProgressiveDownload
completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
[cell.progressView setHidden:NO];
}];
return cell;
}
Any idea what can be the issue with the view?
This looks like you're not taking into account the layout's minimumInteritemSpacing. The formula to calculate the item's width should be
float cellWidth = (screenWidth - 2.0 * minimumInteritemSpacing) / 3.0;
You have to provide minimum spacing between the collection View cell. You
are using collectionviewLayout, So you have to provide minimum spacing like below.
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(collectionView.frame.size.width/3 - 10, collectionView.frame.size.width/3)
}
Here You can provide minimum spacing (like 10) between cells programmatically.
I have an issue with UICollectionViewCell design layout. I need to remove space with animation while scrolling between UICollectionView Cell, I have try some delegate method of UICollectionView like -
CollectionView - minimumLineSpacingForSectionAtIndex
CollectionView - minimumInteritemSpacingForSectionAtIndex
UIEdgeInsetsMake(0,0,0,0);
scrollViewDidEndDragging
but unable to up to the mark. here is the code:
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
float cellWidth = screenWidth / 2.1; //Replace the divisor with the column count requirement. Make sure to have it in float.
CGSize size = CGSizeMake(cellWidth, cellWidth);
return size;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
return 1.0;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return 1.0;
}
// Layout: Set Edges
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
return UIEdgeInsetsMake(0,0,0,0); // top, left, bottom, right
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
UIEdgeInsetsMake(0,0,0,0); // after scroll cell space not remove.
}
I didn't completely understand what you're trying to do, but if you want to change layout attributes of a collection view and animate the change, the best way is calling setLayout:animated:.
So like this -
UICollectionViewFlowLayout *layout = [UICollectionViewFlowLayout alloc] init];
layout.minimumLineSpacing = 1.0;
layout.minimumInteritemSpacing = 1.0;
layout.itemSize = CGSizeMake(cellWidth, cellHeight);
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:frame collectionViewLayout:layout]
And then whenever you want to change it, just call the setLayout:animated: method:
UICollectionViewFlowLayout *layout = [UICollectionViewFlowLayout alloc] init];
initialLayout.minimumLineSpacing = 5.0;
initialLayout.minimumInteritemSpacing = 7.0;
layout.itemSize = CGSizeMake(newCellWidth, newCellHeight);
[collectionView setLayout:layout animated:YES];
I want to get rid of one pixel issue on my device.I am designing a calendar which looks like below
I am using a UICollectionViewCell for this purpose
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(0,0,0,0); // top, left, bottom, right
}
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat collectionViewWidth = (CGRectGetWidth(collectionView.frame) / 7);
CGFloat collectionViewHeight = 48;
return CGSizeMake(collectionViewWidth, collectionViewHeight);
}
The problem is that if I increase width even by 0.0000001 point then the number of cells draw per line is 6 instead of 7. I have tried increasing the UIEdgeInset (by 0.00001) as well but it's the same issue. The properties for flow layout are set appropriately.
layout.minimumInteritemSpacing = 0.0f;
layout.minimumLineSpacing = 0.0f;
How do I make cell size consistent without leaving the gap ? The actual width of the cell is 53.571428571428569 (375/7). If I round the value to 53.58 then I get the below view
This is a very popular problem, the fastest way to resolve it use collectionViewWidth % 7 == 0 for cell size
For example your collectionViewWidth == 320. Cell == 320/7 == 45.7142857, U simply should use collectionViewWidth == 322, and your problem are resolved, because cell == 46
That the increase wasn't noticeable collectionViewWidth U have two option
First, if you collectionViewWidth == screenWidth, simply align to the center and edges will hide out of screen limits
Second if you collectionViewWidth < screenWidth, use UIview to container for collectionView, and use clipTobounds, edges will hide out of container limits.
To get rid of one pixel try using these delegate methods of UICollectionView:
- (CGFloat)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
return -0.5;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return -0.5;
}
or, alternatively:
layout.minimumInteritemSpacing = -0.5;
layout.minimumLineSpacing = -0.5;
It may happen that you would have to set one of these to 0.0, while the other to -0.5. Try playing with it.
I am trying to create 10 cells in the collection view(same size as the screen). When I run my app in iphone5s simulator, the view contains exactly 5 cells. But when I switch to iphone6p simulator, the view contains more than 5 cells. How should I adjust the cell size so that the number of cells in screen are consistent across different screen sizes?
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
int numberOfCellInRow = 3;
CGFloat cellWidth = [[UIScreen mainScreen] bounds].size.width/numberOfCellInRow;
return CGSizeMake(cellWidth, cellWidth);
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
return CGSizeMake([(NSString*)[[tagArray objectAtIndex:indexPath.row] objectForKey:#"tag"] sizeWithAttributes:NULL].width+10, 40);
}
I'm trying to adjust the cell heights to fit the UIImages, the problem is it does not seem like the UIImage is filling the collectionView cell. As you can see on this
Image: http://oi61.tinypic.com/98d3zd.jpg
It seems like the cell adjusted, but the image is not filled correctly to fill the cell?
cellheights
First I've created a loop which calculate the new height if the cellWidth is 140, which is the case allways.
for (int i = 0; i < [homesDic count]; i++) {
UIImage *originalImage = [[homesDic objectAtIndex:i] objectForKey:#"image"];
CGFloat originalHeight = originalImage.size.height;
CGFloat originalWidth = originalImage.size.width;
CGFloat wantedWidth = 140;
float wantedHeight = (originalHeight*wantedWidth)/originalWidth;
[_cellHeights addObject:#(wantedHeight)];
}
Then I insert a imageView in to the collectionView cell and set the frame and set cell height equal to the imageheight from the cellHeights array.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
FRGWaterfallCollectionViewCell *waterfallCell = [collectionView dequeueReusableCellWithReuseIdentifier:WaterfallCellIdentifier indexPath];
waterfallCell.lblTitle.text = [NSString stringWithFormat: #"Item %d", indexPath.item];
waterfallCell.bottomView.backgroundColor = [UIColor colorWithRed:0.184 green:0.192 blue:0.196 alpha:0.7];
waterfallCell.homeImage.image = [[homesDic objectAtIndex:indexPath.item] objectForKey:#"image"];
waterfallCell.homeImage.frame = CGRectMake(0, 0, [self.cellHeights[indexPath.item] floatValue], waterfallCell.frame.size.width);
return waterfallCell;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView
layout:(FRGWaterfallCollectionViewLayout *)collectionViewLayout
heightForItemAtIndexPath:(NSIndexPath *)indexPath {
return [[self.cellHeights objectAtIndex:indexPath.item] floatValue];
}
To set up cell size you should use collectionView:layout:sizeForItemAtIndexPath method, try this:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
// Get reference to your image base on indexPath here (I assume you have one section and indexPath.row refer to right image) adjust if needed:
UIImage *originalImage = [[homesDic objectAtIndex: indexPath.row] objectForKey:#"image"];
CGSize imgSize = originalImage.size;
//Adjust if needed
imgSize.height += 20;
imgSize.width += 20;
return imgSize;
}
if you need spacing between the cells, headers, and footers, use this method:
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(20, 10, 20, 10);
}
Hope this is what you are looking for