Selection and unselection isselection issue in UICollectionView - ios

I am facing the same issue Multiple selections Issue
Here is my code which I have done.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
RCCollectionCell* cell = [_channelCollectionView dequeueReusableCellWithReuseIdentifier:#"RC" forIndexPath: indexPath];
cell.layer.cornerRadius = 5.0f;
cell.layer.borderWidth=1.0f;
cell.layer.borderColor=[UIColor lightGrayColor].CGColor;
if (indexPath.row < [_fC count]){
[cell setChannel:_favoriteChannels[indexPath.row]];
[_channelCollectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone];
} else {
//NSLog(#"Error cell %d requested only %d channels in incident", (int)indexPath.row, (int)[_incident.channels count]);
}
return cell;
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
RCCollectionCell* cell = [_channelCollectionView dequeueReusableCellWithReuseIdentifier:#"RC" forIndexPath: indexPath];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
RCCollectionCell* cell = (RCCollectionCell*)[collectionView cellForItemAtIndexPath:indexPath];
Channel* channel = [self getChannelForIndexPath:indexPath];
if ([_upload.channels containsObject:channel.uuid]) {
[_upload.channels removeObject:channel.uuid];
cell.selectedImage.hidden = YES;
} else {
[self.view makeToast:channel.name duration:1.5 position:CSToastPositionCenter];
[_upload.channels addObject:channel.uuid];
cell.selectedImage.hidden = NO;
}
[collectionView deselectItemAtIndexPath:indexPath animated:YES];
}
My Problem is cell.selectedImage.hidden = NO; when I click on any cell and when I scroll the collectionview I can see that another cell is also affected with selectedimage.hidden = no.
Please suggest me some solutions to resolve this issue.
Thanks in advance.
EDIT:
selectedImage is a checkmark image which I am using to check and uncheck the cell.

First you create a NSMutableArray to store the selected collectionview indexpaths.
NSMutableArray *SelectedIndexes = [[NSMutableArray alloc]init];
and add the indexpath in the if conditoin of didselect method
[SelectedIndexes addObject:indexPath];
And remove the indexpath inside "else" condition of didselect method.
if ([SelectedIndexes containsObject:indexPath]) {
[SelectedIndexes removeObject:indexPath];
}
In your cellForItemAtIndexPath method check for the selected indexpath.
if ([SelectedIndexes containsObject:indexPath]) {
cell.selectedImage.hidden = YES;
}
else {
cell.selectedImage.hidden = NO;
}

Related

Adding collectionview into uitableviewcell and reload data for particular cell of tableview

how to bind data from server into collectionview which is inside uitableviewcell using hide and unhide functionality.on tap of uibutton i want to make colectionview visible and hide it again on the tap of button.What happens is when i scroll the tableview the data inside the collectionview skips from one cell to another making the collection view blank.
-(void)arrowButtonTapped:(UIButton *)donwbtn{
myob = [NSString stringWithFormat:#"%li", (long)donwbtn.tag];
NSLog(#"%#",myob);
NSIndexPath * indexPath = [NSIndexPath indexPathForRow:0
inSection:donwbtn.tag];
OppCell* celll = [_tableView cellForRowAtIndexPath:indexPath];
celll.collView.tag=donwbtn.tag;
if ([checkcoll containsObject:myob]) {
[checkcoll removeObject:myob];
celll.collView.hidden = true;
celll.collvwhght.constant=0;
celll.colltop.constant=0;
celll.collbottom.constant=0;
}
else
{
[checkcoll addObject:myob];
celll.collView.hidden = false;
celll.collvwhght.constant=229;
celll.colltop.constant=9;
celll.collbottom.constant=8;
[celll.collView reloadData] ;
}
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath{
OppCell *cell = (OppCell *)[tableView
dequeueReusableCellWithIdentifier:#"OppCell"];
NSString *theIndexpath = [NSString stringWithFormat:#"%ld",
(long)indexPath.section];
if ([checkcoll containsObject:theIndexpath])
{
cell.collView.hidden = false;
cell.collvwhght.constant=229;
cell.colltop.constant=9;
cell.collbottom.constant=8;
if((![[[_Activitylistarray
objectAtIndex:indexPath.section]
valueForKey:#"OpportunityContactInfoList"]
isKindOfClass:[NSNull class]])&&([[[_Activitylistarray
objectAtIndex:indexPath.section]
valueForKey:#"OpportunityContactInfoList"]count]>0)){
if(cell.contactdetailsarray == nil) {
cell.contactdetailsarray =[[NSMutableArray alloc]init];
for(NSDictionary * contactdict in
[[_Activitylistarray objectAtIndex:indexPath.section]
valueForKey:#"OpportunityContactInfoList"] ){
[cell.contactdetailsarray addObject:contactdict];
[cell.collView reloadData];
}
}
}
}
else
{
cell.collView.hidden = true;
cell.collvwhght.constant=0;
cell.colltop.constant=0;
cell.collbottom.constant=0;
// [cell.contactdetailsarray removeAllObjects];
// [cell.collView reloadData];
}
////Code in UITableViewCell
#import "OppCell.h"
#import "OppsContactCell.h"
#implementation OppCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
[self.collView registerNib:[UINib nibWithNibName:#"OppsContactCell"
bundle:nil] forCellWithReuseIdentifier:#"OppsContactCell"];
self.collView.pagingEnabled = YES;
UICollectionViewFlowLayout * layout=[[UICollectionViewFlowLayout
alloc]init];
layout.scrollDirection=UICollectionViewScrollDirectionHorizontal;
self.collView.collectionViewLayout = layout;
self.collView.decelerationRate =
UIScrollViewDecelerationRateNormal;
// _contactdetailsarray=[NSMutableArray array];
// self.collvwhght.constant=0;
//self.collView.hidden=YES;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (UICollectionViewCell *)collectionView:(UICollectionView
*)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
OppsContactCell *cell = [collectionView
dequeueReusableCellWithReuseIdentifier:#"OppsContactCell"
forIndexPath:indexPath];
cell.contactimgvw.image = [cell.contactimgvw.image
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[cell.contactimgvw setTintColor:[UIColor blackColor]];
cell.numberimgvw.image = [cell.numberimgvw.image
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[cell.numberimgvw setTintColor:[UIColor blackColor]];
cell.emailimgvw.image = [cell.emailimgvw.image
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[cell.emailimgvw setTintColor:[UIColor blackColor]];
if(_contactdetailsarray.count==1){
if(([[[_contactdetailsarray
objectAtIndex:0]valueForKey:#"Designation"]isEqualToString:#""])&&([[[_contactdetailsarray
objectAtIndex:0]valueForKey:#"Department"]isEqualToString:#"" ])){
cell.lbldesignation.text=#"";
}
else{
cell.lbldesignation.text=[NSString stringWithFormat:#"%#,%#",
[[_contactdetailsarray objectAtIndex:0]valueForKey:#"Designation"],
[[_contactdetailsarray objectAtIndex:0]valueForKey:#"Department"]];
}
cell.lblcontatname.text=[[_contactdetailsarray
objectAtIndex:0]valueForKey:#"ContactName"];
cell.lblcontactnumber.text=[[_contactdetailsarray
objectAtIndex:0]valueForKey:#"TelephoneNo"];
cell.lblemail.text=[[_contactdetailsarray
objectAtIndex:0]valueForKey:#"EmailAddress"];
}
else{
if(([[[_contactdetailsarray
objectAtIndex:0]valueForKey:#"Designation"]isEqualToString:#""])&& .
([[[_contactdetailsarray
objectAtIndex:0]valueForKey:#"Department"]isEqualToString:#"" ])){
cell.lbldesignation.text=#"";
}
else{
cell.lbldesignation.text=[NSString stringWithFormat:#"%#,%#",
[[_contactdetailsarray
objectAtIndex:indexPath.section]valueForKey:#"Designation"],
[[_contactdetailsarray
objectAtIndex:indexPath.section]valueForKey:#"Department"]];
}
cell.lblcontatname.text=[[_contactdetailsarray
objectAtIndex:indexPath.row]valueForKey:#"ContactName"];
cell.lblcontactnumber.text=[[_contactdetailsarray
objectAtIndex:indexPath.row]valueForKey:#"TelephoneNo"];
cell.lblemail.text=[[_contactdetailsarray
objectAtIndex:indexPath.row]valueForKey:#"EmailAddress"];
}
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(_collView.bounds.size.width
,_collView.bounds.size.height);
}
- (CGFloat)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return 5;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section{
// return 5;
if(_contactdetailsarray.count==0){
return 0;
}
else{
return _contactdetailsarray.count;
}
}
Thanks & Regards,
Roshan.k

UICollectionview changes selection/disabling selection while scrolling - iOS

I'm populating data on uicollectionview cell and selecting and deselecting, everything works perfect but when I start scrolling sometime selection is not there sometimes selection changing with the cell. Below is the code, help much appreciated.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
cell = (BYOCollectionCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"CVCCell" forIndexPath:indexPath];
cell.vSelectionView.hidden = YES;
cell.vSelectionView.backgroundColor = customLightGreenColor;
[self makeRoundElement:cell.vSelectionView forLabel:nil withCorner:8.0f withBorder:0];
pizzaInfo *pizzainfo= [[pizzaInfo alloc]init];
pizzainfo = [_lstDishCollection objectAtIndex: indexPath.row];
if (pizzainfo._bIsSelected)
{
cell.vSelectionView.hidden = NO;
}
else
{
cell.vSelectionView.hidden = YES;
}
//label customization
return cell;
}
DidselectItem
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
cell = (BYOCollectionCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"CVCCell" forIndexPath:indexPath];
pizzaInfo *pizzaInfoCellData = [_lstDishCollection objectAtIndex: indexPath.row];
byoPizzaInfo = [_lstDishCollection objectAtIndex:indexPath.row];
if ( pizzaInfoCellData._bIsSelected)
{
cell.vSelectionView.hidden = NO;
pizzaInfoCellData._bIsSelected = NO;
[self._byodelegate deltaDeSelection:pizzaInfoCellData];
}
else
{
cell.vSelectionView.hidden = YES;
pizzaInfoCellData._bIsSelected = YES;
// deltaSelection:(pizzaInfo *)selectedItem
[self._byodelegate deltaSelection:pizzaInfoCellData];
if (self._IsNotifiable) {
[self showView];
}
}
[_vCVC reloadData];
}
More over collectionViewCell is inside tableViewCell.
In your cellForItemAtIndexPath you have already added condition for hide and show the selected view so you need to change your didSelectItemAtIndexPath like this
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
pizzaInfo *pizzaInfoCellData = [_lstDishCollection objectAtIndex: indexPath.row];
if (pizzaInfoCellData._bIsSelected)
{
[self._byodelegate deltaDeSelection:pizzaInfoCellData];
}
else
{
[self._byodelegate deltaSelection:pizzaInfoCellData];
}
pizzaInfoCellData._bIsSelected = !pizzaInfoCellData._bIsSelected
[_vCVC reloadData];
}
Note:- Class name always start with uppercase latter so it is batter if you change your class name pizzaInfo with PizzaInfo, its suggestion for good coding guidelines.

collectionviewcell didSelectItemAtIndexPath/didDeselectItemAtIndexPath not responding for specific cells

I am trying to preselect some of the cell according to condition, which sets those cells selected and also change its background color while drawing those cells. Now the method
didSelectItemAtIndexPath / didDeselectItemAtIndexPath
is not getting called only for those preselected cells and hence I am not able to toggle selection and background color. The select/deselect delegate methods are being called for other cells
-(UICollectionViewCell*) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"cellForItemAtIndexPath: %#", indexPath);
CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"collectionViewCell" forIndexPath:indexPath];
if(indexPath.row != 0 && indexPath.row != 8 && indexPath.section != 0 && indexPath.section != 25){
NSMutableDictionary *blockedHours = [blockedDaysArray objectAtIndex:indexPath.row-1];
NSString *blockedVal = [blockedHours valueForKey:#(indexPath.section-1).stringValue];
[cell setBlockedVal:(NSString*)blockedVal];
}
[cell addDayTimeLable:indexPath];
return cell;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"didSelectItemAtIndexPath: %# ", indexPath);
NSMutableDictionary *blockedHours = [blockedDaysArray objectAtIndex:indexPath.row-1];
[blockedHours setValue:#"1" forKey:#(indexPath.section-1).stringValue];
CollectionViewCell *cell = (CollectionViewCell*)[collectionView cellForItemAtIndexPath:indexPath];
cell.selected = YES;
}
-(void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"didDeselectItemAtIndexPath %#", indexPath);
NSMutableDictionary *blockedHours = [blockedDaysArray objectAtIndex:indexPath.row-1];
[blockedHours setValue:#"0" forKey:#(indexPath.section-1).stringValue];
CollectionViewCell *cell = (CollectionViewCell*)[collectionView cellForItemAtIndexPath:indexPath];
cell.selected = NO;
}
In CollectionViewCell.m:
Self.selected calls the setter method and hence chagnes the background color
-(void)setBlockedVal:(NSString*)blockedVal{
if([blockedVal isEqualToString:#"1"]){
self.selected = YES;
}
}
-(void)setSelected:(BOOL)selected{
NSLog(#"set selected: %d", selected);
[super setSelected:selected];
if(selected)
self.backgroundColor = [SFIColors lightGreenColor];
else
self.backgroundColor = [UIColor whiteColor];
}
Note:
(1) didHighlightItemAtIndexPath/didUnHighlightItemAtIndexPath are
getting called for preselected cells.
(2)I Just found out that setting selected via didselect/didunselect is
redundant and I just removed from my code.Noticed that setSeleted is
auto called on clicking the other cells. Still this setSelected is not
being for preselected cells
Any Inputs to fix this or another way that I can do my task would be of great help.
I found the answer in this link: UICollectionView - didDeselectItemAtIndexPath not called if cell is selected
I actually searched a lot actually, but only now I found this link.
I had let my collection view know about my selection and that did the trick:
[collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone];

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

Resources