服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - iOS实现电商购物车界面示例

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

2021-02-22 14:08万里初心 IOS

这篇文章主要为大家详细介绍了iOS实现一个类似电商购物车界面示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

先看界面效果图:

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

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

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

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"):

?
1
2
3
4
5
6
7
8
9
10
11
//创建窗口
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 中去设置,导航栏标题

?
1
2
3
self.title = @"购物车";
 //设置标题的属性样式等
[self.navigationcontroller.navigationbar settitletextattributes:@{nsforegroundcolorattributename : [uicolor blackcolor],nsfontattributename:[uifont systemfontofsize:23.0f]}];

2.2 创建一个模型类用于存放数据模型
创建一个goodsinfomodel 类 ,继承于 nsobject
实现代码如下: goodsinfomodel.h 中

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@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对象)。代码如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@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 创建表格视图
代码如下:

?
1
2
3
4
5
6
7
8
9
10
/* 创建表格,并设置代理 /
_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 创建尾部视图

代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/* * 创建表格尾部视图 * * @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 :

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#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 实现表格的代理方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//返回单元格个数
- (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>
然后实现代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#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 全选方法的实现

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
* 全选按钮事件
*
* @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 计算总价格

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#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;
}

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

源码下载:androidshoppinglist.rar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

延伸 · 阅读

精彩推荐
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01
  • IOS关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01