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;
}
下面就是效果图