********《MVC模式下的购物车》********
ViewController: 购物车界面
整个界面就是TableView + 底部结账栏View组成
以店铺为section:商店下的商品为row和店铺名称组成一个 section
定制段头的View 把section的全选按钮、点击商品、编辑的三个按钮全部装起来,里面点击的方法用代理的方法。
-(UIView*)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section;
这是加载自定义段头的代理方法。
建议使用Masonry进行cell适配
cell的创建就是和我们平常的一样,把要展示的样式代码编写或者xib都可以。再把数据源填充到我们所创建好的cell中和段头上。
使用masonry进行适配会省去我们要考虑的label换行及各类UI适配问题,切记在写约束时不要写高度。
创建好一个View添加在TableView的下方。View上写上全选及总金额等UI。每次我们选定的物品的增减都要调用该View赋值的方法,刷新金额等字段显示。
Cell:物品栏
创建两种cell,一个是正常的物品显示cell,另一个cell是编辑后的cell。
正常的cell:只说下label中划线的实现
//中划线
NSDictionary *attribtDic = @{NSStrikethroughStyleAttributeName: [NSNumber numberWithInteger:NSUnderlineStyleSingle]};
NSMutableAttributedString *attribtStr = [[NSMutableAttributedString alloc]initWithString:info[@"GoodsOldPrice"] attributes:attribtDic];
// 赋值
_Goods_OldPrice.attributedText = attribtStr;
编辑后的cell:
主要由三部分组成。商品数量 + 商品种类 + 删除
商品数量用的是第三方PPNumberButton,点击时改变model中该商品的实际数量;点击商品种类进行重新选择(方法未实现,原理一样);点击删除进行cell的删除及数据源的删除。
注释:这里的删除 及 修改 都是要对数据源进行修改在刷新的
Model:数据源的处理及购物车内各类按钮的判断
demo中的数据源我没有放到model中去处理,其实原理都一样,我把判断各类按钮的判断字段加到数据源中去了,如果用model模型的话,自己加上相对应的字段,并设置初始值。当进行model数据源的修改时,直接进行修改。
这是一种model处理方式,还有一种就是用JsonModel来处理,一层层的写下来,原理一样。
购物车逻辑及实现总结
逻辑整理:当我们把有购买意向的物品加到购物车后,我们在购物车中调用接口获取购物车中的物品信息。数据源格式大概是(感觉不怎么对,但是能理解就行)
[
{@“店铺信息”:[@{物品信息},@{物品信息},@{物品信息}]}, -------》组一
{@"店铺信息":[@{物品信息}]}, -------》组二
{@”店铺信息“:[@{物品信息},@{物品信息}]} -------》组三
]
把数据源用model装起来,把数据填充到tableview中去。
1.单个商品的选择、单个店铺内所有商品的选择、结账栏下的全选
如果做得很简单的话,可以直接用系统的单选和全选方法。
最重要的两句 !!!!
TableDemo.editing=YES; 编辑状态
TableDemo.allowsMultipleSelectionDuringEditing=YES; 编辑的时候多选
cell.tintColor= [UIColorredColor]; 选中后的颜色
选中和取消选中
-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath 选中
-(void)tableView:(UITableView*)tableView didDeselectRowAtIndexPath:(NSIndexPath*)indexPath 取消选中
如果不用系统的话,则利用model来进行单选和全选的操作,选中和取消选中对model中的判断字段进行修改,刷新当前cell或者section。
//一个section刷新
NSIndexSet *indexSet=[[NSIndexSet alloc]initWithIndex:section];
[tableview reloadSections:indexSet
withRowAnimation:UITableViewRowAnimationAutomatic];
//一个cell刷新
NSIndexPath *indexPath=[NSIndexPath indexPathForRow:row inSection:section];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath,nil] withRowAnimation:UITableViewRowAnimationNone];
这里需要注意的是,每次单选和全选的时候,需要对底部结账栏进行数据的刷新,并且单选完整组后,需要对section上的按钮进行选中状态变化,当选中section时,同样需要对section下的row进行选中状态,如果全部商品选中,还得需要改变结账栏的状态。(这里其实不难,无非就是对model中各类字段进行改变,再刷新,同时判断选中数量的多少来进行按钮的状态变换)
2.删除单个商品
删除的话就相对容易了,直接对数据源删除对应的row,当只剩一个后,删除该数据后,记得删除该组section不然报错。删除后及时刷新底部结账栏金额显示。
3.编辑section
点击编辑按钮,修改model,展示编辑cell。编辑按钮上放了数量计数器、商品的信息、删除。
计数器:用到的是好友的一个库PPNumberButton 喜欢的大家可以去玩玩。点击后用代理方法把数量的变化跟新model。
商品信息:点击对商品的信息进行重新选择,同样修改数据源。
删除:代理出来进行model的修改。
因为这里用的是假数据,所以进行的都是对数据源的修改,正常情况下,原理都一样,可以在次基础上,如果接口成功,就对本地数据进行修改,最后提交的信息会和后台匹配一次的,如果有问题,可以自己修改一下。
有小伙伴提出demo中没有下拉刷新,其实下拉刷新不影响该demo。不过加上效果更好。
谢谢“爱在巴黎梦醒时”该小伙伴。
demo的bug注释:
因为demo中判断section的全选和编辑的按钮都是放在每个section的第一个row中的,所以删除section的第一个row后,会有全选和编辑的固定bug出来。特此声明,该bug不影响主体逻辑,如次bug影响小伙伴对逻辑思路的学习,那我后面再重新组织数据源。
更新:
1.在刷新底部结账栏的总金额时,同时跟新全选状态。(及底部结账栏的UI都要统一刷新一次)
demo纯代码编写的,只隔离了部分模块,因为我也是拿来练练手,所以如果有需要,后续我会把购物车模块化。如果内容有不妥和臃肿的地方,大家可以提出来,我及时学习并修改。如果大家有意见的可以@我1804094055qq.com。如果觉得可以请大家不吝star。
https://github.com/zl645420646/-ZLShoppingCart