当前位置: 移动技术网 > 移动技术>移动开发>IOS > iOS实现电商购物车界面示例

iOS实现电商购物车界面示例

2019年07月24日  | 移动技术网移动技术  | 我要评论

先看界面效果图:

主要实现了商品的展示,并且可以对商品进行多选操作,以及改变商品的购买数量。与此同时,计算出,选中的总价格。


做此类型项目:要注意的:视图与数据要分离开来。视图的展现来源是数据模型层。所以我做的操作就是改变数据层的内容,在根据数据内容,去更新视图界面。
已下是具体实现思路与代码:

1. 实现步骤

  1. 在appdelegate.m中包含viewcontroller.h头文件,创建viewcontroller对象(vc),接着创建一个uinavigationcontroller对象(nvc)将vc设置为自己的根视图,最后设置self.window.rootviewcontroller为nvc。
  2. 在viewcontroller.m中创建一个全局的可变数组,并往里面添加表格需要的数据字典对象。
  3. 创建一个goodsinfomodel 类,继承于nsobject 类,用于做数据模型
  4. 创建一个mycustomcell 类 ,继承于uitableviewcell,自定义单元格类
  5. 在mycustomcell.m 类中,实现单元格的布局
  6. 在 viewcontroller.m 创建表格视图,并且创建表格尾部视图
  7. mycustomcell 类中定义协议,实现代理,完成加、减的运算。
  8. 在 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;
}

短时间手写:代码比较粗糙,没有完全整理;

源码下载:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网