I got a UICollectionView, my setup:
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
if (collectionView == self.navigationCollectionView)
return 24;
else
return 0;
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
if (collectionView == self.navigationCollectionView)
return UIEdgeInsetsMake(14.5, 15, 0, 15);
else // chart collection
return UIEdgeInsetsMake(0, 0, 0, 0);
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
if (collectionView == self.navigationCollectionView) {
DashboardModel *dashModel = [self getDashBoardCacheAtIndex:indexPath.row];
UILabel *label = [[UILabel alloc] init];
label.text = dashModel.dashboardTitle;
label.font = [UIFont boldSystemFontOfSize:17];
[label sizeToFit];
return CGSizeMake(label.bounds.size.width,self.navigationCollectionView.bounds.size.height);
}
}
But when running, it shows like this:
First cell frame is (39,0,85,44)
Second cell frame is (148,14.5,50,44)
The first cell's top inset is not correctly set. What's wrong with it?
EDIT:
I feel the cell is auto-centered by UICollectionView. Can we set not to auto-center?
Related
I set my UICollectionView's delegate methods:
#pragma mark - collectionView delegate
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
//CGPoint point = self.collectionView.frame.origin;
//CGRect rect = CGRectMake(point.x, point.y, self.collectionView.bounds.size.width, 70*2);
// height
/*_heightOfCollectionView.constant = kHeight_Collection_Cell * 6;
_heightOfContents.constant = collectionView.frame.origin.y + 230 + _heightOfCollectionView.constant;*/
return 12;//_recommendDataArr.count;
}
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewFlowLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
float width = (self.view.bounds.size.width / 2);
float height = 89; // 89
return CGSizeMake(width, height);
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return 0;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
HomeGMCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"HomeGMCell" forIndexPath:indexPath];
if (cell == nil) {
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"HomeGMCell" forIndexPath:indexPath];
}
return cell;
}
The minimumLineSpacingForSectionAtIndex is 0:
And you see I return the Cell's size's width is:
(self.view.bounds.size.width / 2) // attention: no matter is `(self.view.bounds.size.width / 2) - ?(?=1,2,3,4)` it all get the below issue:
But I get the result:
It did not flow to the 2 cols. it flows to one flow.
But if I set the Cell's size's width (self.view.bounds.size.width / 2) - 5 in the sizeForItemAtIndexPath method, I will get the below effect:
It shows two cols, it my requirement, but however there comes an other issue is, the right has a 10px's space.
How to avoid this issue in UICollectionView?
Add this method for padding .
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
return CGSizeMake(SCREEN_WIDTH/2 -5, 89);
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
return UIEdgeInsetsMake(0, 0, 0, 0);
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section{
return 10.0f;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return 10.0f;
}
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've an array of UIColor's in my data source, what I'm trying to do is to fit all cells' size so they can all be seen on screen without scrolling.
I don't know how to do it, so far I've:
#pragma mark <UICollectionViewDataSource>
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.dataSource.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
// Configure the cell
UIColor *cellColor = (UIColor *)self.dataSource[indexPath.row];
cell.backgroundColor = cellColor;
for (UIView *view in cell.contentView.subviews) {
if ([view isKindOfClass:[UIImageView class]]) {
if ([[(UIImageView *)view image] isEqual:[UIImage imageNamed:#"V_BG.png"]]) {
[view removeFromSuperview];
}
}
}
if ([cellColor isEqual:self.existingColor]) {
UIImageView *img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"V_BG.png"]];
img.frame = CGRectMake(0, 0, 30, 30);
img.center = cell.contentView.center;
img.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview:img];
}
return cell;
}
#pragma mark <UICollectionViewDelegate>
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
[[NSNotificationCenter defaultCenter] postNotificationName:UIColorDidChangeNotification
object:[NSString stringWithFormat:#"%ld", (long)indexPath.row]];
[self.navigationController popViewControllerRetro];
}
#pragma mark Collection view layout things
// Layout: Set cell size
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat fixSize = ([UIScreen mainScreen].bounds.size.width / 3) - 2;
return CGSizeMake(fixSize, fixSize);
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{
return 2;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return 2;
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
return UIEdgeInsetsMake(0, 0, 0, 0);
}
I want to create 3 cells in each row, with width & height 104.0f each. But I am getting the output as shown in the screenshot.
The code used is given below. Since I am new to UICollectionView, I have no idea how to implement this. Where do I design the cells incase if frames are different for all?
- (void)viewDidLoad
{
....
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
dealListCollectionView=[[UICollectionView alloc] initWithFrame:CGRectMake(1.0f, 1.0f, 320.0f, 525.0f) collectionViewLayout:layout];
[dealListCollectionView setDataSource:self];
[dealListCollectionView setDelegate:self];
[dealListCollectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"cellIdentifier"];
[dealListCollectionView setBackgroundColor:[UIColor lightGrayColor]];
[self.view addSubview:dealListCollectionView];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 10;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
cell.backgroundColor=[UIColor greenColor];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(104, 104);
}
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(0, 0, 0, 0);
}
- (UIEdgeInsets)insetsForItemAtIndexPath:(NSIndexPath *)indexPath {
return UIEdgeInsetsMake(2, 2, 2, 2);
}
Click on your CollectionView, Go to the Size Inspector and change the default value of Min Spacing For Cells and For Rows. For your size 104x104 it have to be 4px.
The below code solved my problem :
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 2.0;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 2.0;
}