Tableview Cell Images Moving To Different Positions When Scrolling - objective-c

When I scroll the table view my images move to the wrong cells. I have set some conditions when an image should be showing or not showing, but no matter what I have tried they just keep moving. My code below.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = #"myCell";
CustomTableView *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil) {
if (self.view.frame.size.height == 736) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCelliPhone6+" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
else if (self.view.frame.size.height == 667){
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCelliPhone6" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
else if (self.view.frame.size.height == 568) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCelliPhone5" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCelliPad" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
else {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomTableView" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
}
MusicFileInfo *musicFileInfo = [mMusicInfoArray objectAtIndex:indexPath.row];
cell.trackName.text = musicFileInfo.mDesc;
cell.trackName.backgroundColor = [UIColor clearColor];
cell.trackName.font = [UIFont fontWithName:#"AvenirNext-Regular" size:13.0];
if (songPlaying == indexPath.row && mAudioPlayer.isPlaying) {
[cell.playButton setBackgroundImage:[UIImage imageNamed:#"pauseBtn.png"] forState:UIControlStateNormal];
[cell.playButton addTarget:self action:#selector(pause:) forControlEvents:UIControlEventTouchUpInside];
cell.playButton.tag = indexPath.row;
}
else {
[cell.playButton setBackgroundImage:[UIImage imageNamed:#"playBtn.png"] forState:UIControlStateNormal];
[cell.playButton addTarget:self action:#selector(playPreview:) forControlEvents:UIControlEventTouchUpInside];
cell.playButton.tag = indexPath.row;
}
if ([[NSUserDefaults standardUserDefaults] boolForKey:[NSString stringWithFormat:#"pack%li", (long)indexPath.row]] == true || [[NSUserDefaults standardUserDefaults] boolForKey:#"unlockAllTracks"] == true) {
cell.rightImage.image = nil;
}
if ([[NSUserDefaults standardUserDefaults] boolForKey:[NSString stringWithFormat:#"pack%li", (long)indexPath.row]] == false) {
if (indexPath.row <= 4) {
cell.rightImage = nil;
} else
[cell.rightImage setImage:[UIImage imageNamed:#"iapBtnStore.png"]];
}
cell.backgroundColor = [UIColor colorWithRed:231.0f/255.0f green:235.0f/255.0f blue:236.0f/255.0f alpha:1];
cell.tag = indexPath.row;
return cell;
}
The play button and track label are fine, they work as they should, but the rightImage is where the problem is.
The first 5 cells should not have an image on first load, on second load the first 5 cells should have a star image and the rest of the cells should have a padlock image. After an IAP has been made, depending on the indexpath.row then that padlock image should no longer be there.
I am checking that with NSUserDefaults.
I hope I have explained properly.
Thanks for any help

UITableViewCells get reused to increase memory efficiency and performance, so you need to "reset" any elements that might change based on the item's state or it might re-appear somewhere else in the list.
Hence "reusable":
[tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil) {
// load nib if needed
}
cell.rightImage = nil; // always reset image

Related

Selected row changes when scrolling UITableView

currently my situation is my fist row is checked by default. but when i want to uncheck it, it need user to click twice to uncheck it. may i know where i done wrongly?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = #"Report_SelectGroupTableViewCell";
Report_SelectGroupTableViewCell *cell = (Report_SelectGroupTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil){
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"Report_SelectGroupTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.indexPath = indexPath;
cell.delegate = self;
}
// [myTableView selectRowAtIndexPath:0 animated:NO scrollPosition:UITableViewScrollPositionNone];
//[self tableView:myTableView didSelectRowAtIndexPath:0];
[cell setSelectionStyle:NO];
NSString *groupID = [[groupArray objectAtIndex:indexPath.row] objectForKey:#"group_id"];
if ([groupID isEqualToString:selectedGroup]){
NSMutableDictionary *dict = [groupArray objectAtIndex:indexPath.row];
BOOL isSelected = [[dict objectForKey:#"isSelected"] boolValue];
if (!isSelected) {
isSelected = !isSelected;
[dict setObject:[NSNumber numberWithBool:isSelected] forKey:#"isSelected"];
}
cell.userInteractionEnabled = NO;
}
cell.groupName.text = [[groupArray objectAtIndex:indexPath.row] objectForKey:#"group_name"];
NSMutableDictionary *typeDict = [groupArray objectAtIndex:indexPath.row];
cell.tickButton.selected = [[typeDict objectForKey:#"isSelected"] boolValue];
if (cell.tickButton.selected) {
[cell.tickButton.layer setBorderColor:[UIColor clearColor].CGColor];
if([cell.groupName.text isEqual:#"All Users"])
{
[cell.tickButton setImage:[UIImage imageNamed:#"tick_Icon_empty.png"] forState:UIControlStateNormal];
}
}
else{
[cell.tickButton.layer setBorderColor:[UIColor whiteColor].CGColor];
}
if([cell.groupName.text isEqual:#"All Users"])
{
[cell.tickButton setImage:[UIImage imageNamed:#"tick_Icon.png"] forState:UIControlStateNormal];
[cell.tickButton.layer setBorderColor:[UIColor clearColor].CGColor];
[typeDict setObject:#"1" forKey:#"isSelected"];
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Report_SelectGroupTableViewCell *cell = (Report_SelectGroupTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
NSMutableDictionary *dict = [groupArray objectAtIndex:indexPath.row];
BOOL isSelected = [[dict objectForKey:#"isSelected"] boolValue];
isSelected = !isSelected;
[dict setObject:[NSNumber numberWithBool:isSelected] forKey:#"isSelected"];
if (cell.tickButton.isSelected == YES)
{
[cell.tickButton setSelected:NO];
[cell.tickButton.layer setBorderColor:[UIColor whiteColor].CGColor];
if([cell.groupName.text isEqual:#"All Users"])
{
[cell.tickButton setImage:[UIImage imageNamed:#"tick_Icon_empty.png"] forState:UIControlStateNormal];
}
}
else if (cell.tickButton.isSelected == NO)
{
[cell.tickButton setSelected:YES];
[cell.tickButton.layer setBorderColor:[UIColor clearColor].CGColor];
}
}
You should remove
[myTableView selectRowAtIndexPath:0 animated:YES scrollPosition:
UITableViewScrollPositionNone];
and use this to select the first row (this should be called once outside this method or you want to set this row selected everytime each cell is render)
[myTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionNone];
And I don't know why you called this in this method
[myTableView.delegate tableView:myTableView didSelectRowAtIndexPath:0];
but if you want to call it you should change to this too
[myTableView.delegate tableView:myTableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
ps. You should set the cell's selectionStyle correctly to see the cell is selected.
Update::
Try to replace all codes in the method with this
Report_SelectGroupTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Report_SelectGroupTableViewCell"];
if (!cell){
cell = [[[NSBundle mainBundle] loadNibNamed:#"Report_SelectGroupTableViewCell" owner:self options:nil] objectAtIndex:0];
}
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
[tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionNone];
return cell;
Please tell me if the first row is not selected and highlighted.

Value stored to 'cell' is never read

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *customCell_Identifier = #"CustomCell";
ThreePartitionCells *cell = (ThreePartitionCells *)[tableView dequeueReusableCellWithIdentifier:customCell_Identifier];
if (cell == nil)
{
cell = (ThreePartitionCells *)[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:customCell_Identifier] autorelease];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ThreePartitionCells" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
NSLog(#"%#", [arrActivityList objectAtIndex:[indexPath row]]);
NSString *strTemp = [NSString stringWithFormat:#"%#-%#", [[[[[arrActivityList objectAtIndex:[indexPath row]] objectForKey:#"ITEMS"] objectForKey:#"Area"] objectForKey:#"AREANAME"] objectForKey:#"text"], [[[[[[[arrActivityList objectAtIndex:[indexPath row]] objectForKey:#"ITEMS"] objectForKey:#"Area"] objectForKey:#"ITEMS"] objectForKey:#"Bin"] objectForKey:#"BIN_BARCODE"] objectForKey:#"text"] ];
cell.lblProductName.text = strTemp;
cell.lblExpectedCount.text = [[[arrActivityList objectAtIndex:[indexPath row]]objectForKey:#"ProductName"]objectForKey:#"text" ];
cell.lblCounted.text = [[[arrActivityList objectAtIndex:[indexPath row]] objectForKey:#"Status"] objectForKey:#"text"];
[cell.lblProductName setFont:[UIFont fontWithName:#"Helvetica" size:13.0]];
[cell.lblCounted setFont:[UIFont fontWithName:#"Helvetica" size:13.0]];
return cell;
}
I get warning while analyzing project like this "value stored to 'cell' is never read" .Well! code is using the cell but outside of that if block. I want to silent this warning!
Can anybody help me for this?
Thanks in advance :)
The problem here:
if (cell == nil)
{
cell = (ThreePartitionCells *)[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:customCell_Identifier] autorelease];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ThreePartitionCells" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
You initialize the cell from custom class, and then you assigned to the cell from a nib, so that you lose control of the first cell and you have not used the first cell.
Try this:
if (!cell){
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ThreePartitionCells"
owner:self
options:nil];
for (id obj in nib) {
if ([obj isKindOfClass:[ThreePartitionCells class]]) {
cell = (ThreePartitionCells *)obj;
break;
}
}
}
or:
if (!cell){
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ThreePartitionCells"
owner:self
options:nil];
cell = nib[0];
}
or:
if (!cell){
cell = [[[ThreePartitionCells alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:customCell_Identifierr] autorelease];
}

How Block or disable someones Customs Cells From Tableview with data from plist?

well I have 2 plist files:
And:
My StoryBoard is:
the problem is when in my "Inicio" viewcontroller load data from the plist, I want Disable the cells when have the ENABLE=NO property & Enable the cells with ENABLE = YES, when I push or click in the cell, then go to the next view controller "PERSONAS" in this view controller load the 2nd Plist and in the same case I want go to the "DETALLE"viewcontroller only with the enabled cells that have ENABLED YES from plist.
for each viewdidload Im use:
NSString *myListPath = [[NSBundle mainBundle] pathForResource:#"MainMenuList" ofType:#"plist"];
mainMenu = [[NSArray alloc]initWithContentsOfFile:myListPath];
NSLog(#"%#",mainMenu);
NSString *myListPath = [[NSBundle mainBundle] pathForResource:#"PersonasList" ofType:#"plist"];
Personas = [[NSArray alloc]initWithContentsOfFile:myListPath];
NSLog(#"%#",Personas);
And for show the tableview in the custom cell Im use:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"CustomCell";
NSLog(#"CARGANDO CELDAS");
MainMenuCell *cell = (MainMenuCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCelliPhone" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
//CustomCell*cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
cell.Enabled.text = [[mainMenu objectAtIndex:indexPath.row]objectForKey:#"ENABLE"];
cell.TitleLabel.text = [[mainMenu objectAtIndex:indexPath.row]objectForKey:#"NAME"];
cell.ImageImageView.image = [UIImage imageNamed:[[mainMenu objectAtIndex:indexPath.row]objectForKey:#"IMAGE"]];
if ([cell.Enabled.text isEqualToString:#"NO"])
{
NSLog(#"%#",cell.Enabled.text);
cell.userInteractionEnabled = NO;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.selected = NO;
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
in the Persona view controller I use the same code but not working, all customs cells are enabled, how can I fix that?, or am I wrong in something? or I did Forget Something please help guys!!
in the Simulator run in that way for ENABLE:
But I dont wanna the cells with ENABLE NO run!!:
Please help guys, im using XCODE 5 DP6, for iOS7, how is the best way for solve this!!!
THANKS!!!!
for many intents, finally fix this!! well in each viewcontroller the code whit solve this is like:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"MainMenuCell";
NSLog(#"CARGANDO CELDAS");
MainMenuCell *cell = (MainMenuCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MainMenuCelliPhone" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
//MainMenuCell*cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
cell.Enabled.text = [[mainMenu objectAtIndex:indexPath.row]objectForKey:#"Enabled"];
cell.TitleLabel.text = [[mainMenu objectAtIndex:indexPath.row]objectForKey:#"Title"];
cell.ImageImageView.image = [UIImage imageNamed:[[mainMenu objectAtIndex:indexPath.row]objectForKey:#"Image"]];
//cell.ImageImageView.image = [[mainMenu objectAtIndex:indexPath.row]objectForKey:#"Image"];
if ([[[mainMenu objectAtIndex:indexPath.row]objectForKey:#"Enabled"] isEqualToString:#"NO"])
{
NSLog(#"%#",cell.Enabled.text);
cell.userInteractionEnabled = NO;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.selected = NO;
cell.accessoryType = UITableViewCellAccessoryNone;
cell.ImageImageView.image = [UIImage imageNamed:#"NO.png"];
}
else
{
cell.ImageImageView.image = [UIImage imageNamed:#"YES.png"];
}
return cell;
//------------------------------------------//
// THANKS anyway //
// GRETTINGS FROM BOLIVIA //
// ROCK ON!!!! n_n' //
//------------------------------------------//
}

UITableView and custom cells

i have a tableView with a custom cell, my first cell is different with the others cells. ( it contain a small image and a label). I am doing like this :
#
pragma mark - tableView data source methods
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
SuggestionCarteCell *cell = (SuggestionCarteCell *)[tableView dequeueReusableCellWithIdentifier:#"carteCell"];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SuggestionCarteCell" owner:nil options:nil] ;
cell = [nib objectAtIndex:0];
}
if (indexPath.row == 0) {
// crer l'image
NSLog(#" je suis dans row 0");
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(21, 9, 13, 26)];
imageView.image = [UIImage imageNamed:#"iconeLocation"];
[cell addSubview:imageView];
cell.labelRegion.frame = CGRectMake(21+13+10, cell.labelRegion.frame.origin.y,cell.labelRegion.frame.size.width , cell.labelRegion.frame.size.height);
cell.labelRegion.text = [NSString stringWithFormat:#"A proximité,"];
}
else{
Region *region = [Region new];
region =(Region *) [arrayRegion objectAtIndex:indexPath.row];
cell.labelRegion.text =region.nomRegion;
}
return cell;
}
in the first time it's good, but when i scroll my first cell ( the small image added) appear in the other rows. What i am doing wrong ? thanks
You have two types of cell but only one reuse identifier.
Two options:
Make sure that when your cell is reused it resets its state to a default, empty state. There's a prepareForReuse method for this purpose
Define two different cells, each with their own, unique reuse identifier. That way your first, different cell will not get reused later on
Try like this
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
SuggestionCarteCell *cell = (SuggestionCarteCell *)[tableView dequeueReusableCellWithIdentifier:#"carteCell"];
UIImageView *imageView;
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SuggestionCarteCell" owner:nil options:nil] ;
cell = [nib objectAtIndex:0];
imageView = [[UIImageView alloc]initWithFrame:CGRectMake(21, 9, 13, 26)];
imageView.tag = 100;
[cell addSubview:imageView];
} else {
imageView = [cell viewWithTag:100];
}
if (indexPath.row == 0) {
// crer l'image
NSLog(#" je suis dans row 0");
imageView.image = [UIImage imageNamed:#"iconeLocation"];
cell.labelRegion.frame = CGRectMake(21+13+10, cell.labelRegion.frame.origin.y,cell.labelRegion.frame.size.width , cell.labelRegion.frame.size.height);
cell.labelRegion.text = [NSString stringWithFormat:#"A proximité,"];
}
else{
Region *region = [Region new];
region =(Region *) [arrayRegion objectAtIndex:indexPath.row];
cell.labelRegion.text =region.nomRegion;
imageView.image = nil;
}
return cell;
}
This way, the cells are reused, the image view is created only once, then you get its reference by its tag, but in one case you set its image, in the other case, you set it to nil.

When scrolling a tableview back again cells appear blank?

After loading a tableview with custom cells all looks fine and scrolling down is fine.
When I scroll up the cells above appear blank. They are in fact fully functional as they can still be selected and then they go off to the details pages.
The code cellForRowAtIndexPath is executed for the returning row and returns the cell as I would expect with the right details. It just isn't displayed.
Any thoughts/help would be appreciated.
The code below is what I have been using.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CustomCellIdentifier = #"CustomCellIdentifier";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
for (id oneObject in nib) {
if ([oneObject isKindOfClass:[CustomCell class]]) {
cell = (CustomCell *)oneObject;
}
}
}
// Configure the cell.
Book *aBook = [appDelegate.sortedArray objectAtIndex:indexPath.row];
//name
NSString *trimmedString = [aBook.Name stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
cell.nameLabel.text = trimmedString;
//catagory
NSString *trimmedExperience = [aBook.PrimaryExperience stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([trimmedExperience isEqualToString:#"1"]) {
cell.catagoryLabel.text = #"None";
}
else if([trimmedExperience isEqualToString:#"2"]){
cell.catagoryLabel.text = #"Limited";
}
else if ([trimmedExperience isEqualToString:#"4"]) {
cell.catagoryLabel.text = #"Full";
}
else {
cell.catagoryLabel.text = #"";
}
cell.distanceLabel.text = [NSString stringWithFormat:#"%1.1f",aBook.distance];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
return cell;
}
The problem lies with the xib file and how it loaded. To cut out the issue and gain total control the following code was substituted for the IB version of the custom cell.
static NSString *CellTableIdentifier = #"CellTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellTableIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellTableIdentifier] autorelease];
CGRect nameLabelRect = CGRectMake(15, 5, 200, 15);
UILabel *nameLabel = [[UILabel alloc] initWithFrame:nameLabelRect];
nameLabel.textAlignment = UITextAlignmentLeft;
nameLabel.font = [UIFont boldSystemFontOfSize:14];
nameLabel.tag = kNameTag;
[cell.contentView addSubview:nameLabel];
[nameLabel release];
CGRect catagoryLabelRect = CGRectMake(15, 26, 100, 15);
UILabel *catagoryLabel = [[UILabel alloc]initWithFrame:catagoryLabelRect];
catagoryLabel.textAlignment = UITextAlignmentLeft;
catagoryLabel.font = [UIFont systemFontOfSize:12];
catagoryLabel.tag = kExperienceTag;
[cell.contentView addSubview:catagoryLabel];
[catagoryLabel release];
CGRect distanceLabelRect = CGRectMake(210, 26, 70, 15);
UILabel *distanceLabel = [[UILabel alloc] initWithFrame:distanceLabelRect];
distanceLabel.textAlignment = UITextAlignmentRight;
distanceLabel.font = [UIFont boldSystemFontOfSize:12];
distanceLabel.tag = kDistanceTag;
[cell.contentView addSubview:distanceLabel];
[distanceLabel release];
}
Thanks for helping think this one through. Now the scrolling works perfectly.