Add inner effect when item selected in collection view - ios

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

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

UICollectionView adding button to cell

I'm adding a button to a cell of a collection view as below
- (void)activateDeletionMode:(UILongPressGestureRecognizer *)gr
{
if (gr.state == UIGestureRecognizerStateBegan)
{
NSLog(#"deletion mode");
if(self.isDeleteActive == NO){
self.isDeleteActive = YES;
NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:[gr locationInView:self.collectionView]];
UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
self.deletedIndexpath = indexPath.row;
self.deleteButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[self.deleteButton addTarget:self
action:#selector(deleteImage:)
forControlEvents:UIControlEventTouchUpInside];
[self.deleteButton setBackgroundImage: [UIImage imageNamed:#"delete.png"] forState:UIControlStateNormal];
self.deleteButton.frame = CGRectMake(10, 0, 10, 10);
[cell addSubview:self.deleteButton];
}
}
}
The problem is, when the cell is reused when the collection view is scrolled, I see the button displayed in this cell too. How do I avoid this happening? Code for collection view below:
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath;
{
Cell *cell = [cv dequeueReusableCellWithReuseIdentifier:kCellID forIndexPath:indexPath];
cell.image.image = [self.imageArray objectAtIndex:indexPath.row];
return cell;
}
In the past I've done things like this, when adding the view add a tag:
self.deleteButton.frame = CGRectMake(10, 0, 10, 10);
//Mark the view with a tag so we can grab it later
self.deleteButton.tag = DELETE_BUTTON_TAG;
[cell addSubview:self.deleteButton];
Then remove it from any new recycled cells:
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath;
{
Cell *cell = [cv dequeueReusableCellWithReuseIdentifier:kCellID forIndexPath:indexPath];
//Remove the delete view if it exists
[[cell viewWithTag:DELETE_BUTTON_TAG] removeFromSuperview];
cell.image.image = [self.imageArray objectAtIndex:indexPath.row];
return cell;
}

How can i modify only the size and position for item selected from collectionView?

i have a collection view and when i select an item i want to make bigger that image and add a frame . I do this , but the rest of images are moving also . This is how i was doing :
- (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 {
// select new cell
celulaSelectata=indexPath;
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
recipeImageView = (UIImageView *)[cell viewWithTag:100];
CollectionViewCell *cellOne = [collectionView cellForItemAtIndexPath:indexPath];
recipeImageView.frame=CGRectMake(recipeImageView.frame.origin.x, recipeImageView.frame.origin.y, 120, 120);
cellOne.inner.frame=recipeImageView.frame;
How can i modify only the size and position for item selected ?
selectedIndexPath create UICollectionViewLayoutAttributes for selected cell and call invalidateItemsAtIndexPaths:(NSArray *)indexPaths to update cell for selected UICollectionViewLayoutAttributes
Subclass your UICollectionViewLayout and add funtion in your UICollectionViewLayout and invalidate any indexPath to update
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes *attribute = [super layoutAttributesForItemAtIndexPath:indexPath];
if ([indexPath isEqual:selectedIndexPath]) {
//set attributes
//attribute.frame = //setframe;
}
return attribute;
}
if ([selectedIndexPath isEqual:indexPath])
I think you have to write this part in the cellforRow method.
not in didSelectRowAtIndexpath.

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

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

Resources