前言
由于前段时间现在项目中用到了购物车,花了点时间写了写,但是新版本居然砍掉了,于是又抽出来,写了个小demo,主要是逻辑的实现,基本应付大部分购物车需求,当然也可以完善一下,加上自己的需求!
个人感觉主要的逻辑就是选中问题,单个商品的选中,整个分区的选择,全选以及价格的计算。
界面有点丑了,没有图片,设置的随机色,主要看逻辑把!
下面贴部分代码----Controller中部分代码
1. UI部分
#pragma mark --------------------- UI ------------------
- (void)setSubViews {
CGFloat tabBarHeight = kTabBarHeight;
if(self.isSubPage) {
tabBarHeight = kTabBarHeight-49;
}else{
tabBarHeight = kTabBarHeight;
}
self.myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, kNavBarHeight, kScreenWidth, kScreenHeight-kNavBarHeight-tabBarHeight - kBottomHeight) style:(UITableViewStyleGrouped)];
self.myTableView.dataSource = self;
self.myTableView.delegate = self;
[self.view addSubview:self.myTableView];
self.myTableView.tableFooterView = [[UIView alloc] init];
[self.myTableView registerNib:[UINib nibWithNibName:@"HBK_ShoppingCartCell"bundle:nil] forCellReuseIdentifier:@"HBK_ShoppingCartCell"];
[self.myTableView registerNib:[UINib nibWithNibName:@"HBK_ShoppingCartHeaderView"bundle:nil] forHeaderFooterViewReuseIdentifier:@"HBK_ShoppingCartHeaderView"];
self.bottomView = [[[NSBundle mainBundle] loadNibNamed:@"HBK_ShopppingCartBottomView"owner:nil options:nil] objectAtIndex:0];
self.bottomView.frame = CGRectMake(0, kScreenHeight - tabBarHeight - kBottomHeight, kScreenWidth, kBottomHeight);
//全选
[self clickAllSelectBottomView:self.bottomView];
[self.view addSubview:self.bottomView];
}
#pragma mark ------------------ ----
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
returnself.storeArray.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
HBK_StoreModel *storeModel = self.storeArray[section];
returnstoreModel.goodsArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
HBK_ShoppingCartCell *cell = [tableView dequeueReusableCellWithIdentifier:@"HBK_ShoppingCartCell"];
HBK_StoreModel *storeModel = self.storeArray[indexPath.section];
HBK_GoodsModel *goodsModel = storeModel.goodsArray[indexPath.row];
cell.goodsModel = goodsModel;
//把事件的处理分离出去
[self shoppingCartCellClickAction:cell storeModel:storeModel goodsModel:goodsModel indexPath:indexPath];
returncell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
returnkFit(100);
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
returnkFit(40);
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
returnCGFLOAT_MIN;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
HBK_ShoppingCartHeaderView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"HBK_ShoppingCartHeaderView"];
headerView.contentView.backgroundColor = [UIColor whiteColor];
HBK_StoreModel *storeModel = self.storeArray[section];
headerView.storeModel = storeModel;
//分区区头点击事件--- 把事件分离出去
[self clickSectionHeaderView:headerView andHBK_StoreModel:storeModel];
returnheaderView;
}
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
return@"删除";
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
returnYES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if(editingStyle == UITableViewCellEditingStyleDelete) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"确定删除?"message:nil preferredStyle:(UIAlertControllerStyleAlert)];
kWeakSelf(self);
[alert addAction:[UIAlertAction actionWithTitle:@"是"style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
kStrongSelf(self);
[self deleteGoodsWithIndexPath:indexPath];
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"否"style:(UIAlertActionStyleDefault) handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
}
}
2. Action逻辑处理
#pragma mark ------------------------Action 逻辑处理-----------------------------
/**
判断分区有没有被全选
@param section 分区坐标
*/
- (void)judgeIsSelectSection:(NSInteger)section {
HBK_StoreModel *storeModel = self.storeArray[section];
BOOL isSelectSection = YES;
//遍历分区商品, 如果有商品的没有被选择, 跳出循环, 说明没有全选
for(HBK_GoodsModel *goodsModelinstoreModel.goodsArray) {
if(goodsModel.isSelect == NO) {
isSelectSection = NO;
break;
}
}
//全选了以后, 改变一下选中状态
HBK_ShoppingCartHeaderView *headerView = (HBK_ShoppingCartHeaderView *)[self.myTableView headerViewForSection:section];
headerView.isClick = isSelectSection;
storeModel.isSelect = isSelectSection;
}
/**
是否全选
*/
- (void)judgeIsAllSelect {
NSInteger count =0;
//先遍历购物车商品, 得到购物车有多少商品
for(HBK_StoreModel *storeModelinself.storeArray) {
count += storeModel.goodsArray.count;
}
//如果购物车总商品数量 等于 选中的商品数量, 即表示全选了
if(count == self.selectArray.count) {
self.bottomView.isClick = YES;
}else{
self.bottomView.isClick = NO;
}
}
/**
计算价格
*/
- (void)countPrice {
double totlePrice =0.0;
for(HBK_GoodsModel *goodsModelinself.selectArray) {
double price = [goodsModel.realPrice doubleValue];
totlePrice += price * [goodsModel.count integerValue];
}
self.bottomView.allPriceLabel.text = [NSString stringWithFormat:@"合计 ¥%.2f", totlePrice];
}
3、Action点击事件的处理
#pragma mark ----------- Action 点击事件 --------------------
/**
区头点击----选中某个分区/取消选中某个分区
@param headerView 分区
@param storeModel 分区模型
*/
- (void)clickSectionHeaderView:(HBK_ShoppingCartHeaderView *)headerView andHBK_StoreModel:(HBK_StoreModel *)storeModel {
headerView.ClickBlock = ^(BOOL isClick) {
storeModel.isSelect = isClick;
if(isClick) {//选中
NSLog(@"选中");
for(HBK_GoodsModel *goodsModelinstoreModel.goodsArray) {
goodsModel.isSelect = YES;
if(![self.selectArray containsObject:goodsModel]) {
[self.selectArray addObject:goodsModel];
}
}
}else{//取消选中
NSLog(@"取消选中");
for(HBK_GoodsModel *goodsModelinstoreModel.goodsArray) {
goodsModel.isSelect = NO;
if([self.selectArray containsObject:goodsModel]) {
[self.selectArray removeObject:goodsModel];
}
}
}
[self judgeIsAllSelect];
[self.myTableView reloadData];
[self countPrice];
};
}
/**
全选点击---逻辑处理
@param bottomView 底部的View
*/
- (void)clickAllSelectBottomView:(HBK_ShopppingCartBottomView *)bottomView {
kWeakSelf(self);
bottomView.AllClickBlock = ^(BOOL isClick) {
kStrongSelf(self);
for(HBK_GoodsModel *goodsModelinself.selectArray) {
goodsModel.isSelect = NO;
}
[self.selectArray removeAllObjects];
if(isClick) {//选中
NSLog(@"全选");
for(HBK_StoreModel *storeModelinself.storeArray) {
storeModel.isSelect = YES;
for(HBK_GoodsModel *goodsModelinstoreModel.goodsArray) {
goodsModel.isSelect = YES;
[self.selectArray addObject:goodsModel];
}
}
}else{//取消选中
NSLog(@"取消全选");
for(HBK_StoreModel *storeModelinself.storeArray) {
storeModel.isSelect = NO;
}
}
[self.myTableView reloadData];
[self countPrice];
};
bottomView.AccountBlock = ^{
NSLog(@"去结算");
};
}
- (void)shoppingCartCellClickAction:(HBK_ShoppingCartCell *)cell
storeModel:(HBK_StoreModel *)storeModel
goodsModel:(HBK_GoodsModel *)goodsModel
indexPath:(NSIndexPath *)indexPath {
//选中某一行
cell.ClickRowBlock = ^(BOOL isClick) {
goodsModel.isSelect = isClick;
if(isClick) {//选中
NSLog(@"选中");
[self.selectArray addObject:goodsModel];
}else{//取消选中
NSLog(@"取消选中");
[self.selectArray removeObject:goodsModel];
}
[self judgeIsSelectSection:indexPath.section];
[self judgeIsAllSelect];
[self countPrice];
};
//加
cell.AddBlock = ^(UILabel *countLabel) {
NSLog(@"%@", countLabel.text);
goodsModel.count = countLabel.text;
[self.selectArray replaceObjectAtIndex:indexPath.row withObject:goodsModel];
[self countPrice];
};
//减
cell.CutBlock = ^(UILabel *countLabel) {
NSLog(@"%@", countLabel.text);
goodsModel.count = countLabel.text;
[self.selectArray replaceObjectAtIndex:indexPath.row withObject:goodsModel];
[self countPrice];
};
}
/**
删除某个商品
@param indexPath 坐标
*/
- (void)deleteGoodsWithIndexPath:(NSIndexPath *)indexPath {
HBK_StoreModel *storeModel = [self.storeArray objectAtIndex:indexPath.section];
HBK_GoodsModel *goodsModel = [storeModel.goodsArray objectAtIndex:indexPath.row];
[storeModel.goodsArray removeObjectAtIndex:indexPath.row];
[self.myTableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:(UITableViewRowAnimationFade)];
if(storeModel.goodsArray.count ==0) {
[self.storeArray removeObjectAtIndex:indexPath.section];
}
if([self.selectArray containsObject:goodsModel]) {
[self.selectArray removeObject:goodsModel];
[self countPrice];
}
NSInteger count =0;
for(HBK_StoreModel *storeModelinself.storeArray) {
count += storeModel.goodsArray.count;
}
if(self.selectArray.count == count) {
_bottomView.clickBtn.selected = YES;
}else{
_bottomView.clickBtn.selected = NO;
}
if(count ==0) {
//此处加载购物车为空的视图
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.myTableView reloadData];
});
}