How to change an image within UICollectionViewCell on tap? - ios

I am trying to change an image that is displayed inside a UICollectionViewCell on tap. Here is my code:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
UIImageView *cellImageView = (UIImageView *)[cell viewWithTag:100];
cellImageView.image = [[allActivities objectAtIndex:indexPath.row] obverseIcon];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%# was selected", [[allActivities objectAtIndex:indexPath.row] name]);
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
UIImageView *cellImageView = (UIImageView *)[cell viewWithTag:100];
Activity *activity = [allActivities objectAtIndex:indexPath.row];
if (activity.isMy)
{
activity.isMy = NO;
cellImageView.image = [[allActivities objectAtIndex:indexPath.row] obverseIcon];
}
else
{
activity.isMy = YES;
cellImageView.image = [[allActivities objectAtIndex:indexPath.row] reverseIcon];
}
[allActivities replaceObjectAtIndex:indexPath.row withObject:activity];
[self.collectionView reloadData];
}
When I tap a cell, image does not change.

try this:
- (UICollectionViewCellSubclass *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCellSubclass *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
Activity *activity = allActivities[indexPath.row];
cell.imageView.image = activity.isMy ? activity.obverseIcon : activity.reverseIcon;
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
Activity *activity = allActivities[indexPath.row];
activity.isMy = !activity.isMy;
[self.collectionView reloadItemsAtIndexPaths:#[indexPath]];
}
where UICollectionViewCellSubclass is your custom class which inherit from UICollectionViewCell and implement:
#property (nonatomic, strong) UIImageView *imageView;

Create custom cell class with super class UICollectionViewCell.
Create an outlet from your cell's image to that class .h file.
In your didSelectItemAtIndexPath method replace UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
with your cell's class name.
Change the image. For example cell.imageView.hidden = YES;

- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
questionImageCollectionViewCell * cell=[self.questionCollectionView dequeueReusableCellWithReuseIdentifier:#"coustomCell" forIndexPath:indexPath];
cell.optionImageView.image=[UIImage imageNamed:[_optionImageArr objectAtIndex:indexPath.item]];
[cell.rightTickImg setHidden:YES];
if(self.array==nil)
{
[cell.rightTickImg setHidden:YES];
}
else
{
[cell.rightTickImg setHidden:YES];
NSDictionary *dic = self.array[indexPath.row];
NSLog(#"ouput DIC=%#",dic);
NSLog(#"objeject for key=%#",[dic objectForKey:#"option"]);
// if ([dic[#"option"] boolValue])
if([[dic objectForKey:#"option"] isEqualToString:#"1"])
{
[cell.rightTickImg setHidden:NO];
}
else
{
[cell.rightTickImg setHidden:YES];
}
}
return cell;
}
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return
CGSizeMake(collectionView.frame.size.width/2.2,collectionView.frame.size.height/2.3);
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
[self dicData];
NSLog(#"First=%#",self.array);
[self.array removeObjectAtIndex:indexPath.row];
NSDictionary *dic = #{#"option":#"1"};
[self.array insertObject:dic atIndex:indexPath.row];
NSLog(#"Second=%#",self.array);
NSMutableArray * indexArry=[[NSMutableArray alloc]init];
for (NSInteger i=0; i< _optionImageArr.count; i++)
{
NSIndexPath * index =[NSIndexPath indexPathForRow:i inSection:0] ;
[indexArry addObject:index];
NSLog(#"%#",indexArry);
}
[collectionView reloadItemsAtIndexPaths:indexArry];
}
Heading

Related

UICollectionView handle selection with NSIndexPath

I'm using a collection view in my app with the selection of cells ..
To handle the selection I am using an NSIndexPath that I call in didSelectItemAtIndexPath and in didDeselectItemAtIndexPath.
The selection seems to work fine but when I select two cells nearby it seems that the didDeselectItemAtIndexPath is not called ... where am I doing wrong?
this is my code
#property (nonatomic, strong) NSIndexPath *selectedIndex;
#implementation YearSelector
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath {
YearCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:yearCellID forIndexPath:indexPath];
cell.yearLabel.text = [NSString stringWithFormat:#"%#", self.yearArray[indexPath.item]];
if ([indexPath isEqual:self.selectedIndex]) [cell highlightedYear:YES];
else [cell highlightedYear:NO];
return cell;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
NSIndexPath *newIndex = [NSIndexPath indexPathForItem:indexPath.item inSection:0];
[collectionView scrollToItemAtIndexPath:newIndex atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
YearCell *cell = (YearCell *)[collectionView cellForItemAtIndexPath:indexPath];
_selectedIndex = indexPath;
[cell highlightedYear:YES];
}
-(void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {
YearCell *cell = (YearCell *)[collectionView cellForItemAtIndexPath:indexPath];
[cell highlightedYear:NO];
_selectedIndex = nil;
}
This is the code I use for highlighted cell ( Custom Year Cell)
-(void)highlightedYear:(BOOL)highlighted {
if (highlighted) {
_baseView.backgroundColor = [UIColor colorWithHexString:#"#FF7751" setAlpha:1];
_baseView.layer.borderColor = UIColor.clearColor.CGColor;
_yearLabel.textColor = UIColor.groupTableViewBackgroundColor;
}
else {
_baseView.backgroundColor = [UIColor colorWithHexString:#"#272D3D" setAlpha:1];
_baseView.layer.borderColor = [UIColor colorWithHexString:#"#485674" setAlpha:1].CGColor;
_yearLabel.textColor = UIColor.groupTableViewBackgroundColor;
}
}

Add inner effect when item selected in collection view

I have a collection view and i want to add an image , with inner effect when one item is selected .
I made this but when i do scroll another item has the same effect and i don't want. How can i change this ?
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CollectionViewCell *cellO = [self.collection cellForItemAtIndexPath:celulaSelectata];
if ([selectedIndexPath isEqual:indexPath]) {
UIImage *inerImager =(UIView *)[cell viewWithTag:100];
cellO.inner.hidden=YES;
return CGSizeMake(100, 100);
}
else {
cellO.inner.hidden=NO;
return CGSizeMake(100, 100);
}
}
-(void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath {
CollectionViewCell *cellOne = [collectionView cellForItemAtIndexPath:indexPath];
cellOne.inner.hidden=YES;
recipeImageView = (UIImageView *)[cell viewWithTag:100];
recipeImageView.frame=CGRectMake(recipeImageView.frame.origin.x, recipeImageView.frame.origin.y, 100, 100);
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
if ([selectedIndexPath isEqual:indexPath]) {
selectedIndexPath = nil;
[self.player stop];
CollectionViewCell *cellOne = [collectionView cellForItemAtIndexPath:indexPath];
cellOne.inner.hidden=YES;
recipeImageView.frame=CGRectMake(recipeImageView.frame.origin.x, recipeImageView.frame.origin.y, 100, 100);
recipeImageView.layer.borderColor = [[UIColor blackColor] CGColor];
}
else {
celulaSelectata=indexPath;
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
CollectionViewCell *cellOne = [collectionView cellForItemAtIndexPath:indexPath];
recipeImageView.frame=CGRectMake(recipeImageView.frame.origin.x, recipeImageView.frame.origin.y, 100, 100);
cellOne.inner.hidden=YES;
}
That is happening because cells are reused. In your CollectionViewCell class you have to implement the method:
-(void)prepareForReuse {
[super prepareForReuse];
//Clear the effect here.
}

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

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.

Resources