整理一个简单的购物车小demo。主要利用“通知”来实现事件的传递。通知的发布和监听、移除通知。(资料来源于小码哥)
- UITableView 搭建基本骨架、加减按钮的圆角边框处理、底部工具条及数据显示
- model
- UITableViewCell 自定义
- NSNotificationCenter 监听发布及移除
如上图所示:点击加减按钮可以改变购物数量,底部工具条上的总价也随之变化计算出相应的价格总和。减号按钮、清空购物车按钮 默认不能点击,当数量大于0时可以点击。
model.m文件
#import <Foundation/Foundation.h>
@interface MRootModle : NSObject
@property (copy, nonatomic) NSString *money;
@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *image;
//
@property (nonatomic,assign)int count;
@end
RootViewController.m文件
#import "RootViewController.h"
#import "RootTableViewCell.h"
#import "MRootModle.h"
#import "MJExtension.h"
#define ScreenWidth [UIScreen mainScreen].bounds.size.width
#define ScreenHeight [UIScreen mainScreen].bounds.size.height
@interface RootViewController ()<UITableViewDelegate,UITableViewDataSource>
@property (nonatomic,strong)UITableView *tableView;
@property (nonatomic,strong)NSArray *dataArray;//数据源
@property (nonatomic,strong)UILabel *priceLabel;//总价价格
@property (nonatomic,strong)UILabel *zongjiaLabel;//总价
@property (nonatomic,strong)UIButton *clearBtn;//清空购物车
@property (nonatomic,strong)UIButton *buyBtn;//购物
@end
@implementation RootViewController
//数据源
- (NSArray *)dataArray{
if (!_dataArray) {
_dataArray = [MRootModle mj_objectArrayWithFilename:@"wine.plist"];
}
return _dataArray;
}
- (UITableView *)tableView{
if (!_tableView) {
_tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0,ScreenWidth, ScreenHeight-49) style:UITableViewStylePlain];
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.tableFooterView = [[UIView alloc]init];
}
return _tableView;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = @"购物车";
[self.view addSubview:self.tableView];
[self creatFootView];
//监听通知
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(plusClick:) name:@"plusClickNSNotification" object:nil];
[center addObserver:self selector:@selector(minusClick:) name:@"minusClickNSNotification" object:nil];
}
- (void)creatFootView{
//底部View
UIView *footView = [[UIView alloc]initWithFrame:CGRectMake(0, ScreenHeight-49, ScreenWidth, 49)];
footView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:footView];
//黑线
UIView *line = [[UIView alloc]initWithFrame:CGRectMake(0, ScreenHeight-49, ScreenWidth, 1)];
line.backgroundColor = [UIColor blackColor];
line.alpha = 0.3;
[self.view addSubview:line];
//总价
_zongjiaLabel = [[UILabel alloc]initWithFrame:CGRectMake(15, 8, 60, 33)];
_zongjiaLabel.font = [UIFont systemFontOfSize:15];
_zongjiaLabel.text =@"总价:¥";
[footView addSubview:_zongjiaLabel];
//
_priceLabel = [[UILabel alloc]initWithFrame:CGRectMake(65, 8, 100, 33)];
_priceLabel.text = @"0";
_priceLabel.textColor = [UIColor redColor];
[footView addSubview:_priceLabel];
//购物
_buyBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_buyBtn.frame = CGRectMake(ScreenWidth - 160, 8, 40, 33);
[_buyBtn setTitle:@"购物" forState:UIControlStateNormal];
[_buyBtn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
_buyBtn.font = [UIFont systemFontOfSize:17];
[_buyBtn addTarget:self action:@selector(buyClick:) forControlEvents:UIControlEventTouchUpInside];
[footView addSubview:_buyBtn];
//清空购物车
_clearBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_clearBtn.frame = CGRectMake(ScreenWidth-160, 8, 200, 33);
[_clearBtn setTitle:@"清空购物车" forState:UIControlStateNormal];
[_clearBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
_clearBtn.font = [UIFont systemFontOfSize:17];
[_clearBtn addTarget:self action:@selector(clearClick:) forControlEvents:UIControlEventTouchUpInside];
[footView addSubview:_clearBtn];
}
//购买
- (void)buyClick:(UIButton *)btn{
NSLog(@"购买");
}
//清空购物车
- (void)clearClick:(UIButton *)btn{
//清除模型里的数据
for (MRootModle *model in _dataArray) {
model.count = 0;
}
//刷新表格数据
[self.tableView reloadData];
self.priceLabel.text = @"0";
self.clearBtn.enabled = NO;
NSLog(@"清空购物车");
}
//减号的通知事件
- (void)plusClick:(NSNotification *)notif{
RootTableViewCell *cell =notif.object;
int price =self.priceLabel.text.intValue+cell.model.money.intValue;
//如果有文字就不行转换
_priceLabel.text = [NSString stringWithFormat:@"%d",price];
if (price>0) {
_clearBtn.enabled = YES;
[_buyBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
}
}
//加号的通知事件
- (void)minusClick:(NSNotification *)notif{
RootTableViewCell *cell = notif.object;
int price = self.priceLabel.text.intValue - cell.model.money.intValue;
_priceLabel.text =[NSString stringWithFormat:@"%d",price];
if (price==0) {
_clearBtn.enabled = NO;
[_buyBtn setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
}
}
- (void)dealloc{
//移除通知
[[NSNotificationCenter defaultCenter]removeObserver:self];
}
/**
代理
*/
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.dataArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
RootTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"iden"];
if (cell == nil) {
cell= [[RootTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"iden"];
}
cell.model =_dataArray[indexPath.row];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
TableViewCell.m文件
@interface RootTableViewCell ()
@property (nonatomic,strong)UIButton *jiaBtn;
@property (nonatomic,strong)UIButton *jianBtn;
@property (nonatomic,strong)UILabel *numLabel;
@property (nonatomic,strong)UIImageView *headerImageView;
@property (nonatomic,strong)UILabel *titletLabel;
@property (nonatomic,strong)UILabel *danjiaLabel;
@end
@implementation RootTableViewCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
if ([super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
[self createUI];
}
return self;
}
- (void)createUI{
//图片
_headerImageView = [[UIImageView alloc]initWithFrame:CGRectMake(10, 2, 40, 40)];
_headerImageView.backgroundColor = [UIColor brownColor];
[self.contentView addSubview:_headerImageView];
//题目
_titletLabel = [[UILabel alloc]initWithFrame:CGRectMake(53, 0, 200, 30)];
_titletLabel.textColor = [UIColor orangeColor];
_titletLabel.font = [UIFont systemFontOfSize:11];
[self.contentView addSubview:_titletLabel];
//单价
_danjiaLabel = [[UILabel alloc]initWithFrame:CGRectMake(53, 25, 50, 20)];
_danjiaLabel.textColor = [UIColor orangeColor];
_danjiaLabel.font = [UIFont systemFontOfSize:11];
[self.contentView addSubview:_danjiaLabel];
//加号button
_jiaBtn = [UIButton buttonWithType:UIButtonTypeCustom];
_jiaBtn.frame = CGRectMake(ScreenWidth-50, 5, 35, 35);
[_jiaBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[_jiaBtn setTitle:@"+" forState:UIControlStateNormal];
[_jiaBtn addTarget:self action:@selector(jiaClick) forControlEvents:UIControlEventTouchUpInside];
[self custombutton:_jiaBtn];
//数量
_numLabel =[[UILabel alloc]initWithFrame:CGRectMake(ScreenWidth - 80, 12, 20, 20)];
_numLabel.font = [UIFont systemFontOfSize:11];
[self.contentView addSubview:_numLabel];
//减号button
_jianBtn = [UIButton buttonWithType:UIButtonTypeSystem];
[_jianBtn setTitle:@"-" forState:UIControlStateNormal];
_jianBtn.frame =CGRectMake(ScreenWidth-140, 5, 35, 35);
_jianBtn.enabled = NO;
[_jianBtn addTarget:self action:@selector(jianClick) forControlEvents:UIControlEventTouchUpInside];
[self custombutton:_jianBtn];
}
-(void)setModel:(MRootModle *)model{
_model =model;
NSLog(@"%@",model.image);
_headerImageView.image =[UIImage imageNamed:model.image];
_titletLabel.text = model.name;
_danjiaLabel.text = [NSString stringWithFormat:@"¥%@",model.money];
_numLabel.text =[NSString stringWithFormat:@"%d",model.count];
//判断减号能不能用
_jianBtn.enabled = (_model.count>0);
}
// + 按钮
- (void)jiaClick{
NSLog(@"加一件");
self.model.count++;
_numLabel.text =[NSString stringWithFormat:@"%d",self.model.count];
if (_model.count>0) {
self.jianBtn.enabled = YES;
}
//发布通知
[[NSNotificationCenter defaultCenter]postNotificationName:@"plusClickNSNotification" object:self];
}
// — 按钮
- (void)jianClick{
self.model.count--;
_numLabel.text =[NSString stringWithFormat:@"%d",self.model.count];
if (!(self.model.count>0)) {
_numLabel.text =[NSString stringWithFormat:@"0"];
_jianBtn.enabled =NO;
}
//发布通知
[[NSNotificationCenter defaultCenter]postNotificationName:@"minusClickNSNotification" object:self];
NSLog(@"减一件");
}
//处理加减按钮的圆角边框
- (void)custombutton:(UIButton *)btn{
btn.layer.cornerRadius = btn.frame.size.width*0.5;
btn.layer.borderWidth = 1;
btn.layer.borderColor = [UIColor orangeColor].CGColor;
[btn setTitleColor:[UIColor grayColor] forState:UIControlStateHighlighted];
btn.titleLabel.font = [UIFont systemFontOfSize:25];
[self.contentView addSubview:btn];
}
当然也可以用KVO来关联view与model。取代通知下面贴出代码:
- (NSArray *)wineArray
{
if (!_wineArray) {
_wineArray = [XMGWine mj_objectArrayWithFilename:@"wine.plist"];
NSLog(@"数据源%@",_wineArray);
for (XMGWine *wine in _wineArray) {
[wine addObserver:self forKeyPath:@"count" options:NSKeyValueObservingOptionNew| NSKeyValueObservingOptionOld context:nil];
}
}
return _wineArray;
}
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)dealloc {
for (XMGWine *wine in _wineArray) {
[wine removeObserver:self forKeyPath:@"count"];
}
}
#pragma mark - KVO
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(XMGWine *)wine change:(NSDictionary<NSString *,id> *)change context:(void *)context{
// NSKeyValueChangeNewKey == @"new"
int new = [change[NSKeyValueChangeNewKey] intValue];
// NSKeyValueChangeOldKey == @"old"
int old = [change[NSKeyValueChangeOldKey] intValue];
if (new > old) { // 数量增加,点击加号
// 计算总价
int totalPrice = self.totalPriceLabel.text.intValue + wine.money.intValue;
// 设置总价
self.totalPriceLabel.text = [NSString stringWithFormat:@"%d",totalPrice];
// 购买按钮一定能点击
self.buyButton.enabled = YES;
} else { // 数量减少,点击减号
// 计算总价
int totalPrice = self.totalPriceLabel.text.intValue - wine.money.intValue;
// 设置总价
self.totalPriceLabel.text = [NSString stringWithFormat:@"%d",totalPrice];
// 控制购买按钮是否能点击
self.buyButton.enabled = (totalPrice > 0);
}
}