I am able to load the collection view but unable to load the cell.below is my code I'm using.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"reuseCell";
[self.view_dashboard registerClass:[UICollectionViewCell class]
forCellWithReuseIdentifier:#"reuseCell"];
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
recipeImageView = (UIImageView *)[cell viewWithTag:100];
recipeImageView.image= [UIImage imageNamed:[dashBoard_img objectAtIndex:indexPath.row]];
return cell;
}
There doesn't seem to be anything particularly wrong with your code.
Loading a cell in a collection view requires more work than just this single method.
I would start explaining further, but I would just be reading the docs to you. Instead, have a read of the Apple Documentation for yourself.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionView_class/index.html#//apple_ref/doc/uid/TP40012177-CH1-SW4
Related
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
I am in the process of creating an App to take care of Maintenance Planning for Harley Davidson enthusiasts.
The planned target is the iPad series at this point.
I wish do display a grid that shows detail for each fuel purchase. The following graphic hopefully shows what I am trying to achieve.
To get this, I’m using the UICollectionView as I don’t think there is another View that gives me what I am after.
The code below illustrates how I have done this – but I believe it’s a pretty chunky way of doing it:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
FuelCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor lightTextColor];
cell.cellLabel.text = [NSString stringWithFormat:#" %# %# %# %#",self.fuelDetailsForSelectedBike[indexPath.row][0],self.fuelDetailsForSelectedBike[indexPath.row][1],self.fuelDetailsForSelectedBike[indexPath.row][2],self.fuelDetailsForSelectedBike[indexPath.row][3]];
return cell;
}
What I would prefer is have a cell for each piece of information but unsure how I would achieve this using the UICollectionView.
You already have created a custom cell FuelCollectionViewCell which is a good starting point.
Probably you have a prototype cell in your Storyboard with subclass FuelCollectionViewCell right?
In this cell, add 4 UILabel aligned in one row as your design and 'link' them to your subclass .h file with a simple drag+alt (as you've done with cellLabel).
And update your cellForItemAtIndexPath method with something like:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
FuelCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor lightTextColor];
cell.dateLabel.text = self.fuelDetailsForSelectedBike[indexPath.row][0];
cell.litresLabel.text = self.fuelDetailsForSelectedBike[indexPath.row][1];
cell.distanceLabel.text = self.fuelDetailsForSelectedBike[indexPath.row][2];
cell.costLabel.text = self.fuelDetailsForSelectedBike[indexPath.row][3];
return cell;
}
I've got an issue with my UICollectionView where my cells are always initiated blank/in a default state with no data.
The data only appears in the cells after scrolling them in and out of view.
Code:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"EquipmentCell";
APInventoryCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
if (!cell) cell = [[APInventoryCollectionViewCell alloc] init];
//set cell data...
cell.label.text = [arrayOfStrings objectAtIndex:indexPath.row];
return cell;
}
Your problem is that you probably set the arrayOfStrings somewhere in the viewDidLoad method of your view controller, the problem with that is that the collectionview datasource calls are done before that.
What you should do in your viewDidLoad method just call [collectionview reloadData]; an you will be fine
I have an UICollectionView with images, now I want to add a sticker to all images from 5th image to the end. I use the following code, and It works, but when I scroll down to the end, then scroll it back, all stickers appears on ALL IMAGES.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"Cell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
recipeImageView.layer.borderWidth = 0.3;
recipeImageView.layer.borderColor = [UIColor blackColor].CGColor;
recipeImageView.image = [UIImage imageNamed:[wallPack objectAtIndex:indexPath.row]];
// add Paid stickers
NSString *stickName = [NSString stringWithFormat:#"stickerImage.png"]; /// image name
UIImage *stickImage = [UIImage imageNamed:stickName];
stickView = [[UIImageView alloc] initWithImage:stickImage];
stickView.contentMode = UIViewContentModeScaleAspectFit;
if (indexPath.row >= 5) {
[recipeImageView addSubview:stickView];
}
return cell;
}
where is the problem? why before scrolling down everything appears as I want, from 5th to the end, but when I scroll it back, the sticker image puts on ALL images.
The cells are reused. You must add the sticker to the ones you want to add it to if it is not there, but also remove it from the ones where you don't want want it if it is there.
I would suggest creating UICollectionViewCell subclass wherein you can add a property for stickImage and set it (based on your condition).
Moreover in prepareForReuse function you can default it to whatever you want, it will also make your
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
a bit more cleaner.
I want to have two UICollectionView in same page. Two UICollectionView that would show different data as required. How can I do this?
Thanks in advance.
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifierHall2 = #"hall2";
/* Uncomment this block to use subclass-based cells */
timeCell *cell = (timeCell *)[myCollectionViewHall2 dequeueReusableCellWithReuseIdentifier:cellIdentifierHall2 forIndexPath:indexPath];
[cell.timeButton setTitle:[[allSimilarMutableArray valueForKey:#"showTime"] objectAtIndex:indexPath.item] forState:UIControlStateNormal];
return cell;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifierHall3 = #"hall3";
/* Uncomment this block to use subclass-based cells */
timeCell *cell = (timeCell *)[myCollectionViewHall3 dequeueReusableCellWithReuseIdentifier:cellIdentifierHall3 forIndexPath:indexPath];
[cell.timeButton setTitle:[[allSimilarMutableArray valueForKey:#"showTime"] objectAtIndex:indexPath.item] forState:UIControlStateNormal];
return cell;
}
You can do the same by differentiating in 'cellForItemAtIndexPath'
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
if (collectionView == self.collectiveview1) {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"CollectionCell" forIndexPath:indexPath];
UILabel *titleLabel = (UILabel *)[cell viewWithTag:100];
[titleLabel setText:celldata];
UIImageView *imageView = (UIImageView *)[cell viewWithTag:200];
[imageView setImage:[UIImage imageNamed:connimage]];
return cell;
} else {
static NSString *cellIdentifier = #"FollowCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
UILabel *titleLabel = (UILabel *)[cell viewWithTag:100];
[titleLabel setText:celldata];
UIImageView *imageView = (UIImageView *)[cell viewWithTag:200];
[imageView setImage:[UIImage imageNamed:cellImage]];
return cell;
}
}
Hope it helps.
Because both UICollectionView's respond to the same protocol: UICollectionViewDataSource, you must differentiate between them in the method:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
You can do this multiple ways, depending on how your UICollectionView's are created.
1. If you created them in Storyboard or in Interface Builder, link them to your class using IBOutlet's. Then you can distinguish between them with the following code:
if (collectionView == self.firstCollectionView) { ... }
else if (collectionView == self.secondCollectionView) { ... }
Both firstCollectionView and secondCollectionView must be properties in your View Controller class.
2. Another way is to set tags to them either on Storyboard/Interface Builder or in code with tag property.
So you can for example do this:
self.firstCollectionView.tag = 100;
self.secondCollectionView.tag = 200;
And then again in the cellForItemAtIndexPath method you can distinguish them like:
if (collectionView.tag == 100) { ... }
else if (collectionView.tag == 200) { ... }
Even if you created the collection views in code, you can use the same techniques. Either create properties that point strongly to the collections and compare the pointers or compare them by tags.
The delegate method for cellForItemAtIndexPath also passes in the instance of the collection view it's requesting a cell for. This code snippet is correcting the code example you put in the original post. To take your example, here's how you do this:
- (void)viewDidLoad {
// Initialization of collectionView done previously, set delegates to yourself.
[self.collectionView1 setDelegate:self];
[self.collectionView2 setDelegate:self];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// Setting the cellIdentifier to "hall2" by default, no need to check twice.
NSString *cellIdentifier = #"hall2";
// The collectionView requesting a cell is collectionView2, change the cellIdentifier
if ([collectionView isEqual:self.collectionView2]) {
cellIdentifier = #"hall3";
}
// Since the collectionView we need is already passed, just dequeue and reuse from it.
timeCell *cell = (timeCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
[cell.timeButton setTitle:[[allSimilarMutableArray valueForKey:#"showTime"] objectAtIndex:indexPath.item] forState:UIControlStateNormal];
return cell;
}
I hope this helps you understand how to use multiple collection views with the same delegate.
You can tag the two collection view with different value.
In order to add two UICollectionView in the same page, i user collectionView.tag to identify each of them and decide witch data to pass to each one.
Also, i needed to define different cell sizes for each collection view, but in this method collectionView.tag wasn't working for me. So i had to define a different UICollectionViewLayout to each UICollectionView and then:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
if (collectionViewLayout == layout1) {
return CGSizeMake(100,100);
} else {
return CGSizeMake(50, 50);
}
}