Add an image on collection view cell having background colour in iOS - ios

i am working on my application in which I have to add an image to collection view cell on selection. Collection view cell is circular and filled with color, so on selection of cell, image of tick should be on that color.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
NSArray *hexaColor= _advantageModelObj.productDetail.carColorDetails;
CarColorDetailObject *carColor= [hexaColor objectAtIndex:indexPath.row];
NSString *hexCode= carColor.carColor.hexCode;
cell.layer.masksToBounds=TRUE;
cell.backgroundColor=[self colorWithHexString:hexCode];
cell.layer.cornerRadius= (roundf(cell.frame.size.width/2));
cell.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:#"colorselected.png"]];
return cell;
}

Make global variable
int clickedIndex;
2 in viewDidLoad assign to clickedIndex
clickedIndex=-1;
in collectionView didSelectItemAtIndexPath
clickedIndex=(int)indexPath.row;
[collectionView reloadData];
4 add some line in collectionView cellForItemAtIndexPath
if(clickedIndex==indexPath.row){
UIImageView* imageView=[[UIImageView alloc]init];
[imageView setFrame:CGRectMake(10, 0, cell.contentView.size.width, cell.contentView.size.height)];
imageView.image=[UIImage imageNamed:[NSString stringWithFormat:#“tickImage”,]];
imageView.alpha=0.5;
[cell.contentView addSubview: imageView];
}

Related

UICollectionViewCell background color change works in cellForItemAtIndexPath but not didSelectItemAtIndexPath

I can change my collection view cell background color in cellforitematindexpath but not in didselectitematindexpath using the code below (i only change the color in one place however). How does this happen? I know that didselectitematindexpath is being called.
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CollectionViewCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"CollectionView" forIndexPath:indexPath];
cell.layer.borderWidth=1.0f;
cell.layer.borderColor=[UIColor grayColor].CGColor;
cell.label.text = #"test"
cell.contentView.backgroundColor = [UIColor redColor];
return cell;
}
-(void)collectionView:(UICollectionView *)cv didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"selected cell");
CollectionViewCell *cell = [self collectionView:cv cellForItemAtIndexPath:indexPath];
cell.contentView.backgroundColor = [UIColor redColor];
}
Several things wrong here.
You're using the wrong method to get the selected cell. Never call the delegate method directly, instead ask the collection view for the cell directly like this:
CollectionViewCell *cell = [cv cellForItemAtIndexPath:indexPath];
You're modifying the cell in a place where those modifications will not persist. When you scroll and that cell gets reused, the color will get wiped out. Instead you should call reloadItemsAtIndexPaths: when the cell gets selected, and have some code in collectionView:cellForRowAtIndexPath that checks the selected property of the cell and sets the color you want based on that. That way, the layout will remain consistent when you scroll and cells are reused.
use this..
self.collectionView.allowsMultipleSelection = YES;
then..
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath**
{
static NSString *identifier = #"Cell";
RecipeViewCell *cell = (RecipeViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
recipeImageView.image = [UIImage imageNamed:[recipeImages[indexPath.section] objectAtIndex:indexPath.row]];
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"photo-frame-2.png"]];
cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"photo-frame.png"]];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
if (shareEnabled) {
NSString *selectedRecipe = [recipeImages[indexPath.section] objectAtIndex:indexPath.row];
[selectedRecipes addObject:selectedRecipe];
}
}
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath
{
if (shareEnabled) {
NSString *deSelectedRecipe = [recipeImages[indexPath.section] objectAtIndex:indexPath.row];
[selectedRecipes removeObject:deSelectedRecipe];
}
}

UICollectionView - Image is getting set randomly

