操蛋的UITableView重用机制

来源:互联网 发布:七天网络组织代码登录 编辑:程序博客网 时间:2024/05/17 09:16

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值不同。

感觉自己的想法没有表达清楚,有什么问题直接留言。

原创粉丝点击