UICollectionView handle selection with NSIndexPath - ios

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

Related

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

How to change an image within UICollectionViewCell on tap?

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

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

Image of cell does not change in didDeselectItemAtIndexPath

I try to change status of image in the cell of the UICollectionView object...
this is a part of my code:
-(UICollectionViewCell*) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
cell *aCell = [collectionView dequeueReusableCellWithReuseIdentifier:#"myCell" forIndexPath:indexPath];
[aCell.myImage setImage:[UIImage imageWithContentsOfFile:self.imageArray[indexPath.item]]];
if (aCell.selected) {
aCell.myImage.layer.borderWidth = 1.0;
aCell.myImage.layer.borderColor = [UIColor blackColor].CGColor;
aCell.mySelect.hidden = NO;
} else {
aCell.myImage.layer.borderWidth = 0.0;
aCell.myImage.layer.borderColor = nil;
aCell.mySelect.hidden = YES;
}
return aCell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Select");
cell *selectedCell= [collectionView dequeueReusableCellWithReuseIdentifier:#"myCell" forIndexPath:indexPath];
if (selectedCell.selected) {
[selectedCell.mySelect setImage:[UIImage imageNamed:#"select.png"]];
selectedCell.myImage.layer.borderWidth = 1.0;
selectedCell.myImage.layer.borderColor = [UIColor blackColor].CGColor;
selectedCell.mySelect.hidden = NO;
} else {
[selectedCell.mySelect setImage:nil];
selectedCell.myImage.layer.borderWidth = 0.0;
selectedCell.myImage.layer.borderColor = nil;
selectedCell.mySelect.hidden = YES; }
}
when i tap any cell, the value select changes, but view object does not refresh.
you need to refresh your row selected with this methos from your didSelectItemAtindexPath method
- (void)reloadItemsAtIndexPaths:(NSArray *)indexPaths
I think you should override selected/highlighted property in your custom UICollectionViewCell subclass for this task instead of using reload.
cell *selectedCell= [collectionView dequeueReusableCellWithReuseIdentifier:#"myCell" forIndexPath:indexPath];
This code will create a NEW cell! Your viewController is not contain this cell!
You should use correct method for getting selected cell:
[yourContentView cellForItemAtIndexPath:indexPath];
Why you are dequeue Cell, when cell is selected .
write following code
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath: (NSIndexPath *)indexPath
{
NSLog(#"Select");
cell *selectedCell= (cell *)[collectionView cellForItemAtIndexPath:indexPath];
[selectedCell.mySelect setImage:(selectedCell.selected) ? [UIImage imageNamed:#"select.png"]: nil];
[collectionView reloadItemsAtIndexPaths:indexPath];
}

How to change the image of a selected cell of a UICollectionView?

I am trying to use this code, but it's not working:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
printf("Selected View index=%d",indexPath.row);
UICollectionViewCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
cell.selectedBackgroundView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"blue_s.png"]];
//[self.collectionView reloadData];
}
How do I change the UIImage of selected UICollectionViewCell in a UICollectionView?
did using this
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"yellow_seat.png"]];
cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"blue_s.png"]];
return cell;
}
got help from link
try this
UICollectionViewCell *cell = (UICollectionViewCell *)[self.collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];

Resources