1.说起tableview这个控件真是个老生常谈的东西,这个看似平凡的控件里面竟然也可以用到很多的知识。
2.从最基本的说起那就是cell 的重用机制了。当我们初次进入界面时,界面内用N个cell,这N个cell是新alloc的这个大家都知道,然后当我们滑动cell 的时候就会引用到我们的重用机制了。
3.在cell上的控件也是多种多样,例如我们加载了100多行,每一行都有数个图片,这时候如果我们不对内存做优化的话就会引起界面卡顿。
4.cell上如果有需要用户交互的控件的时候也是个麻烦的事,例如我们需要有个选中的按钮需要用户标示处已经选择了这个cell,如果我们不做处理那么当我们滑动cell的时候就会发现cell消失再出现以后我们的选中效果不见了。
5.说了这么多就是想声明这个重用机制的问题,我们既要得到点击的某一个cell里面的按钮又要将选中的效果保存到数据中,方便于重用cell时不会将我们的选中效果给丢失。
好了不多说,直接上代码。
- (UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *ShoppingCartCellIdentifier = @"ShoppingCartCellIdentifier";
MSShoppingCartTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ShoppingCartCellIdentifier];

if (cell == nil) {
    cell = [[MSShoppingCartTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ShoppingCartCellIdentifier];
}

cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.indexPath = indexPath;
cell.delegate=self;
//取出网络数据
shopModule = self.dataArray[indexPath.section];
goodsModule =[shopModule.detailList objectAtIndex:indexPath.row];
NSInteger isSelected =goodsModule.isSelected;
if (isSelected == 1)
{
    [cell.productStatusButton setSelected:YES];
}
else
{
    [cell.productStatusButton setSelected:NO];
}

return cell;

}

  • (UIView )tableView:(UITableView )tableView viewForHeaderInSection:(NSInteger)section{
    static NSString * identy = @”headFoot”;
    UITableViewHeaderFooterView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:identy];
    if (headerView == nil) {
    headerView = [[UITableViewHeaderFooterView alloc]initWithReuseIdentifier:identy];
self.shoppingCartHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 45)];

[headerView addSubview:_shoppingCartHeaderView];

}

_shoppingCartHeaderView.backgroundColor=[UIColor whiteColor]; 
 UIButton *productGroupStatusButton = [[UIButton alloc] init];[productGroupStatusButton setImage:[UIImage imageNamed:@”product_Unchecked_icon”] forState:UIControlStateNormal]; 
 [productGroupStatusButton setImage:[UIImage imageNamed:@”product_checked_icon”] forState:UIControlStateSelected]; 
 [productGroupStatusButton addTarget:self action:@selector(clickProductGroupStatusButton:) forControlEvents:UIControlEventTouchUpInside]; 
 productGroupStatusButton.tag = section+10000;[_shoppingCartHeaderView addSubview:productGroupStatusButton];
[productGroupStatusButton mas_makeConstraints:^(MASConstraintMaker *make) { 
 make.centerY.equalTo(_shoppingCartHeaderView.mas_centerY); 
 make.left.equalTo(_shoppingCartHeaderView.mas_left).offset(13); 
 }];UIButton tmpBtn = (UIButton )[_shoppingCartHeaderView viewWithTag:section+10000];
