I have a problem with iOS UICollectionView.
I have a UICollectionView with a layout:
UICollectionViewFlowLayout *collectionViewFlowLayout = [[UICollectionViewFlowLayout alloc] init];
collectionViewFlowLayout.itemSize = CGSizeMake(COLLECTION_VIEW_CELL_WIDTH, COLLECTION_VIEW_CELL_HEIGHT);
collectionViewFlowLayout.minimumLineSpacing = 3.0f;
My UICollectionView frame is frame = (0 ,45, 769,307);
Also, I have a custom UICollectionViewCell with frame frame = (0 ,0, 190, 100)
190 * 4 = 760. That means, that 4 cells should fit into my collection view width. But there is only 3 of them...
Where is my problem?
you can try this delegate
#pragma mark collection view cell paddings
- (UIEdgeInsets)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(0, 0, 0, 0); // top, left, bottom, right
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 0.0;
}
Related
I'm creating Grid View with UICollectionView and want to scroll it by paging.
Now I have a problem. The offset of grid gradually shift by paging scroll.
I want to fit the left top of next page cell to that of screen.
My code is like below,
ViewController.m
- (void)loadView
{
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
self.view = [[GridView alloc] initWithLayout:layout];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBarHidden = YES;
}
- (BOOL)prefersStatusBarHidden
{
return YES;
}
GridView.m
#define GRID_SPACE (20)
- (id)initWithLayout:(UICollectionViewFlowLayout *)layout
{
self = [super initWithFrame:CGRectZero collectionViewLayout:layout];
if (self) {
self.pagingEnabled = YES;
self.backgroundColor = UIColor.redColor;
self.delegate = self;
self.dataSource = self;
[self registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:NSStringFromClass([UICollectionViewCell class])];
}
return self;
}
#pragma mark -
#pragma mark UICollectionViewDelegate
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGSize selfSize = self.frame.size;
return CGSizeMake( (selfSize.width - GRID_SPACE) / 2, (selfSize.height - GRID_SPACE) / 2 );
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return GRID_SPACE;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
return GRID_SPACE;
}
I'd appreciate if you would provide me a good solution.
Thank you.
The page size of an UIScrollView (which UICollectionView inherits from) is the size of it's viewport, so to make it work you need to include the height of the red border at the top. If you don't want to show the border at top or bottom, then you can let the UICollectionView stretch under another element or under the top of the display if it is aligned at the top.
LGP's answer resolved my problem. Resolved code I added to my GridView.m is below,
Add the length of grid item to the height of CollectionView, because the theight is the length of Paging Scroll.
And more, you need to set the length of grid item as bottom of CollectionView insets.
In GridView.m
- (void)layoutSubviews
{
[super layoutSubviews];
CGSize parentSize = self.superview.frame.size;
self.frame = CGRectMake(0, 0, parentSize.width, parentSize.height + GRID_SPACE);
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
return UIEdgeInsetsMake(0, 0, GRID_SPACE, 0);
}
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'm working with a UICollectionView where I have to set a small gap between the margin and the cell of UICollectionView. I tried adjusting the inset of the flow layout like this but I couldn't get what I wanted.
let flow = resturantCollection.collectionViewLayout as! UICollectionViewFlowLayout
flow.sectionInset = UIEdgeInsetsMake(0, 10, 0, 10)
Please look at the image to get an idea of what I'm trying to do.
I'm trying to set a small gap between the cell and the margin. Is there anyway to do this?
Here is the code
//-----------------------------------------------------------------------
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake((self.view.frame.size.width - 40) / 3 , (self.view.frame.size.width - 40) / 3);
}
//-----------------------------------------------------------------------
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(10, 10, 10, 10);
}
//-----------------------------------------------------------------------
Here what i want is need 4 Cell to be displayed in Every screen with 10px space all sides
(self.view.frame.size.width - 40) / 3 -> 4 Cells
I'm currently working on autosizing cells which are new in iOS8.
According to WWDC 2014 video 'What's New in Table and Collection Views', all that is required to autosize cells is to set an estimatedSize on the UICollectionViewFlowLayout given to the UICollectionView on initialisation, and override the sizeThatFits: method in the UICollectionViewCell.
Initialisation:
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setEstimatedItemSize:CGSizeMake(146.0f, 156.0f)];
_collectionView = [[UICollectionView alloc] initWithFrame:[_containerView bounds] collectionViewLayout:flowLayout];
sizeThatFits method in my cell, where _userLabel is the label that is on the bottom and marks the actual height.
- (CGSize)sizeThatFits:(CGSize)size
{
CGSize actualSize = CGSizeMake([[self contentView] bounds].size.width, [_userLabel frame].origin.x + [_userLabel bounds].size.height);
return actualSize;
}
It turns out that actual size has larger height than my estimated size, which should be okay and the cell actually gets resized properly in height.
Now with the iPhone6 and 6+, the width can also differ. I want the cells to properly span the width of the screen. I've therefore implemented three delegate methods on UICollectionViewFlowLayout; my first intuition is to calculate the width I want the cells to have according to the screen width, the section insets and the inter-item spacing.
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
UIEdgeInsets sectionInsets = [self collectionView:collectionView layout:collectionViewLayout insetForSectionAtIndex:[indexPath section]];
CGFloat interItemSpacing = [(UICollectionViewFlowLayout *) collectionViewLayout minimumInteritemSpacing];
CGFloat cellWidth = ([_collectionView bounds].size.width - sectionInsets.left - sectionInsets.right - interItemSpacing) / 2;
CGSize collectionViewCellSize = CGSizeMake(cellWidth, 156.0f);
return collectionViewCellSize;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return 12.0f;
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
return UIEdgeInsetsMake(10.0f, 10.0f, 10.0f, 10.0f);
}
It works, however partly. The collectionView won't respect the top section inset, and when scrolling the collectionView, switching out another tab and then back again, cells seem to have disappeared.
Apparently I'm doing something wrong, but I can't seem to figure out where. Anyone got a clue?
I have implemeted this method
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
return UIEdgeInsetsMake(0, 0, 0, 0);
}
So the method invokes in any case because if I change for example with UIEdgeInsetsMake(0, 0, 100, 0) I can see 100 pt padding on the top of each section. But if I set zero value there is still approximately 10 pt between lines.
Set that in your flow layout
UICollectionViewFlowLayout * flow = [[UICollectionViewFlowLayout alloc]init];
flow.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
flow.scrollDirection = UICollectionViewScrollDirectionVertical;
flow.minimumInterItemSpacing = 0; // space between cells in row
flow.minimumLineSpacing = 0; // space between rows
yourCollectionView = [[UICollectionView alloc]initWithFrame:someFrame collectionViewLayout:flow];
Or Delegate Method:
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 0;
// space between cells on different lines
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 0;
// space beetween cells in same row
}