Layout of Images in UICollectionView - ios

I am trying to layout a collection of Magazine covers in a UICollectionView in which the background is a bookshelf. I want it to have 2 magazines per shelf, and the rest to be seen when scrolling down. Here is my code I have:
-(void)viewDidLoad {
UINib *cellNib = [UINib nibWithNibName:#"NibCell" bundle:nil];
[self.collectionView registerNib:cellNib forCellWithReuseIdentifier:#"cvCell"];
self.collectionView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"shelves.png"]];
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
NSLog(#"1");
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [_allEntries count];
NSLog(#"2");
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
static NSString *cellIdentifier = #"cvCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
UIImageView *titleLabel = (UIImageView *)[cell viewWithTag:100];
UILabel *titleLabel2 = (UILabel *)[cell viewWithTag:200];
NSString *thearticleImage = entry.articleImage;
[titleLabel setImageWithURL:[NSURL URLWithString:entry.articleImage] placeholderImage:[UIImage imageNamed:#"icon#2x.png"]];
// [titleLabel2 setText:entry.articleTitle];
return cell;
}
I am using an XIB to create the collectionView cell.
When there are only 2 issues, it looks fine, but as more and more issues get added and you begin to have to scroll, they get quite off:

Your calculation of your UICollectionViewCell with paddings between cells could be kind a wrong. You can either play with size of images or set the size of cell programmatically:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(192.f, 192.f);
}
You can also play with paddings in Interface Builder.
You can also do this programmatically:
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setItemSize:CGSizeMake(100, 200)];
[flowLayout setMinimumInteritemSpacing:10];
[flowLayout setMinimumLineSpacing:10];

Related

black window in simulator -collection view

The code is a simple collection view with a bunch of images
I ran it and Xcode doesn't argue about anything but the simulator shows a black screen after running the app.
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return recipePhotos.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier =#"Cell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
// Configure the cell
UIImageView * recipeImageView = (UIImageView *)[cell viewWithTag:100];
recipeImageView.image=[UIImage imageNamed:[recipePhotos objectAtIndex:indexPath.row]];
return cell;
}
Check collection view datasource outlet, maybe it was not connected with your controller?
Check receipeImageView is not nil.
Did you register your UICollectionViewCell with identifier #"Cell"?
If you don't want black background, you have to set
collectionView.backgroundColor = [UIColor clearColor];
Then you must register the cell
UINib *cellNib = [UINib nibWithNibName:#"yournibname" bundle:nil];
[collectionView registerNib:cellNib forCellWithReuseIdentifier:#"cell"];
Both need to be implemented in viewDidLoad method

collectionview just filling one cell

I'm trying to fill a collectionview with data from an array which I've checked it has the data, but at runtime it's filling just the cell at index 0.
The collectionview is a list of friends in pages of 9 items showing photo and name. The number of items at section is working properly, I mean, if the array has 3 objects, the collectionview displays three cells but just the first one with the photo and name of the object, concretly the last one in the array, not the first one. And the other cells show the prototype cell.
I guess I'm dealing wrong with the indexpath of the collection view, but I have another one in my storyboard and works properly. This other one has only one cell per page, could be something related to this?
I paste my collectionview methods:
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [self.miListaAmigos count];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"friendCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
UILabel *nameLabel = (UILabel *)[self.view viewWithTag:102];
nameLabel.font = [UIFont fontWithName:#"Ubuntu" size:12.0];
nameLabel.text = [[self.miListaAmigos objectAtIndex:indexPath.row] valueForKey:#"usr_username"];
return cell;
}
you not directly reuse UILabel from self.view, UILabel *nameLabel = (UILabel *)[self.view viewWithTag:102];
try this below code for solve your problem:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"friendCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
if(cell == nil)
{
//Create UILabel here
UILabel *nameLabel=[[UILabel alloc]initWithFrame:CGRectMake(5, 5, 310, 20)];
nameLabel.tag=100;
[cell addSubview:nameLabel];
nameLabel.font = [UIFont fontWithName:#"Ubuntu" size:12.0];
}
// Access label and reuse
UILabel *nameLabel = (UILabel *)[cell viewWithTag:100];
nameLabel.text = [[self.miListaAmigos objectAtIndex:indexPath.row] valueForKey:#"usr_username"];
return cell;
}
Check your collectionView alloc and required deleagte:
UICollectionViewDelegate、UICollectionViewDataSource、 UICollectionViewDelegateFlowLayout.
e.g.
UICollectionViewFlowLayout *collectionLayout = [[UICollectionViewFlowLayout alloc] init];
[collectionLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:collectionLayout];
[collectionView registerClass:[CNCollectionViewCell class] forCellWithReuseIdentifier:cellIndetify];
collectionView.delegate = self;
collectionView.dataSource = self;
[self.view addSubview:collectionView];
Your label is in self.view not in the cell... You really should make a subclass of UICollectionViewCell
File -> New -> File -> Cocoa Touch Class
Class: MYFriendCollectionViewCell
Subclass of: UICollectionViewCell
Also Create XIB: Tick
Language: Objective C
Look at MYFriendCollectionViewCell.xib and make your label inside here... connect the labels to an IBOutlet... don't use tags...
#property (weak, nonatomic) IBOutlet UILabel *nameLabel;
https://www.youtube.com/watch?v=GusRijNLUGg <- connecting IBOutlets
Add the line below in your ViewController
[self.collectionView registerNib:[UINib nibWithNibName:#"MYFriendCollectionViewCell" bundle:nil] forCellWithReuseIdentifier: CellIdentifier];
Change your cellForItem to:
static NSString *CellIdentifier = #"friendCell";
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath{
MYFriendCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier: CellIdentifier forIndexPath: indexPath];
cell.nameLabel.font = nameLabel.font = [UIFont fontWithName:#"Ubuntu" size:12.0]; // This ideally would be in MYFriendCollectionViewCell.m
cell.nameLabel.text = [[self.miListaAmigos objectAtIndex:indexPath.row] valueForKey:#"usr_username"];
return cell;
}

Create a gallery using UICollectionView iOS

I wanna create a gallery using uicollectionview above tab bar controller. the problem that i have is i’m getting a SIGABRT crash when i’m connecting uicollectionview datasource. but when i didnt connecting it, the controller view did not show any image. did somebody know what to do?
this is the code I've made :
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
NSLog(#"stiker : %d", stickers1.count);
return stickers1.count;
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"Cell";
NSLog(#"indexpath row : %d", indexPath.row);
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
recipeImageView.image = [UIImage imageNamed:[stickers1 objectAtIndex:indexPath.row]];
// cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"photo-frame.png"]];
return cell;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
NSLog(#"numberOfSectionsInCollectionView coll : %d, stic : %d", collectionView.numberOfSections, stickers1Collection.numberOfSections);
return collectionView.numberOfSections;
}
I've connected the uicollectionview datasource in xib
Set number of items
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
set content
Just add UIImageView and UIlabel and set there tags in storyboard assign data in cellForItemAtIndexPath method
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"Cell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
UIImageView *ImageView = (UIImageView *)[cell viewWithTag:100];
ImageView.image = [UIImage imageNamed:[[arrCategoryValue objectAtIndex:indexPath.row] objectForKey:#"image"]];
UILabel *lbl = (UILabel *)[cell viewWithTag:200];
lbl.text = [[arrCategoryValue objectAtIndex:indexPath.row] objectForKey:#"name"];
cell.tag = indexPath.row;
return cell;
}
for more info you can go here

Cells are hidden using CollectionView

I have a Navigation Controller pushing to a Collection View Controller. This collectionView has an NSArray of images, and I'm sure there are some elements in the collectionView using the method visibleCells.
But when I launch it there is no displaying cells.
Here is my code :
- (void)viewDidLoad
{
[super viewDidLoad];
images = [NSArray arrayWithObjects:#"angry_birds_cake.jpg", #"creme_brelee.jpg", #"egg_benedict.jpg", #"full_breakfast.jpg", #"green_tea.jpg", #"ham_and_cheese_panini.jpg", #"ham_and_egg_sandwich.jpg", #"hamburger.jpg", #"instant_noodle_with_egg.jpg", #"japanese_noodle_with_pork.jpg", #"mushroom_risotto.jpg", #"noodle_with_bbq_pork.jpg", #"starbucks_coffee.jpg", #"thai_shrimp_cake.jpg", #"vegetable_curry.jpg", #"white_chocolate_donut.jpg", nil];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return images.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"Cell";
UICollectionViewCell *cell;
[collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"Cell"];
cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
NSArray *tab = [collectionView visibleCells];
for (int i = 0; i < [tab count]; ++i)
{
NSLog(#"%d", i);
}
[collectionView setBackgroundColor:[UIColor blueColor]];
UIImageView *imageView = (UIImageView *)[cell viewWithTag:100];
imageView.image = [UIImage imageNamed:[images objectAtIndex:indexPath.row]];
return cell;
}
Where am I wrong ? Thanks a lot.

UICollectionView reload data Issue

I have a problem with data reloading using UICollectionView. I have this array on the viewDidLoad to fill the UICollectionView.
array = [[NSMutableArray alloc] init];
[array addObject:#"1"];
[array addObject:#"2"];
[array addObject:#"3"];
[array addObject:#"4"];
[array addObject:#"5"];
[array addObject:#"6"];
and the method:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"Cell";
//cell = [[UICollectionViewCell alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
myCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(5, 0, 100, 20)];
[titleLabel setText:[array objectAtIndex:indexPath.row]];
titleLabel.textColor = [UIColor whiteColor];
titleLabel.backgroundColor = [UIColor clearColor];
[cell addSubview:titleLabel];
return cell;
}
I tap the UIButton and data is reloaded:
[myCollectionView reloadData];
Here how the data looks like before and after the reload:
You add a new label each time you tap the reload button. You should add the label once and change the label text according.
Here a simple example.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = (MyCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"Cell"
forIndexPath:indexPath];
[cell setMyTextLabel:indexPath.row];
return cell;
}
where MyCell will contains a UILabel and a property to modify its text.
I really suggest to take a look at Fun with UICollectionView code by #Ben Scheirman.
Hope that helps.
P.S. Rename myCell to MyCell. A class should start with an uppercase letter.
You are adding your label when you tap reload button. In that case you are adding label again and again...
So there are three solutions:
Make your cell reusable
Remove your cell from superview in reload method.
You can check if label's text length is not equal to zero. In that case no need to add that label and change text.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
dispatch_async(dispatch_get_main_queue(), ^{
// ********* Changed *******
for (UIView *v in [cell.contentView subviews])
[v removeFromSuperview];
// ********** Changed **********
if ([self.collectionviewFlow.indexPathsForVisibleItems containsObject:indexPath]) {
NSString *img_name=[NSString stringWithFormat:#"%#_thumb%d.png",self.VaritiesName,(int)indexPath.row+1];
imageVw=[[UIImageView alloc]initWithImage:[UIImage imageNamed: img_name]];
imageVw.frame=CGRectMake(10,10,100,100);
[cell.contentView addSubview:imageVw];
}
});
cell.backgroundColor=[UIColor clearColor];
return cell;
}
It is quit late, but here is my solution.
if you used custom collectionviewcell
try to use 'func prepareForReuse()'

Resources