if ([self.groupSelectedStatusSet containsObject:[NSNumber numberWithInteger:section]]) 
 { 
 [tmpBtn setSelected: YES];} 
 else 
 { 
 [tmpBtn setSelected: NO]; 
 }// 创建控件 
 UIImageView *headImageView = [[UIImageView alloc] init]; 
 headImageView= [[UIImageView alloc] init]; 
 headImageView.image = [UIImage imageNamed:@”user_header_default_icon”]; 
 headImageView.layer.cornerRadius = 15; 
 headImageView.layer.masksToBounds = YES; 
 headImageView.userInteractionEnabled = YES;UILabel *channelShopLabel = [[UILabel alloc] init]; 
 channelShopLabel = [[UILabel alloc] init]; 
 channelShopLabel.text = @”Channel Shop”; 
 channelShopLabel.font = [UIFont systemFontOfSize:15.0f]; 
 channelShopLabel.textColor = [UIColor blackColor]; 
 channelShopLabel.textAlignment = NSTextAlignmentLeft;UIView *topLineView = [[UIView alloc] init]; 
 topLineView.backgroundColor = [UIColor colorWithRed:216.0/255.0f green:216.0/255.0f blue:216.0/255.0f alpha:1.0f];UIView *bottomLineView = [[UIView alloc] init]; 
 bottomLineView.backgroundColor = [UIColor colorWithRed:216.0/255.0f green:216.0/255.0f blue:216.0/255.0f alpha:1.0f];// 添加控件 
 [_shoppingCartHeaderView addSubview:headImageView]; 
 [_shoppingCartHeaderView addSubview:channelShopLabel]; 
 [_shoppingCartHeaderView addSubview:topLineView]; 
 [_shoppingCartHeaderView addSubview:bottomLineView];// 自动布局 
 [headImageView mas_makeConstraints:^(MASConstraintMaker *make) { 
 make.left.equalTo(productGroupStatusButton.mas_right).offset(17); 
 make.centerY.equalTo(_shoppingCartHeaderView.mas_centerY); 
 make.height.equalTo(@30); 
 make.width.equalTo(@30); 
 }];[channelShopLabel mas_makeConstraints:^(MASConstraintMaker *make) { 
 make.left.equalTo(headImageView.mas_right).offset(8); 
 make.centerY.equalTo(_shoppingCartHeaderView.mas_centerY); 
 make.width.equalTo(@200); 
 }];[topLineView mas_makeConstraints:^(MASConstraintMaker *make) { 
 make.left.equalTo(_shoppingCartHeaderView.mas_left); 
 make.right.equalTo(_shoppingCartHeaderView.mas_right); 
 make.top.equalTo(_shoppingCartHeaderView.mas_top); 
 make.height.equalTo(@1); 
 }];[bottomLineView mas_makeConstraints:^(MASConstraintMaker *make) { 
 make.left.equalTo(_shoppingCartHeaderView.mas_left); 
 make.right.equalTo(_shoppingCartHeaderView.mas_right); 
 make.bottom.equalTo(_shoppingCartHeaderView.mas_bottom); 
 make.height.equalTo(@1); 
 }];return _shoppingCartHeaderView; 
 }

pragma mark - clickproductAllStatusButton

//全选
- (void)clickProductAllStatusButton:(UIButton *)sender {

sender.selected = !sender.selected;
if (sender.selected) {
    //修改当前section下的isSelected
    [self reSetSelectedProductWithReplaceType:SelectedAll WithReplaceSection:0 WithReplaceCell:0 WithSetBool:1];
}
else
{
    //修改当前section下的isSelected
    [self reSetSelectedProductWithReplaceType:SelectedAll WithReplaceSection:0 WithReplaceCell:0 WithSetBool:0];
}

}

//选中section(某个商家) 
 - (void)clickProductGroupStatusButton:(UIButton *)sender 
 {
sender.selected = !sender.selected;
if (sender.selected == YES)
{
    //修改当前section下的isSelected
    [self reSetSelectedProductWithReplaceType:SelectedSection WithReplaceSection:sender.tag-10000 WithReplaceCell:0 WithSetBool:1];
}
else
{
    //修改当前section下的isSelected
    [self reSetSelectedProductWithReplaceType:SelectedSection WithReplaceSection:sender.tag-10000 WithReplaceCell:0 WithSetBool:0];
}

}

//选中单个商品 
 -(void)shoppingCartTableViewCellDelegate:(NSIndexPath *)indexPath status:(BOOL)status 
 { 
 [self reSetSelectedProductWithReplaceType:SelectedCell WithReplaceSection:indexPath.section WithReplaceCell:indexPath.row WithSetBool:status]; 
 }

pragma mark-重置是否选中该商品

