I have 4 UICollectionViewCell in which I want to make first 2 cell to have image in it mandatory. Sample code is as below. Below is a usecase:
There are 4 UICollectionViewCell if I click on each cell will open camera and we can either take a photo or select image from image gallery. How to know first 2 cell must have image. Looking for condition to check this logic.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
Image *image = (Image *)self.defect.imageSet[indexPath.item];
ADRPhotoCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([ADRPhotoCollectionViewCell class]) forIndexPath:indexPath];
cell.image = image.thumbnailImage ? image.thumbnailImage : nil;
cell.photoType = [self.defect defectPhotoTypeForIndex:indexPath];
return cell;
}
#pragma mark - UICollectionViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
Image *image = self.defect.imageSet[indexPath.item];
if (self.selectedImage != image) {
[self updateAnnotatedImage];
self.selectedImage = image;
[self.jotController clearAll];
[self updateUserInterface];
if (image.thumbnailImage) {
[self transitionImage:YES];
} else {
self.imageView.image = nil;
[self showCameraPicker];
}
} else if (!image.thumbnailImage) {
//clicked the + to add a new image
[self showCameraPicker];
}
}
You can check if there is an image in UIImageView or not by this way:
-(BOOL) checkImages {
for (int i=0, i<2 , i++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
ADRPhotoCollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
if (cell.imageView.image == nil || CGSizeEqualToSize(cell.imageView.image.size, CGSizeZero)) {
//there isn't any image or the image is empty
return NO;
}
}
return YES;
}
Related
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;
}
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
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.
I have maked following view.
But when calling -reloadData, the view becomes...
I think it's because cells is reused.
Do you have any idea to keep view as first image even if calling reloadData?
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCellIdentifier forIndexPath:indexPath];
if (indexPath.item == 0)
{
cell.label.text = #"Hello";
}
else
{
UIImage *image = dataArray[indexPath.item];
cell.imageView.image = image;
}
return cell;
}
CustomCell.m
#property (nonatomic, strong) UIImageView* imageView;
#property (nonatomic, strong) UILabel* label;
//...
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
self.imageView = [[UIImageView alloc]initWithFrame:imgViewFrame];
[self.contentView addSubview:self.imageView];
self.label = [[UILabel alloc]initWithFrame:labelFrame];
[self.contentView addSubview:self.label];
}
return self;
}
EDIT:
I modified my code.
- setting all default values before setting them with correct data
- calling -prepareForReuse
When calling -reloadData, Although imageView.image stay nil, label.text in indexPath.item==0 becomes nil and label.text in indexPath.item==3 outputs #"Hello".
Yes, its because of reusability. You can avoid it by changing line of code to this:
if (indexPath.item == 0)
{
cell.label.text = #"Hello";
cell.imageView.image = nil;
}
else
{
UIImage *image = dataArray[indexPath.item];
cell.imageView.image = image;
cell.label.text = #"";
}
When you're retrieving the dequeued cells they are already setup. So the first time you retrieve 9 different cells and initialise them accordingly.
The second time tough the cells properties are already set so you need to restart them.
So your code should look as follows:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCellIdentifier forIndexPath:indexPath];
if (indexPath.row == 0)
{
cell.imageView.image = nil;
cell.label.text = #"Hello";
}
else
{
UIImage *image = dataArray[indexPath.item];
cell.imageView.image = image;
cell.label.text = nil;
}
return cell;
}
Try setting all default values of your cell before doing any check:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCellIdentifier forIndexPath:indexPath];
//Set all default values before setting them with correct data
cell.imageView.image = nil;
cell.label.text = #"";
if (indexPath.row == 0)
{
cell.label.text = #"Hello";
}
else
{
UIImage *image = dataArray[indexPath.item];
cell.imageView.image = image;
}
return cell;
}
EDIT:
You could add this method to your CustomCell.m
- (void)prepareForReuse
{
//Set default values here
}
REPORT:
I solved the issue on my own.so, I will report it.
I used the property hidden.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCellIdentifier forIndexPath:indexPath];
if (indexPath.item == 0)
{
cell.label.text = #"Hello";
cell.imageView.hidden = YES;
}
else
{
UIImage *image = dataArray[indexPath.item];
cell.imageView.image = image;
cell.label.hidden = YES;
}
return cell;
}
I am trying to select a cell in UICollectionView, it gets selected but on scroll down it selects the some other cell on the bottom and scroll up it shows some other to be selected.
Below is the code which I am using didSelectItemAtIndexPath
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath *newIndex = indexPath;
cell = (CustomCollectionCell *)[collectionView cellForItemAtIndexPath:newIndex];
NSString *strId = [[masterArray valueForKey:#"id"]objectAtIndex:indexPath.row];
NSString *tempIndexRow = [NSString stringWithFormat:#"%ld",(long)indexPath.row];
NSLog(#"%#, %#,%d ,%#, %d", strId,tempIndexRow,cell.imageView.tag,[boolArray objectAtIndex:indexPath.row],indexPath.row);
if (strId && [[boolArray objectAtIndex:indexPath.row] isEqualToString:#"False"] && cell.imageView.tag == indexPath.row) {
cell.selectedImage.image = [UIImage imageNamed:#"select.png"];
[boolArray replaceObjectAtIndex:indexPath.row withObject:#"True"];
}
else{
cell.selectedImage.image = Nil;
[boolArray replaceObjectAtIndex:indexPath.row withObject:#"False"];
}
}
This is what I select for the first time
This is what I get when I scroll down
Thanks
You need to set selected item index store in to one array and at cellForRowIndex time check this array index with indexPath.row like bellow:-
selectedCellsArray alloc this array at ViewDIdLoad method
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
cell = (CustomCollectionCell *)[collectionView cellForItemAtIndexPath:newIndex];
if ( [selectedCellsArray containsObject:[NSString stringWithFormat:#"%d",indexPath.row]] )
{
[selectedCellsArray removeObject:[NSString stringWithFormat:#"%d",indexPath.row]];
cell.selectedImage.image = Nil;
}
else
{
[selectedCellsArray addObject:[NSString stringWithFormat:#"%d",indexPath.row]];
cell.selectedImage.image = [UIImage imageNamed:#"select.png"];
}
}
and
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:indexPath.row];
if ( [selectedCellsArray containsObject:[NSString stringWithFormat:#"%#",rowNsNum]] )
{
cell.selectedImage.image = [UIImage imageNamed:#"select.png"];
}
else
{
cell.selectedImage.image = Nil;
}
}
It is not selecting another cell. Problem is mostlikely due to you reusing cells and not reintializing them correctly when they come back on the screen. When Cells not visible, it unloaded to save memory.
So better check this condtion as well in cellForItemAtIndexPath datasource
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
//You cell initialization code.
if ([[boolArray objectAtIndex:indexPath.row] isEqualToString:#"True"] ) {
cell.selectedImage.image = [UIImage imageNamed:#"select.png"];
}
else{
cell.selectedImage.image = Nil;
}
}