iOS实现电商购物车界面示例
先看界面效果图:
主要实现了商品的展示,并且可以对商品进行多选操作,以及改变商品的购买数量。与此同时,计算出,选中的总价格。
做此类型项目:要注意的:视图与数据要分离开来。视图的展现来源是数据模型层。所以我做的操作就是改变数据层的内容,在根据数据内容,去更新视图界面。
已下是具体实现思路与代码:
1. 实现步骤
- 在appdelegate.m中包含viewcontroller.h头文件,创建viewcontroller对象(vc),接着创建一个uinavigationcontroller对象(nvc)将vc设置为自己的根视图,最后设置self.window.rootviewcontroller为nvc。
- 在viewcontroller.m中创建一个全局的可变数组,并往里面添加表格需要的数据字典对象。
- 创建一个goodsinfomodel 类,继承于nsobject 类,用于做数据模型
- 创建一个mycustomcell 类 ,继承于uitableviewcell,自定义单元格类
- 在mycustomcell.m 类中,实现单元格的布局
- 在 viewcontroller.m 创建表格视图,并且创建表格尾部视图
- mycustomcell 类中定义协议,实现代理,完成加、减的运算。
- 在 viewcontroller.m 实现全选运算。
2. 代码实现
2.1 完成界面的导航栏创建
在appdelegate.m中包含viewcontroller.h头文件,创建viewcontroller对象(vc),接着创建一个uinavigationcontroller对象(nvc)将vc设置为自己的根视图,最后设置self.window.rootviewcontroller为nvc。
2.1.1 代码
在appdelegate.m的 - (bool)application:(uiapplication)application didfinishlaunchingwithoptions:(nsdictionary )launchoptions方法中实现以下代码(记得包含#import "viewcontroller.h"):
//创建窗口 self.window = [[uiwindow alloc]initwithframe:[uiscreen mainscreen].bounds]; self.window.backgroundcolor = [uicolor whitecolor]; //创建一个导航控制器,成为根视图 uinavigationcontroller *nav = [[uinavigationcontroller alloc]initwithrootviewcontroller:[viewcontroller new]]; self.window.rootviewcontroller = nav; //显示窗口 [self.window makekeyandvisible];
在viewcontroller.m 的 viewdidload 中去设置,导航栏标题
self.title = @"购物车"; //设置标题的属性样式等 [self.navigationcontroller.navigationbar settitletextattributes:@{nsforegroundcolorattributename : [uicolor blackcolor],nsfontattributename:[uifont systemfontofsize:23.0f]}];
2.2 创建一个模型类用于存放数据模型
创建一个goodsinfomodel 类 ,继承于 nsobject
实现代码如下: goodsinfomodel.h 中
@interface goodsinfomodel : nsobject @property(strong,nonatomic)nsstring *imagename;//商品图片 @property(strong,nonatomic)nsstring *goodstitle;//商品标题 @property(strong,nonatomic)nsstring *goodsprice;//商品单价 @property(assign,nonatomic)bool selectstate;//是否选中状态 @property(assign,nonatomic)int goodsnum;//商品个数 -(instancetype)initwithdict:(nsdictionary *)dict; @end goodsinfomodel.m 中 -(instancetype)initwithdict:(nsdictionary *)dict { if (self = [super init]) { self.imagename = dict[@"imagename"]; self.goodstitle = dict[@"goodstitle"]; self.goodsprice = dict[@"goodsprice"]; self.goodsnum = [dict[@"goodsnum"]intvalue]; self.selectstate = [dict[@"selectstate"]boolvalue]; } return self; }
2.3 创建设置表格数据的数据
在viewcontroller.m中创建一个全局的可变数组,并往里面添加表格需要的数据字典对象。
2.3.1 代码
在viewcontroller.m的- (void)viewdidload中实现以下代码(先在viewcontroller.m中声明infoarr对象)。代码如下
@interface viewcontroller ()<uitableviewdatasource,uitableviewdelegate,mycustomcelldelegate> { uitableview *_mytableview; float allprice; nsmutablearray *infoarr; } @property(strong,nonatomic)uibutton *allselectbtn; @property(strong,nonatomic)uilabel *allpricelab; @end --------------------------------------------------------------- //初始化数据 allprice = 0.0; infoarr = [[nsmutablearray alloc]init]; /** * 初始化一个数组,数组里面放字典。字典里面放的是单元格需要展示的数据 */ for (int i = 0; i<7; i++) { nsmutabledictionary *infodict = [[nsmutabledictionary alloc]init]; [infodict setvalue:@"img6.png" forkey:@"imagename"]; [infodict setvalue:@"这是商品标题" forkey:@"goodstitle"]; [infodict setvalue:@"2000" forkey:@"goodsprice"]; [infodict setvalue:[nsnumber numberwithbool:no] forkey:@"selectstate"]; [infodict setvalue:[nsnumber numberwithint:1] forkey:@"goodsnum"]; //封装数据模型 goodsinfomodel *goodsmodel = [[goodsinfomodel alloc]initwithdict:infodict]; //将数据模型放入数组中 [infoarr addobject:goodsmodel]; }
2.4 创建表格视图
代码如下:
/* 创建表格,并设置代理 / _mytableview = [[uitableview alloc]initwithframe:cgrectmake(0, 0, self.view.frame.size.width, self.view.frame.size.height) style:uitableviewstyleplain]; _mytableview.datasource = self; _mytableview.delegate = self; //给表格添加一个尾部视图 _mytableview.tablefooterview = [self creatfootview]; [self.view addsubview:_mytableview];
2.5 创建尾部视图
代码如下:
/* * 创建表格尾部视图 * * @return 返回一个uiview 对象视图,作为表格尾部视图/ -(uiview *)creatfootview{ uiview *footview = [[uiview alloc]initwithframe:cgrectmake(0, 0, self.view.frame.size.width, 150)]; //添加一个全选文本框标签 uilabel *lab = [[uilabel alloc]initwithframe:cgrectmake(self.view.frame.size.width - 150, 10, 50, 30)]; lab.text = @"全选"; [footview addsubview:lab]; //添加全选图片按钮 _allselectbtn = [uibutton buttonwithtype:uibuttontypecustom]; _allselectbtn.frame = cgrectmake(self.view.frame.size.width- 100, 10, 30, 30); [_allselectbtn setimage:[uiimage imagenamed:@"复选框-未选中"] forstate:uicontrolstatenormal]; [_allselectbtn addtarget:self action:@selector(selectbtnclick:) forcontrolevents:uicontroleventtouchupinside]; [footview addsubview:_allselectbtn]; //添加小结文本框 uilabel *lab2 = [[uilabel alloc]initwithframe:cgrectmake(self.view.frame.size.width - 150, 40, 60, 30)]; lab2.textcolor = [uicolor redcolor]; lab2.text = @"小结:"; [footview addsubview:lab2]; //添加一个总价格文本框,用于显示总价 _allpricelab = [[uilabel alloc]initwithframe:cgrectmake(self.view.frame.size.width - 100, 40, 100, 30)]; _allpricelab.textcolor = [uicolor redcolor]; _allpricelab.text = @"0.0"; [footview addsubview:_allpricelab]; //添加一个结算按钮 uibutton *settlementbtn = [uibutton buttonwithtype:uibuttontyperoundedrect]; [settlementbtn settitle:@"去结算" forstate:uicontrolstatenormal]; [settlementbtn settitlecolor:[uicolor whitecolor] forstate:uicontrolstatenormal]; settlementbtn.frame = cgrectmake(10, 80, self.view.frame.size.width - 20, 30); settlementbtn.backgroundcolor = [uicolor bluecolor]; [footview addsubview:settlementbtn]; return footview; }
2.6 创建自定义cell类,并实现初始化方法
创建一个类名叫mycustomcell继承uitableviewcell,在mycustomcell.m中实现重写的初始化方法。
2.6.1 代码:
mycustomcell.h :
#import <uikit/uikit.h> #import "goodsinfomodel.h" //添加代理,用于按钮加减的实现 @protocol mycustomcelldelegate <nsobject> -(void)btnclick:(uitableviewcell *)cell andflag:(int)flag; @end @interface mycustomcell : uitableviewcell @property(strong,nonatomic)uiimageview *goodsimgv;//商品图片 @property(strong,nonatomic)uilabel *goodstitlelab;//商品标题 @property(strong,nonatomic)uilabel *pricetitlelab;//价格标签 @property(strong,nonatomic)uilabel *pricelab;//具体价格 @property(strong,nonatomic)uilabel *goodsnumlab;//购买数量标签 @property(strong,nonatomic)uilabel *numcountlab;//购买商品的数量 @property(strong,nonatomic)uibutton *addbtn;//添加商品数量 @property(strong,nonatomic)uibutton *deletebtn;//删除商品数量 @property(strong,nonatomic)uibutton *isselectbtn;//是否选中按钮 @property(strong,nonatomic)uiimageview *isselectimg;//是否选中图片 @property(assign,nonatomic)bool selectstate;//选中状态 @property(assign,nonatomic)id<mycustomcelldelegate>delegate; //赋值 -(void)addthevalue:(goodsinfomodel *)goodsmodel; mycustomcell.m :先写一个宏定义宽度。#define width ([uiscreen mainscreen].bounds.size.width) -(instancetype)initwithstyle:(uitableviewcellstyle)style reuseidentifier:(nsstring *)reuseidentifier { if (self = [super initwithstyle:style reuseidentifier:reuseidentifier]) { //布局界面 uiview * bgview = [[uiview alloc]initwithframe:cgrectmake(5, 5, width-10, 95)]; bgview.backgroundcolor = [uicolor whitecolor]; //添加商品图片 _goodsimgv = [[uiimageview alloc]initwithframe:cgrectmake(5, 10, 80, 80)]; _goodsimgv.backgroundcolor = [uicolor greencolor]; [bgview addsubview:_goodsimgv]; //添加商品标题 _goodstitlelab = [[uilabel alloc]initwithframe:cgrectmake(90, 5, 200, 30)]; _goodstitlelab.text = @"afadsfa fa"; _goodstitlelab.backgroundcolor = [uicolor clearcolor]; [bgview addsubview:_goodstitlelab]; //促销价 _pricetitlelab = [[uilabel alloc]initwithframe:cgrectmake(90, 35, 70, 30)]; _pricetitlelab.text = @"促销价:"; _pricetitlelab.backgroundcolor = [uicolor clearcolor]; [bgview addsubview:_pricetitlelab]; //商品价格 _pricelab = [[uilabel alloc]initwithframe:cgrectmake(160, 35, 100, 30)]; _pricelab.text = @"1990"; _pricelab.textcolor = [uicolor redcolor]; [bgview addsubview:_pricelab]; //购买数量 _goodsnumlab = [[uilabel alloc]initwithframe:cgrectmake(90, 65, 90, 30)]; _goodsnumlab.text = @"购买数量:"; [bgview addsubview:_goodsnumlab]; //减按钮 _deletebtn = [uibutton buttonwithtype:uibuttontypecustom]; _deletebtn.frame = cgrectmake(180, 65, 30, 30); [_deletebtn setimage:[uiimage imagenamed:@"按钮-.png"] forstate:uicontrolstatenormal]; [_deletebtn addtarget:self action:@selector(deletebtnaction:) forcontrolevents:uicontroleventtouchupinside]; _deletebtn.tag = 11; [bgview addsubview:_deletebtn]; //购买商品的数量 _numcountlab = [[uilabel alloc]initwithframe:cgrectmake(210, 65, 50, 30)]; _numcountlab.textalignment = nstextalignmentcenter; [bgview addsubview:_numcountlab]; //加按钮 _addbtn = [uibutton buttonwithtype:uibuttontypecustom]; _addbtn.frame = cgrectmake(260, 65, 30, 30); [_addbtn setimage:[uiimage imagenamed:@"按钮+.png"] forstate:uicontrolstatenormal]; [_addbtn addtarget:self action:@selector(addbtnaction:) forcontrolevents:uicontroleventtouchupinside]; _addbtn.tag = 12; [bgview addsubview:_addbtn]; //是否选中图片 _isselectimg = [[uiimageview alloc]initwithframe:cgrectmake(width - 50, 10, 30, 30)]; [bgview addsubview:_isselectimg]; [self addsubview:bgview]; } return self; } /** * 给单元格赋值 * @param goodsmodel 里面存放各个控件需要的数值 */ -(void)addthevalue:(goodsinfomodel *)goodsmodel { _goodsimgv.image = [uiimage imagenamed:goodsmodel.imagename]; _goodstitlelab.text = goodsmodel.goodstitle; _pricelab.text = goodsmodel.goodsprice; _numcountlab.text = [nsstring stringwithformat:@"%d",goodsmodel.goodsnum]; if (goodsmodel.selectstate) { _selectstate = yes; _isselectimg.image = [uiimage imagenamed:@"复选框-选中"]; }else{ _selectstate = no; _isselectimg.image = [uiimage imagenamed:@"复选框-未选中"]; } } /** * 点击减按钮实现数量的减少 * * @param sender 减按钮 */ -(void)deletebtnaction:(uibutton *)sender { //判断是否选中,选中才能点击 if (_selectstate == yes) { //调用代理 [self.delegate btnclick:self andflag:(int)sender.tag]; } } /** * 点击加按钮实现数量的增加 * * @param sender 加按钮 */ -(void)addbtnaction:(uibutton *)sender { //判断是否选中,选中才能点击 if (_selectstate == yes) { //调用代理 [self.delegate btnclick:self andflag:(int)sender.tag]; } }
2.7 实现表格的代理方法
//返回单元格个数 - (nsinteger)tableview:(uitableview *)tableview numberofrowsinsection: (nsinteger)section { return infoarr.count; } //定制单元格内容 - (uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath { static nsstring *identify = @"indentify"; mycustomcell *cell = [tableview dequeuereusablecellwithidentifier:identify]; if (!cell) { cell = [[mycustomcell alloc]initwithstyle:uitableviewcellstyledefault reuseidentifier:identify]; cell.delegate = self; } //调用方法,给单元格赋值 [cell addthevalue:infoarr[indexpath.row]]; return cell; } //返回单元格的高度 -(cgfloat)tableview:(uitableview *)tableview heightforrowatindexpath:(nsindexpath *)indexpath { return 120; } //单元格选中事件 -(void)tableview:(uitableview *)tableview didselectrowatindexpath:(nsindexpath *)indexpath { /** * 判断当期是否为选中状态,如果选中状态点击则更改成未选中,如果未选中点击则更改成选中状态 */ goodsinfomodel *model = infoarr[indexpath.row]; if (model.selectstate) { model.selectstate = no; } else { model.selectstate = yes; } //刷新整个表格 // [_mytableview reloaddata]; //刷新当前行 [_mytableview reloadrowsatindexpaths:@[indexpath] withrowanimation:uitableviewrowanimationautomatic]; [self totalprice]; }
2.8 实现单元格加、减按钮代理
先要再viewcontroller.m 中导入mycustomcelldelegate 协议
@interface viewcontroller ()<uitableviewdatasource,uitableviewdelegate,mycustomcelldelegate>
然后实现代码如下:
#pragma mark -- 实现加减按钮点击代理事件 /** * 实现加减按钮点击代理事件 * * @param cell 当前单元格 * @param flag 按钮标识,11 为减按钮,12为加按钮 */ -(void)btnclick:(uitableviewcell *)cell andflag:(int)flag { nsindexpath *index = [_mytableview indexpathforcell:cell]; switch (flag) { case 11: { //做减法 //先获取到当期行数据源内容,改变数据源内容,刷新表格 goodsinfomodel *model = infoarr[index.row]; if (model.goodsnum > 1) { model.goodsnum --; } } break; case 12: { //做加法 goodsinfomodel *model = infoarr[index.row]; model.goodsnum ++; } break; default: break; } //刷新表格 [_mytableview reloaddata]; //计算总价 [self totalprice]; }
2.9 全选方法的实现
/** * 全选按钮事件 * * @param sender 全选按钮 */ -(void)selectbtnclick:(uibutton *)sender { //判断是否选中,是改成否,否改成是,改变图片状态 sender.tag = !sender.tag; if (sender.tag) { [sender setimage:[uiimage imagenamed:@"复选框-选中.png"] forstate:uicontrolstatenormal]; }else{ [sender setimage:[uiimage imagenamed:@"复选框-未选中.png"] forstate:uicontrolstatenormal]; } //改变单元格选中状态 for (int i=0; i<infoarr.count; i++) { goodsinfomodel *model = [infoarr objectatindex:i]; model.selectstate = sender.tag; } //计算价格 [self totalprice]; //刷新表格 [_mytableview reloaddata]; }
2.10 计算总价格
#pragma mark -- 计算价格 -(void)totalprice { //遍历整个数据源,然后判断如果是选中的商品,就计算价格(单价 * 商品数量) for ( int i =0; i<infoarr.count; i++) { goodsinfomodel *model = [infoarr objectatindex:i]; if (model.selectstate) { allprice = allprice + model.goodsnum *[model.goodsprice intvalue]; } } //给总价文本赋值 _allpricelab.text = [nsstring stringwithformat:@"%.2f",allprice]; nslog(@"%f",allprice); //每次算完要重置为0,因为每次的都是全部循环算一遍 allprice = 0.0; }
短时间手写:代码比较粗糙,没有完全整理;
源码下载:http://xiazai.jb51.net/201612/yuanma/androidshoppinglist(jb51.net).rar
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。