typedef enum 
 { 
 SelectedAll, 
 SelectedSection, 
 SelectedCell 
 }REPLACEGROUP; 
 -(void)reSetSelectedProductWithReplaceType:(REPLACEGROUP)type WithReplaceSection:(NSInteger)section WithReplaceCell:(NSInteger)cell WithSetBool:(NSInteger)selected 
 { 
 //声明新的转换容器 
 NSMutableArray *newStoreArray = [[NSMutableArray alloc]initWithCapacity:0]; 
 static CGFloat totalMoney =0.0; 
 static NSInteger totalNum =0; 
 //根据修改的属性更新
switch (type) {
    case SelectedAll:
    {
        for (NSInteger j=0; j<_storeArray.count; j++) {
            NSDictionary *sectionDic= _storeArray[j];
            NSArray *detailList = sectionDic[@"detailList"];
            NSMutableArray *newDetailList = [[NSMutableArray alloc]initWithCapacity:0];
            for (NSInteger k=0; k<detailList.count; k++) {
                NSDictionary *cellDic = detailList[k];
                NSMutableDictionary *newCellDic = [[NSMutableDictionary alloc]initWithDictionary:cellDic];
                NSInteger oldStatus = [[cellDic objectForKey:@"isSelected"]integerValue];
                [newCellDic removeObjectForKey:@"isSelected"];
                [newCellDic setValue:[NSNumber numberWithInteger:selected] forKey:@"isSelected"];
                //界面底部计算数据
                if (selected==1 && oldStatus==0) {
                    ++totalNum;
                    totalMoney +=[[newCellDic objectForKey:@"sum"]floatValue];
                    [self.groupSelectedStatusSet addObject:[NSNumber numberWithInteger:j]];
                }else if(selected ==0 && oldStatus ==1)
                {
                    --totalNum;
                    totalMoney -=[[newCellDic objectForKey:@"sum"]floatValue];
                    [self.groupSelectedStatusSet removeObject:[NSNumber numberWithInteger:j]];
                }
                else if (selected && oldStatus)
                {
                    [self.groupSelectedStatusSet addObject:[NSNumber numberWithInteger:j]];
                }
                else if (selected == 0 && oldStatus ==0)
                {
                    [self.groupSelectedStatusSet removeObject:[NSNumber numberWithInteger:j]];
                }
                [newDetailList addObject:newCellDic];
            }
            NSMutableDictionary *newsectionDic = [[NSMutableDictionary alloc]initWithDictionary:sectionDic];
            [newsectionDic removeObjectForKey:@"detailList"];
            [newsectionDic setObject:newDetailList forKey:@"detailList"];
            [newStoreArray addObject:newsectionDic];
        }

    }break;
    case SelectedSection:
    {
        for (NSInteger j=0; j<_storeArray.count; j++) {
            NSDictionary *sectionDic= _storeArray[j];
            NSArray *detailList = sectionDic[@"detailList"];
            NSMutableArray *newDetailList = [[NSMutableArray alloc]initWithCapacity:0];
            for (NSInteger k=0; k<detailList.count; k++) {
                NSDictionary *cellDic = detailList[k];
                NSInteger oldStatus = [[cellDic objectForKey:@"isSelected"]integerValue];
                NSMutableDictionary *newCellDic = [[NSMutableDictionary alloc]initWithDictionary:cellDic];
                //当选中的section和循环到的j相同时修改section的isSelected
                if (section == j) {
                    [newCellDic removeObjectForKey:@"isSelected"];
                    [newCellDic setValue:[NSNumber numberWithInteger:selected] forKey:@"isSelected"];
                    //界面底部计算数据
                    if (selected && oldStatus==0) {
                        ++totalNum;
                        totalMoney +=[[newCellDic objectForKey:@"sum"]floatValue];
                        [self.groupSelectedStatusSet addObject:[NSNumber numberWithInteger:j]];
                    }else if(selected ==0 && oldStatus ==1)
                    {
                        --totalNum;
                        totalMoney -=[[newCellDic objectForKey:@"sum"]floatValue];
                        [self.groupSelectedStatusSet removeObject:[NSNumber numberWithInteger:j]];
                    }
                    else if (selected && oldStatus)
                    {
                        [self.groupSelectedStatusSet addObject:[NSNumber numberWithInteger:j]];
                    }
                    else if (selected == 0 && oldStatus ==0)
                    {
                        [self.groupSelectedStatusSet removeObject:[NSNumber numberWithInteger:j]];
                    }
                }
                [newDetailList addObject:newCellDic];
            }
            NSMutableDictionary *newsectionDic = [[NSMutableDictionary alloc]initWithDictionary:sectionDic];
            [newsectionDic removeObjectForKey:@"detailList"];
            [newsectionDic setObject:newDetailList forKey:@"detailList"];
            [newStoreArray addObject:newsectionDic];
        }

    }break;
    case SelectedCell:
    {
        for (NSInteger j=0; j<_storeArray.count; j++) {
            NSDictionary *sectionDic= _storeArray[j];
            NSArray *detailList = sectionDic[@"detailList"];
            NSMutableArray *newDetailList = [[NSMutableArray alloc]initWithCapacity:0];
            for (NSInteger k=0; k<detailList.count; k++) {
                NSDictionary *cellDic = detailList[k];
                NSInteger oldStatus = [[cellDic objectForKey:@"isSelected"]integerValue];
                NSMutableDictionary *newCellDic = [[NSMutableDictionary alloc]initWithDictionary:cellDic];
                //当选中的section和循环到的j和k相同时修改的isSelected
                if (section == j && k==cell) {
                    [newCellDic removeObjectForKey:@"isSelected"];
                    [newCellDic setValue:[NSNumber numberWithInteger:selected] forKey:@"isSelected"];
                    //界面底部计算数据
                    if (selected && oldStatus==0) {
                        ++totalNum;
                        totalMoney +=[[newCellDic objectForKey:@"sum"]floatValue];
                    }else if(selected ==0 && oldStatus ==1)
                    {
                        --totalNum;
                        totalMoney -=[[newCellDic objectForKey:@"sum"]floatValue];
                    }
                }
                [newDetailList addObject:newCellDic];
            }
            NSMutableDictionary *newsectionDic = [[NSMutableDictionary alloc]initWithDictionary:sectionDic];
            [newsectionDic removeObjectForKey:@"detailList"];
            [newsectionDic setObject:newDetailList forKey:@"detailList"];
            [newStoreArray addObject:newsectionDic];
        }


    }break;
    default:
        break;
}


_storeArray =nil;
_storeArray =newStoreArray;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
NSString *totalMoneyStr = [formatter stringFromNumber:[NSNumber numberWithFloat:totalMoney]];
self.productTotalPriceLabel.attributedText =[self setRedMoneyLableString:totalMoneyStr];
self.productAccountLabel.text =[NSString stringWithFormat: @"Account(%ld)",totalNum];
//清空列表数据加载新数据
[self.dataArray removeAllObjects];
for (NSInteger i=0; i<_storeArray.count; i++) {
    shopModule = [[ShoppingModule alloc]initWithSectionJsonString:_storeArray[i]];
    [self.dataArray addObject:shopModule];
}
[self.shoppingCartTableView reloadData];
}

//设置attribute字符串 
 -(NSAttributedString*)setRedMoneyLableString:(NSString*)moneyStr 
 { 
 NSDictionary *attribs = @{NSForegroundColorAttributeName:[UIColor blackColor],NSFontAttributeName:[UIFont systemFontOfSize:16.0f]}; 
 NSMutableAttributedString *attributedText = 
 [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@”Total:$%@”,moneyStr] attributes:attribs]; 
 // Red text attributes 
 //#5773de 
 UIColor *aColor = [UIColor redColor]; 
 [attributedText setAttributes:@{NSForegroundColorAttributeName:aColor,NSFontAttributeName:[UIFont boldSystemFontOfSize:16.0f]} range:NSMakeRange(6, 1)]; 
 return attributedText; 
 }

下面就是效果图

ios cell复用修改一个cell导致其他cell发生改变 cell复用问题_控件