IOS:维护uitableviewcell中的button状态
我有一个iPhone应用程序的问题已经困扰了我几天,它似乎不应该是这样的困难,所以我肯定我失去了一些明显的东西。 我已经研究了许多关于“类似”主题的论坛讨论,但没有任何实际上解决这个问题,特别是。
要清楚的是,如果有一些文件或其他来源需要研究,请指出正确的方向。
开始…
我有一个项目的列表,我显示给一个表(uitableview)内的用户。 每个项目的单元格(uitableviewcell)是自定义的,包含一个图像和一个Likebutton(uibutton)。 正如预期的那样,对于表中的每个项目,用户可以点击Likebutton或忽略它。 像button调用一个单独的进程来更新服务器。 很简单,对吧?
所以,这是问题:
在特定单元格上单击“Like”button时,“选定”状态正常工作,但当您将单元格从视图中移出时,表格中的其他随机单元格将Likebutton显示为“选中”,即使它们从未被触摸过。 由于细胞被重复使用,出于显而易见的性能原因,我明白为什么会发生这种情况。 我不明白的是为什么我的方法(见下面的代码)不会覆盖或重置button的状态,我认为它应该。 为了简洁,我只在这里包括相关的代码(希望格式正确):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"MyCustomCell"; MyCustomViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[MyCustomViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; cell.selectionStyle = UITableViewCellSelectionStyleNone; } NSString *myRating = [[self.dataArray objectAtIndex:indexPath.row] valueForKey:@"my_rating"]; // Create the Like button UIButton *likeButton = [[UIButton alloc] initWithFrame:CGRectMake(260, 68, 40, 40)]; [likeButton setImage:[UIImage imageNamed:@"thumbsUp"] forState:UIControlStateNormal]; [likeButton setImage:[UIImage imageNamed:@"thumbsUpSelected"] forState:UIControlStateSelected]; if (myRating == @"9") { [likeButton setSelected:YES]; } [likeButton setTitle:@"9" forState:UIControlStateNormal]; [likeButton setTag:indexPath.row]; [cell.contentView addSubview:likeButton]; [likeButton addTarget:self action:@selector(likeButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; return cell; } - (void)likeButtonPressed:(UIButton *)sender { // Changed the Selected state on the button UIButton *button = (UIButton *)sender; button.selected = !button.selected; // Create a new object with the user's rating and then replace it in the dataArray NSString *ratingText = sender.titleLabel.text; NSMutableArray *myMutableArray = [[self.dataArray objectAtIndex:row] mutableCopy]; [myMutableArray setValue:ratingText forKey:@"my_rating"]; [self.dataArray replaceObjectAtIndex:row withObject:myMutableArray]; }
所以,我已经经历了许多迭代,但我似乎无法得到button的状态,以显示那些喜欢的项目的选定的图像,并保留那些不喜欢的项目的正常形象。
任何帮助或build议将不胜感激。
问题是每次你创build或重用一个单元时,你都会给它一个新的button,所以当你重新使用一个单元时,类似的button已经被激活,你可以给它一个类似于button的button,但是旧的,激活的像button还在那里。
每当你需要一个单元格时,不需要创build一个类似的button,而应该设置一个现有的button的状态。 看到这个问题的答案对于一些可能的方式来处理。
有一个简单的出路。 你可以欺骗button保持在最新的select状态。
创build一个可变数组,以保持button的选中状态
selectedButton = [[NSMutableArray alloc]init];//i've already defined the array at the .h file for (int i = 0; i<yourTableSize; i++) //yourTableSize = how many rows u got { [selectedButton addObject:@"NO"]; }
在tableviewcell方法中,声明你的button并设置它,以便引用可变arrays来设置它的选中状态
static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if(cell == nil) { cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil]; } UIImage *img = [UIImage imageNamed:@"btn_unselected.png"]; UIButton *toggleButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, img.size.width, img.size.height)]; [toggleButton setImage:img forState:UIControlStateNormal]; img = [UIImage imageNamed:@"btn_selected.png"]; [toggleButton setImage:img forState:UIControlStateSelected]; [toggleButton setTag:indexPath.row+100];//set the tag whichever way you wanted it, i set it this way so that the button will have tags that is corresponding with the table's indexpath.row [toggleButton addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside]; [cell.contentView addSubview:toggleButton]; //and now we set the button's selected state, everytime the table reuse/redraw the cell the button will set it's selected state according to the array if([[selectedButton objectAtIndex:indexPath.row]isEqualToString:@"NO"]) { [toggleButton setSelected:NO]; } else { [toggleButton setSelected:YES]; } return cell;
最后创buildbutton按下时触发button的方法,改变它的select状态
-(void)buttonPressed:(UIButton*)sender { int x = sender.tag - 100; //get the table's row if([sender isSelected]) //if the button is selected, deselect it, and then replace the "YES" in the array with "NO" { [selectedButton replaceObjectAtIndex:x withObject:@"NO"]; [sender setSelected:NO]; } else if (![sender isSelected]) //if the button is unselected, select it, and then replace the "NO" in the array with "YES" { [selectedButton replaceObjectAtIndex:x withObject:@"YES"]; [sender setSelected:YES]; } }
这是无效的(至less不是如果你想比较string我的内容,而不是地址):
if (myRating == @"9")
尝试这个:
if ([myRating isEqualToString:@"9"])
和注意到多个button创build+1 yuji。