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
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;
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 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;
}
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;
}
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;
}