I am using collectionView in my App. I am setting image for the cell backgroundView in didSelect delegate. But When i select one cell indexPath the image is getting set for 3 cell indexPath. When i scroll the collectionView the images are getting changed randomly? Please Help me. thanks in advance.
- (void)viewDidLoad
{
[super viewDidLoad];
[collection registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:uio];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection: (NSInteger)section
{
return 50;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collection dequeueReusableCellWithReuseIdentifier:uio
forIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"index %#",indexPath);
UICollectionViewCell *cell = [collection cellForItemAtIndexPath:indexPath];
cell.backgroundView =[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"download.jpg"]];
}
That's because you reuse your cell. An option would be to have an dictionary variable to say that your cell has been selected and reset the image if it has not been.
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"index %#",indexPath);
UICollectionViewCell *cell = [collection cellForItemAtIndexPath:indexPath];
cell.backgroundView =[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"download.jpg"]];
[selectedDictionary setObject:[NSNumber numberWithBool:YES] forKey:[NSNumber numberWithInteger:indexPath.row]];
}
Then in your cellForItemAtIndexPath method you would check that value
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collection dequeueReusableCellWithReuseIdentifier:uio
forIndexPath:indexPath];
BOOL selected = [[selectedDictionary objectForKey:[NSNumber numberWithInteger:indexPath.row]] boolValue];
if(selected){
cell.backgroundView =[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"download.jpg"]];
}else{
cell.backgroundView = nil;
}
cell.backgroundColor = [UIColor whiteColor];
return cell;
}
Of course if you use some kind of object as model, it would appropriate to have a selected variable in here, you won't need a nsdictionary any more.
The Problem is dequeueReusableCellWithReuseIdentifier.
When you scroll UICollectionview then cell are reused that is problem
add Collectionview inside scrollview.
Try this Inside:
Scroll_View is Your Scroll View
collection is Your Collectionview
-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
self.Scroll_View.contentSize = CGSizeMake(self.view.frame.size.width, collectionView.contentSize.height);
CGRect fram_For_Collection_View = self.collection_view.frame;
fram_For_Collection_View.size.height = collectionView.contentSize.height;
self.collection.view.frame = fram_For_Collection_View;
}
Your -collectionView:didSelectItemAtPath: is adding a new image view to the cell. Nothing is removing that image view when the cell is reused. So, when you say:
UICollectionViewCell *cell = [collection dequeueReusableCellWithReuseIdentifier:uio
forIndexPath:indexPath];
in your -collectionView:cellForItemAtIndexPath:, you're may get back some cell that already has one or more image views.
My suggestion would be to add the image view to the cell in the cell prototype, perhaps in your storyboard or in the cell's initializer. Have your -collectionView:cellForItemAtIndexPath: set the image for that image view to the correct image for the given path.
What's happening is that UICollectionView reuses cells. So in didSelectItemAtIndexPath: you set the cell background, but then the UICollectionView reuses that same cell as needed (and you're not resetting the cell.backgroundView in cellForItemAtIndexPath:).
The way to fix this is to maintain an NSIndexSet of selected cells. In didSelectItemAtIndexPath: you can add the index of the item that was selected, and then force a reload of that item by calling reloadItemsAtIndexPaths. Then, in your cellForItemAtIndexPath: check the index set to see if the selected index is included, and if so, set the backgroundView of the cell.
I had the same issue few days ago & I posted a question here. Here is the answer I got & it works for me.
Collection View Cell multiple item select Error
And also if you are using a custom cell you can add this code to the init method of that cell & it will work too.
CGFloat borderWidth = 6.0f;
UIView *bgView = [[UIView alloc] initWithFrame:frame];
bgView.layer.borderColor = [UIColor redColor].CGColor;
bgView.layer.borderWidth = borderWidth;
self.selectedBackgroundView = bgView;

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

UILabel In UICollectionViewCell is setting after scrolling?

In my code,I was trying to use UIImage & UIabel in UICollectionViewCell.What I was doing If there is no image in UICollectionViewCell i want to shift UILabel upwards.So I used two frames of label and checked for if(UIImageView.image==nil) it is showing effect after scrolling?
What to do?
Here is the code what i did-
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *myCell=(UICollectionViewCell*)[self.view viewWithTag:1];
myCell = [collectionView
dequeueReusableCellWithReuseIdentifier:#"Cell"
forIndexPath:indexPath];
UILabel *label=(UILabel*)[myCell viewWithTag:12];
UIImageView *collectionViewImage=(UIImageView*)[myCell viewWithTag:11];
NSString *collectionViewImageName=[imagesCollectionViewArray objectAtIndex:indexPath.row];
collectionViewImage.image=[UIImage imageNamed:collectionViewImageName];
if (collectionViewImage.image==nil) {
[collectionViewImage setBackgroundColor:[UIColor clearColor]];
[label setFrame:CGRectMake(35, 73, 309, 54)];
label.text=[lableColectionviewArray objectAtIndex:indexPath.row];
return myCell;
}else {
[label setFrame:CGRectMake(20, 294, 352, 49)];
label.text=[lableColectionviewArray objectAtIndex:indexPath.row];
return myCell;
}
}
Try to remove cell contentView subviews every collectionView
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
method call.
use
for([UIView *view in cell.contentView.subViews]){
[view removeFromSuperView];
view=nil;
}
and replace this line of code
UICollectionViewCell myCell=(UICollectionViewCell)[self.view viewWithTag:1];
With
UICollectionViewCell *myCell=nil;

UICollectionViewCell and UIScrollView

I encountered a weird behavior of UIScrollView when inside a UICollectionViewCell. In my project I have a collectionView and each cell has a UIScrollView that contains 1 or more images. Here's some sample code for purpose of this question:
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CustomCollectionCell * cell = [cv dequeueReusableCellWithReuseIdentifier:#"CustomCell" forIndexPath:indexPath];
UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 150, 150)];
imageView.image = [UIImage imageNamed:#"someImage.png"];
[cell.scrollView addSubview:imageView];
return cell;
}
Of course in my project it's not the same image but different ones that are fed from a database.
The first collection cell is added with no problem. When I add the second cell, the scrollView seems to duplicate itself and place another instance of itself on top. I know it sounds weird, but you can see how it looks in the image below:
Notice how the image in the scrollView on the left has darkened, I assume it's because the scrollView get duplicated.
So, I'm guessing that the cell is reused in a wrong way or something.
Thanks for your help!
A new UIImageView is being added to the reused cell each time collectionView: cellForItemAtIndexPath: is invoked. To solve this, in the custom UICollectionViewCell, implement the prepareForReuse method. In that method, remove the image view.
To accomplish this, you could set a tag on the image view. E.g.,:
(UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CustomCollectionCell * cell = [cv dequeueReusableCellWithReuseIdentifier:#"CustomCell" forIndexPath:indexPath];
UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 150, 150)];
imageView.image = [UIImage imageNamed:#"someImage.png"];
[cell.scrollView addSubview:imageView];
// The following line of code is new
cell.contentView.tag = 100;
return cell;
}
And to remove the image view from the cell, add/update the prepareForReuse method in the custom cell:
-(void)prepareForReuse{
UIView *myImageView = [self.contentView viewWithTag:100];
[myImageView removeFromSuperview];
}

Resources