UICollectionViewCell does not take maximum width - ios

I'm trying to make cells take as much width as possible, but I end up like this:
I have tried to remove margins, line spacing etc. in xcode:
But the horizontal margin is still huge, I want the same vertical margin applied.
Any ideas?
P.S attached example code:
- (void)viewDidLoad {
[super viewDidLoad];
self.collectionView.delegate = self;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 9;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
return cell;
}

You set the Collection cell to be 100x100, and to be 3 at row.
So the UICollectionView is minimum 300/300. If you make the view to be 320(normal iPhone width), then the Collection View set padding between the cells automatically.
EDIT:
Try:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
//3 because you wanted 3 cells. 18 is the min padding between the cell.
cell.frame.size.width = collectionView.frame.size.width/3-18;
return cell;
}

Related

UICollectionView `reloadData` causes UILabel lines to disappear

I have a UILabel in a collectionView header. The label is set to zero lines, word wrapping, and proper leading/trailing/top space constraints. If i DO NOT call [collectionView reloadData], the label expands properly to text with greater than two lines. Once reloadData is called, the label goes back to a single line...the second line disappears.
- (UICollectionReusableView *) collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
if (kind == UICollectionElementKindSectionHeader) {
header = (viewRollHeader *) [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"header" forIndexPath:indexPath];
header.rollTitle.text = [self.roll objectForKey:#"title"];
header.rollDescription.text = [self.roll objectForKey:#"info"];
[header.cancelButton addTarget:self action:#selector(exit) forControlEvents:UIControlEventTouchUpInside];
return header;
}
return [UICollectionReusableView new];
}
- (CGSize) collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{
if (section == 0) {
CGRect labelRect = [[self.roll objectForKey:#"title"]
boundingRectWithSize: header.rollTitle.frame.size
options:NSStringDrawingUsesLineFragmentOrigin
attributes:#{NSFontAttributeName : [UIFont fontWithName:#"Arial-BoldMT" size:32.0f]}
context:nil];
return CGSizeMake([[UIScreen mainScreen]bounds].size.width, (174.0f + labelRect.size.height));
}
return CGSizeZero;
}
collectionView:viewForSupplementaryElementOfKind:atIndexPath: is used for the header or footer of the entire collectionView, while collectionView:referenceSizeForHeaderInSection: is used for the header of a specific section of the collectionView
to make sure the size of the header stays consistent and respects your constraints, you'll need to call [(UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout setHeaderReferenceSize:CGSizeMake(width, height)] once the flowlayout is instantiated
Use label setter property inside delegate method where you configure each cell.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
//add label property here
return cell;
}
After reloading, it calls this method again to configure the label.
Try setting the preferredMaxLayoutWidth to the label
self.label.preferredMaxLayoutWidth = 300;

My CollectionView Cell Hide

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.

Display different cells based on data type in UICollectionView

I have three different types of cells with different content size (containing image, label and button) in UICollectionview. I am getting data from web services. I want to show correct cell based on these types.
Firstly you register nibs of layouts for your cells:
[collectionView registerNib:myCellTypeImageNib forCellWithReuseIdentifier:#"MyModelTypeImageCellIdentifier"];
[collectionView registerNib:myCellTypeLabelNib forCellWithReuseIdentifier:#"MyModelTypeLabelCellIdentifier"];
[collectionView registerNib:myCellTypeButtonNib forCellWithReuseIdentifier:#"MyModelTypeButtonCellIdentifier"];
Then return them appropriately:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MyModel *modelObject = self.dataArray[indexPath.item];
UICollectionViewCell *cell = nil;
switch (modelObject.type) {
case MyModelTypeImage:
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"MyModelTypeImageCellIdentifier" forIndexPath:indexPath];
//adjust cell
break;
case MyModelTypeLabel:
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"MyModelTypeLabelCellIdentifier" forIndexPath:indexPath];
//adjust cell
break;
case MyModelTypeButton:
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"MyModelTypeButtonCellIdentifier" forIndexPath:indexPath];
//adjust cell
break;
}
return cell;
}
You can use
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
Note: indexpath
For example. Add all the images in to an array.
self.myArray = [[NSArray alloc] initWithObjects:#"first.jpg",
#"second.jpg",
#"third.jpg",
#"last.jpg",nil]
Then in cellForRow... do the following:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
// configure cell
...
cell.myImageView = [self.myArray objectAtIndex:indexPath.row;
}

How to avoid UICollectionView repeating cells?

Hello I have a UICollectionView. I load data from a NSMutableArray and it has 4 objects. But my problem is its repeating the same cells again.
`
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return mutArrayArtists.count;
}
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView {
return 2;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"Cell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
artist = [mutArrayArtists objectAtIndex:indexPath.row];
UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
recipeImageView.image = artist.artistImage;
UILabel *lblArtistname=(UILabel *)[cell viewWithTag:102];
lblArtistname.text=artist.artistName;
UILabel *lblSongCount=(UILabel *)[cell viewWithTag:101];
lblSongCount.text=artist.numberofSongs;
return cell;
}
`
But the result is like this
How can I avoid this? Please help me
Thanks
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView {
return 1; //instead of 2
}
The section here does not mean the number of columns. It means that the collection view will contain 2 sections vertically above each others
This is the problem:
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView {
return 2;
}
You have two sections to the collection view, and in your cell provider, you don't distinguish the sections. Change it to say return 1; (assuming you do want just one section in the collection) or update the cellForItemAtIndexPath function (by inspecting indexPath.section) to split the sections out as you intend.
This might be helpful
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}

Reusing cell causes unwanted behaviour when updating cell view

I want ot set a border to a selected cell, i save a cell property that represents the selected one and manipulate it:
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
NSArray *eyeArray = [self eyesArrayConfigure][indexPath.row];
if (indexPath.row==5) {
int r = arc4random() % 6;
eyeArray = [self eyesArrayConfigure][r];
}
[borderedCell.contentView.layer setBorderWidth:0.0f] ;
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
borderedCell = cell;
[borderedCell.contentView.layer setBorderColor:self.view.tintColor.CGColor];
[borderedCell.contentView.layer setBorderWidth:3.0f];
}
and the cellForView: (Im usinng 2 types of cell identifiers because one cell contains a label - "Random cell":
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row ==5) {
UICollectionViewCell *randomCell =[collectionView
dequeueReusableCellWithReuseIdentifier:#"randomCell"
forIndexPath:indexPath];
randomCell.backgroundColor = [UIColor purpleColor];
borderedCell = randomCell;
[borderedCell.contentView.layer setBorderColor:self.view.tintColor.CGColor];
[borderedCell.contentView.layer setBorderWidth:3.0f];
return randomCell;
}
UICollectionViewCell *myCell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
NSArray *eyeArray = [self eyesArrayConfigure][indexPath.row];
myCell.backgroundView = [[UIImageView alloc] initWithImage:eyeArray[1]];
return myCell;
}
What i get is if a click one cell it will be fine till i scroll and then i get weird behaviour when couple of cells might be with the border.
Thanks for the help.
The solution is to use a view model. You are already doing this for your cells' background views. Apply the same concept for the border.
#interface MyCollectionView ()
#property (nonatomic) NSInteger selectedRow;
#end
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
//update self.selectedRow and either reload entire collection view or just the currently selected and previously selected.
self.selectedRow = indexPath.row;
[collectionView reloadData];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *myCell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
CGFloat borderWidth = (indexPath.row == self.selectedRow) ? 3.0 : 0.0;
[myCell.contentView.layer setBorderWidth:borderWidth];
return myCell;
}

Resources