Adding image to existing collectionview - ios

I have a sample app of StudentRecord in which i have a UICollectionview of student's images. I want to add button to last cell and this button should add student's image to the last cell.
Following is my existing code, how to modify it-
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CollectionViewCell *myCell = [collectionView
dequeueReusableCellWithReuseIdentifier:#"MyCell"
forIndexPath:indexPath];
UIImage *image;
long row = [indexPath row];
image = [UIImage imageNamed:studentImages[row]];
myCell.imageView.image = image;
return myCell;
}

Related

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 can I show label text dynamically?

I am using an UICollectionViewController in which I shown an different images, but I also want to Add labels for every image and label should show the text dynamically.
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"Cell";
SSCollectionViewCell *cell = (SSCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
int imageNumber = indexPath.row % 10;
cell.imageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"images%d.jpeg",imageNumber]];
cell.myLabel.text = #"Hello";
return cell;
}
As I understand you want to print the image number to your text label then
cell.myLabel.text = [NSString stringWithFormat:#"%d",imageNumber];
this will do

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

UICollectionView images

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.

Collection View Cell multiple item select Error

I have a Collection View & I want to select more than one item. For that I'm using
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
[self.selectedAsset addObject:self.assets[indexPath.row]];
UICollectionViewCell* cell=[self.collectionView cellForItemAtIndexPath:indexPath];
cell.contentView.backgroundColor = [UIColor blackColor];
}
This method to add objects to selectedAsset NSMutableArray.
This is the cellForItemAtIndexPath method.
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath;
{
Cell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"MY_CELL" forIndexPath:indexPath];
// load the asset for this cell
ALAsset *asset = self.assets[indexPath.row];
CGImageRef thumbnailImageRef = [asset thumbnail];
UIImage *thumbnail = [UIImage imageWithCGImage:thumbnailImageRef];
// apply the image to the cell
cell.imageView.image = thumbnail;
[cell.label removeFromSuperview];
//cell.imageView.contentMode = UIViewContentModeScaleToFill;
return cell;
}
I use this code to chance the background colour of the cell.
UICollectionViewCell* cell=[self.collectionView cellForItemAtIndexPath:indexPath];
cell.contentView.backgroundColor = [UIColor blackColor];
But when I select 1st item in the Collection View, both 1st & 15th item in the Collection View change the background Colour.
Why is this happen? Please can someone give me a solution.
Ok, here's what seems to be your problem.
1) When you select first cell this method is called
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
In this method you change cell background colour to be black, so this cell is black from now on.
2) You scroll down and new cells are loaded with method
-(UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath;
There is one tricky line in implementation
dequeueReusableCellWithReuseIdentifier:
So for new cell your app will likely to not create new cell but to show one that is not visible, for example cell #1, which you selected at beginning, and which got black background colour.
So for new cell your app might reuse old one which might be modified.
My fix for you would be next -
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath;
{
UICollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"MY_CELL" forIndexPath:indexPath];
//line below might not work, you have to tune it for your logic, this BOOL needs to return weather cell with indexPath is selected or not
BOOL isCellSelected = [self.selectedAsset containsObject:self.assets[indexPath.row]];
if(!isCellSelected)
{
UICollectionViewCell* cell=[cv cellForItemAtIndexPath:indexPath];
cell.contentView.backgroundColor = [UIColor clearColor]; // or whatever is default for your cells
}
// load the asset for this cell
ALAsset *asset = self.assets[indexPath.row];
CGImageRef thumbnailImageRef = [asset thumbnail];
UIImage *thumbnail = [UIImage imageWithCGImage:thumbnailImageRef];
// apply the image to the cell
cell.imageView.image = thumbnail;
[cell.label removeFromSuperview];
//cell.imageView.contentMode = UIViewContentModeScaleToFill;
return cell;
}

Resources