操蛋的UITableView重用机制
2013-08-14 19:12
288 查看
1,背景
你可能会遇见一下情况:使用UITableView加载数据,比如你的每一个cell上面有一个UITextField,当你在第一个cell的UITextField中写下了内容,开始下滑UITableView,你会发现由于UITableView重用机制的影响,你的第一个UITextField的值会发生变化,令人费解啊,抓狂!
之类的情况可能很多,下面咱们就总结一下发生这种情况的原因,针对这种原因,咱们找到对应的解决办法。
2,用自己的话说UITableView的重用机制
当遇见这中情况的时候,我问过好多个ios程序员,他们多数的解决办法是直接不让它重用了,当然了,这样的话,表面上确实解决了问题,但是却给自己的程序带来了很大的隐患。我们做东西,应该去想着做最好的东西出来,不能这样草草的应付。好了,言归正传。
所谓重用机制,就是模板共用一套,换的是内容。比如;view上显示七个cell,当第一个cell消失,第八个cell出现,那么第八个cell用的还是第一个cell,只不过他把第一个cell的内用换成了自己的。这就是重用的原理。问题就出现在他在换内容的时候,没换好,就出现了错误。
那么为什么会出现这种错误呢,为什么我们替换内容的时候根本就没有错,重用后还会出现错误呢?
不说废话 直接说我遇见的问题以及我的解决办法:
我的问题是右边的UITableView在上下滑动的时候按钮出现了重用,点过之后的按钮会发生变化,分成两个按钮,一个加菜按钮一个减菜按钮
当我点了第一个cell后,分裂成功,我将UITableView向下滑,却出现了第一个cell的按钮又变回了原型。
出现的原因:这个cell是我自定义的,这个按钮的状态是没有记录的,一次重用后他会和原来的状态一样。
解决办法:我是这样想的解决办法,之所以个重用是因为第一个和第八个没有特别的标注,我必须想一个区分第一个和第八个的属性,那么就有了indexpath.row,一位他们即使在重用这个值也不会相同,因此我们就用这个属性解决这个操蛋的问题。
好了,原理是这样,来看看我的解决代码吧;
[self.dataArr enumerateObjectsUsingBlock:^(NSDictionary * obj, NSUInteger idx, BOOL *stop) { [self.tempDotNumberDic setValue:[obj valueForKey:@"number"] forKey:[obj valueForKey:@"ProID"]]; }];
说明:dataArr是tableview的数据源,tempDotNumberDic是一个记录点菜份数的字典,他的key是点菜id(因为id是唯一的,这样可以区分开),他的value是点菜份数。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (tableView.tag == 100) { static NSString * strMark = @"cellMark"; DishesClassCell * cell = [tableView dequeueReusableCellWithIdentifier:strMark]; if (cell == nil) { cell = [[DishesClassCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strMark]; } if (indexPath.row<self.myClassArr.count) { cell.textContentLab.text = [[self.myClassArr objectAtIndex:indexPath.row] valueForKey:@"ClassName"]; } if (self.tempClassDic.count>0) { NSString * result = [self.tempClassDic valueForKey:[NSString stringWithFormat:@"%d",indexPath.row]]; if ([result isEqualToString:@"1"]) { cell.backgroundImageView.image = [UIImage imageNamed:@"DishClass06.png"]; } else { cell.backgroundImageView.image = [UIImage imageNamed:@"DishClass05.png"]; } } return cell; } NSString *str1 = [NSString stringWithFormat:@"cellmark%d",selectRow]; NSString * strMark1 = str1; //不停类别用不同的重用标示符,目的是为了不同分类同一位置的重用现象。 DishesDetailListCell * cell1 = [tableView dequeueReusableCellWithIdentifier:strMark1]; __block int dotNumber = 0; if (indexPath.row < self.myProArr.count) { __block NSString * proID; NSString * currID = [[self.myProArr objectAtIndex:indexPath.row] valueForKey:@"ProID"]; [self.dataArr enumerateObjectsUsingBlock:^(NSDictionary * obj, NSUInteger idx, BOOL *stop) { proID = [obj valueForKey:@"ProID"]; if ([currID isEqualToString:proID]) { dotNumber = [[[[DataBase selectNumberFromProId:[currID intValue]] objectAtIndex:0] valueForKey:@"number"] intValue]; } }]; } if (cell1 == nil) { cell1 = [[DishesDetailListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strMark1 andDotNumber:dotNumber]; } cell1.dishView.myLab.text = [NSString stringWithFormat:@"点%d份",dotNumber]; int resylt = [[self.tempDotNumberDic valueForKey:[[self.myProArr objectAtIndex:indexPath.row] valueForKey:@"ProID"]] intValue]; if (resylt == 0) { [cell1.dishView zeroState]; } else { [cell1.dishView initView:resylt]; } if (indexPath.row%2 == 0) { cell1.backgroundImageView.image = [UIImage imageNamed:@"5.png"]; } else { cell1.backgroundImageView.image = [UIImage imageNamed:@"6.png"]; } cell1.selectionStyle=UITableViewCellSelectionStyleNone; cell1.selectedBackgroundView = [[UIView alloc] initWithFrame:cell1.frame]; cell1.titleLab.text = [[self.myProArr objectAtIndex:indexPath.row] valueForKey:@"ProName"]; NSString * str = @"¥"; NSString * priceStr = [[self.myProArr objectAtIndex:indexPath.row] valueForKey:@"prices"]; cell1.priceLab.text = [str stringByAppendingFormat:@"%@",priceStr]; cell1.dishView.price = [priceStr doubleValue]; cell1.dishView.index = indexPath.row; [cell1.dishView.rightButton addTarget:self action:@selector(rightButtonClickEvent:) forControlEvents:UIControlEventTouchUpInside]; [cell1.dishView.leftButton addTarget:self action:@selector(leftButtonClickEvent:) forControlEvents:UIControlEventTouchUpInside]; [cell1.dishView.bigButton addTarget:self action:@selector(bigButtonClickEvent:) forControlEvents:UIControlEventTouchUpInside]; NSString * pathURL = ALL_URL; NSURL * url = [NSURL URLWithString:[pathURL stringByAppendingFormat:@"%@",[[self.myProArr objectAtIndex:indexPath.row] valueForKey:@"ProductImg"]]]; [cell1.leftImageView setImageWithURL:url placeholderImage:[UIImage imageNamed:ALL_NO_IMAGE]]; return cell1; }
看红色部分的代码,这点就是避免问题出现的办法,因为这个值是不同的cell值不同。
感觉自己的想法没有表达清楚,有什么问题直接留言。
相关文章推荐
- 操蛋的UITableView重用机制
- 解决UITableView中Cell重用机制问题
- ios tableView那些事 (十六) UITableView中Cell重用机制导致内容重复解决方法
- 解决UITableView中Cell重用机制导致内容出错的方法总结
- 解决UITableView中Cell重用机制导致内容出错的方法总结
- UITableView中cell的重用机制
- UITableView中Cell重用机制导致内容重复解决方法
- UITableView的重用机制原理
- UITableView的重用机制原理
- ios tableView那些事 (十六) UITableView中Cell重用机制导致内容重复解决方法
- 解决UITableView中cell重用机制
- UITableView的重用机制
- 解决UITableView中Cell重用机制导致内容出错的方法总结
- 解决UITableView中Cell重用机制导致内容出错的方法总结
- UITableView的重用机制(缓存机制)
- 【iOS沉思录】UITableView的重用机制与加载优化详解
- UITableView中Cell重用机制导致内容重复解决方法
- (iphone/ipad)关于uitableview自定义cell与重用机制探究
- UITableView中Cell重用机制导致内容重复解决方法
- iOS UITableView的重用机制