美文网首页
iOS cell全选、多选、删除、标记已读、点赞、购物车结算等

iOS cell全选、多选、删除、标记已读、点赞、购物车结算等

作者: iOS_July | 来源:发表于2019-04-18 11:46 被阅读0次
  • 写在前边吧,自己太菜了,花了前前后后差不多一天多时间才完全弄清楚(掉坑了~),这玩意儿必须记录一下(篇幅不是很大,逻辑较绕,建议静得下来再食用)
示例.gif

需求:

需求
如图所示(后悔自己当时没画图,走入误区!吸取教训了....),cell中的button对应了这几种情况,底部选择View全选、清空、标记已读三种逻辑。

一、思考

  • 首先,别去想什么禁止tableView复用,这个想法很low,而且很危险、直接不成立,跳过!
  • 其次、参考网上很多的点赞效果实现,修改对应model数据,刷新UI即可,逻辑上是这样的,成立。
  • 确定好方向后,开始动工分析,cell中,确定自己按钮能够达到效果,需要建立的模型数据情况(这句话可能有点绕,接下来我举例说明)

二、思路讲解

tip1:点赞逻辑(较简单)
  • 1、假如,你就是实现点赞逻辑,那么只需要在模型里建立一个按钮是否选中的BOOL就OK了。
/** 按钮是否选中状态*/
@property (nonatomic,assign)BOOL selected;
  • 2、在cell中,模型赋值的方法里,让对应的按钮的选中状态 = model.selected 。
self.selectedBtn.selected = model.selected;
  • 3、在VC中,利用cell的按钮block、或者自定义协议里,取得cell对应在tableView数据源 中的 model数据,通过block、协议传递过来的按钮是否选中的selected BOOL值来改变model里的selected
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
EHSMessageModel *model = self.dataList[indexPath.row];
model.selected = selected;
  • 4、刷新UI,发送点赞(取消点赞)的请求
tip2:多选、全选进行删除、购物车结算、标记已读等逻辑(较复杂)
  • 网上也有很多教程,但大多数都是使其处于编辑状态,这并不符合我的需求(如果你的业务需求也是处于 编辑状态 的情况,你可以选择不用继续看接下来的内容,直接跳过我去做自己的逻辑)

  • 1、依旧是建立模型数据--BOOL

@property (nonatomic,assign)BOOL selected;
  • 2、在cell中,使按钮选中状态 对应模型数据
self.selectedBtn.selected = model.selected;
  • 3、在VC中,初始化 删除数据的Arr结算数据的Arr已读数据的Arr等,用来在全选、多选、单选后,装载对应操作的数据。

  • 4、在VC中,利用cell的按钮block、或者自定义协议里,取得cell对应在tableView数据源 中的 model数据,通过block、协议传递过来的按钮是否选中的selected BOOL值,来改变model里的selected。(主要是对要操作的数据做相应更改)

cell.selectBtnClick = ^(BOOL isSelected) {
//1、取得对应模型
        BuyCarModel *model = _weakSelf.carListArr[indexPath.row];
//2、改变模型BOOL值
        model.isSelected = isSelected;
//3、按钮选中状态对应的操作
        if (isSelected) {
//这里是以购物车结算为例子
            global_jiesuanNum += [model.num intValue];
            global_totalPrice += [model.num intValue] * [model.shop_price floatValue];
            _weakSelf.totalPriceLbl.text = [NSString stringWithFormat:@"¥%.2f", global_totalPrice];
            [_weakSelf.jiesuanBtn setTitle:[NSString stringWithFormat:@"结算(%d)", global_jiesuanNum] forState:UIControlStateNormal];
//这里是将修改后的模型数据添加到对应操作的数组中
            [_weakSelf.jiesuanArr addObject:model];
            [_weakSelf.collectOrDeleteArr addObject:model.car_id];
        } else {//3.1、按钮对应取消选中的操作
//取消结算的操作
            global_jiesuanNum -= [model.num intValue];
            global_totalPrice -= [model.num intValue] * [model.shop_price floatValue];
            _weakSelf.totalPriceLbl.text = [NSString stringWithFormat:@"¥%.2f", global_totalPrice];
            [_weakSelf.jiesuanBtn setTitle:[NSString stringWithFormat:@"结算(%d)", global_jiesuanNum] forState:UIControlStateNormal];
//同样的,对应移除模型数据
            [_weakSelf.jiesuanArr removeObject:model];
            [_weakSelf.collectOrDeleteArr removeObject:model.car_id];
        }
        // 判断 如果有一个cell未被选中,全选按钮取消被选中
        for (BuyCarModel *model in self.carListArr) {
            if (!model.isSelected) {
                _bottomSelectBtn.selected = NO;
            }
        }
        // 判断 如果所有的cell被选中,全选按钮也被选中
        int selectCount = 0;
        for (BuyCarModel *model in self.carListArr) {
            if (model.isSelected) {
                selectCount ++;
            }
        }
        if (selectCount == self.carListArr.count) {
            _bottomSelectBtn.selected = YES;
        }
    };
  • 5、对应全选、删除、标记已读、结算等 按钮的响应事件(tag推荐用枚举,这里例子主要表明对应逻辑和操作过程)
