tableview重用和cell常见问题

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;
}
下面就是效果图
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值