- (IBAction)bottomBtnClick:(UIButton *)button {
    if (button.tag == 1) { // 全选事件
        button.selected = !button.selected;
        if (button.selected) {
            self.bottomSelectBtn.selected = YES;
            int i = 0;
            float totalCount = 0;
            for (BuyCarModel *model in self.carListArr) {
                model.isSelected = YES;
                float total = [model.num intValue]  * [model.shop_price floatValue];
                totalCount += total;
                i += [model.num intValue];
                
                [self.jiesuanArr addObject:model];
                [self.collectOrDeleteArr addObject:model.car_id];
            }
            global_jiesuanNum = I;
            global_totalPrice = totalCount;
            [_jiesuanBtn setTitle:[NSString stringWithFormat:@"结算(%d)", i] forState:UIControlStateNormal];
            _totalPriceLbl.text = [NSString stringWithFormat:@"¥%.2f", totalCount];
            
            // 刷新表格
            [self.tableView reloadData];
        } else {
            self.bottomSelectBtn.selected = NO;
            for (BuyCarModel *model in self.carListArr) {
                model.isSelected = NO;
                
                [self.jiesuanArr removeObject:model];
                [self.collectOrDeleteArr removeObject:model.cat_id];
            }
            [_jiesuanBtn setTitle:@"结算(0)" forState:UIControlStateNormal];
            _totalPriceLbl.text = @"¥0";
            global_jiesuanNum = 0;
            global_totalPrice = 0;
            // 刷新表格
            [self.tableView reloadData];
        }
    } else if (button.tag == 2) { //结算事件
        if (![_jiesuanBtn.titleLabel.text isEqualToString:@"结算(0)"]) {
            ConfirmOrderViewController *confirmOrderVC = [[ConfirmOrderViewController alloc] init];
            confirmOrderVC.buyStatus = @"1";
            confirmOrderVC.buyCarArr = self.jiesuanArr;
            [self.navigationController pushViewController:confirmOrderVC animated:YES];
        }
    } else if (button.tag == 3) { //删除事件
        if (self.collectOrDeleteArr.count == 0) {
            [SVProgressHUD showErrorWithStatus:@"请选择删除数据"];
        } else {
            // 删除选中的物品
            [JXTAlertTools showAlertWith:self title:@"确定删除当前选定的商品?" message:nil callbackBlock:^(NSInteger btnIndex) {
                if (btnIndex == 1) {
//                    [self getCarDelData];
                }
            }  cancelButtonTitle:@"取消" destructiveButtonTitle:@"确定" otherButtonTitles:nil, nil];
        }
    }else if (button.tag == 4) { // 添加收藏
        if (self.collectOrDeleteArr.count == 0) {
            [SVProgressHUD showErrorWithStatus:@"未选择删除数据"];
        }
    }
}

三、讲讲自己是怎么掉坑的(可不看)

因为,我的需求里,已读信息和未读信息,均可被选中,未读信息选中后,变为已读,问题来了,已读信息,选中后呢?变成什么?也是已读吗?
我先假使已读信息 选中后模型数据由原先的@"1"变为@"2",未读模型数据由原先的@"0"变为@"1",再取消选中的时候再对应还原。。。。
表面上没什么问题,可实际上,当我先选择第一行未读,那么 第一行原本的@"0"变为@"1",但是我再全选,那么 第一行原本的@"1"变为@"2",其他的cell原本的@"0"变为@"1"@"1"变为 @"2",也就是说,现在我还原不了第一行到@"0",只能把它变为@"1",这样就出现bug了,根本就还原不了这种情况下的未读信息。

四、怎么达到最终需求的(爬坑)

  • 很简单,因为,我本身不只一个 选中与不选中的情况(这种情况按照上面的介绍,完全可以解决),而是分 已读选中未选中、未读选中未选中的情况,所以一条模型数据是否选中,已经无法满足,增加一条 原始cell是否已读的模型数据,判断的时候,对应的在逻辑里,加入是否原始已读。就行了...行了...了...(可怜我郁闷了很久...)
/** 按钮是否选中状态*/
@property (nonatomic,assign)BOOL selected;
/** 是否选原来就是已读   状态*/
@property (nonatomic,assign)BOOL isOriginalRead;
  • 结语:我是参照的华之曦写的这篇文章,感谢开源精神,没上传Demo,如有什么疑问,可评论留言或者私信。期待成长...

相关文章

网友评论

      本文标题:iOS cell全选、多选、删除、标记已读、点赞、购物车结算等

      本文链接:https://www.haomeiwen.com/subject/xtkzwqtx.html