在商城类APP的开发中,购物车功能是必不可少的。
在上一个app的开发中生活又对我这个菜鸟下手了,我被安排实现购物车功能WTF ~.~ .吐槽归吐槽,功能还是要实现滴。。。
购物车
实现思路:
- 购物车界面实现的关键是对MVC模式开发的理解和运用。我们通过在Model中定义一个是否被选中的bool值(isSelect)来改变选择的状态。
其实MVC这种运用场景还是很多的,比如我们要动态计算一个cell的高度的时候,我们通常也是会在model中去进行计算,然后将结果通过一个定义的常量暴露在.h文件中供其他调用。 - 自定义cell,这个就不多说了,不管是复杂的还是简单的cell大多数都是自定义的,这里复杂的数据可能用到富文本,比如这里现价和市场价我是一个label然后用富文本实现的。
- 多选的实现是在controller中声明了一个选中的数组,然后将选中的model保存到可变数组中。
- 代理的运用。这个功能使用到了很多代理的思想,底部结算区也是用代理实现的。(不建议用block,就是代理和block的优缺点比较吧)。
下面是代码的实现:
ShoppingCartModel.h
#import <Foundation/Foundation.h>
@interface ShoppingCartModel : NSObject
/**购物车ID*/
@property(nonatomic,strong)NSString *cartId ;
/**商品的编号*/
@property(nonatomic,strong)NSString *goodsNo ;
/**商品的id*/
@property(nonatomic,strong)NSString *goodsId ;
/**商品的图片*/
@property(nonatomic,strong)NSString *goodsImage ;
/**商品的名称*/
@property(nonatomic,strong)NSString *goodsName ;
/**商品的的市场价格*/
@property(nonatomic,strong)NSString *goodsMarketPrice ;
/**商品价格*/
@property(nonatomic,strong)NSString *goodsSystemPrice ;
/**商品的市场价格*/
@property(nonatomic,assign)NSInteger number ;
/**上次是否被选*/
@property (nonatomic, assign) BOOL isSelect;
-(instancetype)initWithDict:(NSDictionary *)dict ;
+(instancetype)ShoppingCartModelWithDict:(NSDictionary *)dict ;
@end
自定义cell声明代理方法
ShoppingCartTableViewCell.h
#import <UIKit/UIKit.h>
#import "ChoiceButton.h"
@class ShoppingCartTableViewCell,ShoppingCartModel,SureFormModel ;
@protocol ShoppingCartTableViewDelegate <NSObject>
@optional
/**选中*/
- (void)shopCartGoodViewCell:(ShoppingCartTableViewCell *)cell withSelectedModel:(ShoppingCartModel *)model;
/**添加、减少*/
- (void)shopCartGoodViewCellChange:(ShoppingCartTableViewCell *)cell ;
/**输入框事件*/
- (void)shopCartGoodViewCellTextField:(ShoppingCartTableViewCell *)cell;
@end
@interface ShoppingCartTableViewCell : UITableViewCell
/** 代理属性 */
@property (nonatomic ,weak)id<ShoppingCartTableViewDelegate> delegate;
@property(nonatomic,strong) ShoppingCartModel *model ;
@end
这里完成cell的布局,就不贴代码了,主要是代理部分的代码
ShoppingCartTableViewCell.m
#pragma mark - 勾选按钮事件
-(void)choiceButtonAction:(UIButton *)button{
ShoppingCartTableViewCell *cell = (ShoppingCartTableViewCell *)button.superview.superview;
if ([self.delegate respondsToSelector:@selector(shopCartGoodViewCell:withSelectedModel:)]) {
[self.delegate shopCartGoodViewCell:cell withSelectedModel:cell.model];
}
}
#pragma mark - 商品数量的setter方法
- (void)setGoodsCount:(NSInteger)goodsCount{
_goodsCount = goodsCount;
_shopNumberTextField.text = [NSString stringWithFormat:@"%ld", (long)goodsCount] ;
}
#pragma mark - textFieldDelegete
-(void)textFieldDidEndEditing:(UITextField *)textField{
ShoppingCartTableViewCell *cell = (ShoppingCartTableViewCell *)textField.superview.superview.superview;
ShoppingCartModel *model = cell.model;
if ([_shopNumberTextField.text integerValue] >= 99) {
self.shopNumberTextField.text = [NSString stringWithFormat:@"%d", 99];
}
if ([_shopNumberTextField.text integerValue] <= 0) {
self.shopNumberTextField.text = [NSString stringWithFormat:@"%d", 1];
}
model.number = [self.shopNumberTextField.text integerValue];
//向服务器发送请求
[self.delegate shopCartGoodViewCellTextField:self];
}
#pragma mark - 减按钮事件
-(void)minusButtonAction:(UIButton *)button{
ShoppingCartTableViewCell *cell = (ShoppingCartTableViewCell *)button.superview.superview.superview;
ShoppingCartModel *model = cell.model;
if (_goodsCount != 1) {
self.goodsCount = self.goodsCount - 1;
model.number = self.goodsCount;
//向服务器发送请求
[self.delegate shopCartGoodViewCellChange:self];
}
}
#pragma mark - 加按钮事件
-(void)plusButtonAction:(UIButton *)button{
ShoppingCartTableViewCell *cell = (ShoppingCartTableViewCell *)button.superview.superview.superview;
ShoppingCartModel *model = cell.model;
//换成最大库存
if (_goodsCount <= 99) {
self.goodsCount = self.goodsCount + 1;
model.number = self.goodsCount;
}else{
self.goodsCount = 99;
model.number = self.goodsCount;
}
//向服务器发送请求
[self.delegate shopCartGoodViewCellChange:self];
}
底部结算区:
ShoppingCartBottomMenuView.h
#import <UIKit/UIKit.h>
#import "ChoiceButton.h"
NS_ASSUME_NONNULL_BEGIN
@class ShoppingCartBottomMenuView ;
@protocol ShoppingCartBottomMenuViewDelegate <NSObject>
-(void)shoppingCartbottomPriceView:(ShoppingCartBottomMenuView *)bottonView;
/**
付款
*/
-(void)shoppingCartPayAccountsButton:(ShoppingCartBottomMenuView *)bottonView;
/**
删除
*/
-(void)shoppingCartDeleteButton:(ShoppingCartBottomMenuView *)bottonView;
@end
@interface ShoppingCartBottomMenuView : UIView
@property(nonatomic,strong)ChoiceButton *choiceButton ; //全选
@property(nonatomic,strong)UILabel *choiceLabel ; //选择状态
@property(nonatomic,strong)UILabel *totalPriceLabel ; //总价
@property(nonatomic,strong)UIButton *payAccountsButton ; //付款按钮
@property(nonatomic,strong)UIButton *deleteButton ; //删除按钮
/**结算字符串*/
@property (nonatomic, copy) NSString *payStr;
/**合计字符串*/
@property (nonatomic, strong) NSString *attAllStr;
@property (nonatomic, strong) NSString *changeStr;
@property (nonatomic, assign) BOOL isSelectBtn ;
@property (weak, nonatomic) id<ShoppingCartBottomMenuViewDelegate> delegate;
@end
ShoppingCartBottomMenuView.m
- (void)setIsSelectBtn:(BOOL)isSelectBtn{
_choiceButton.selected = isSelectBtn;
if ([self.delegate respondsToSelector:@selector(shoppingCartbottomPriceView:)]) {
[self.delegate shoppingCartbottomPriceView:self];
}
}
- (void)choiceButtonAction:(UIButton *)button{
button.selected = !button.isSelected;
if (button.selected) {
self.choiceLabel.text = @"全不选" ;
}else{
self.choiceLabel.text = @"全选" ;
}
if ([self.delegate respondsToSelector:@selector(shoppingCartbottomPriceView:)]) {
[self.delegate shoppingCartbottomPriceView:self];
}
}
-(void)payAccountsButtonAction{
if ([self.delegate respondsToSelector:@selector(shoppingCartPayAccountsButton:)]) {
[self.delegate shoppingCartPayAccountsButton:self];
}
}
-(void)deleteButtonAction{
if ([self.delegate respondsToSelector:@selector(shoppingCartDeleteButton:)]) {
[self.delegate shoppingCartDeleteButton:self];
}
}
- (void)setPayStr:(NSString *)payStr{
_payStr = payStr ;
if ([payStr isEqualToString:@""]) {
[self.payAccountsButton setTitle:@"结算" forState:UIControlStateNormal];
}else{
[self.payAccountsButton setTitle:[NSString stringWithFormat:@"结算%@", payStr] forState:UIControlStateNormal];
}
}
- (void)setAttAllStr:(NSString *)attAllStr{
_attAllStr = [NSString stringWithFormat:@"合计:¥%@", attAllStr];
NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc]initWithString:_attAllStr];
//添加属性
NSRange range = { 4,_attAllStr.length - 4};
NSRange range1 = {3, _attAllStr.length - 3};
[attStr addAttribute:NSFontAttributeName value:FONT(22 * kFitWithWidth) range:NSMakeRange(3, 1)] ;
[attStr addAttribute:NSFontAttributeName value:FONT_BOLD(32 * kFitWithWidth) range:range];
[attStr addAttribute:NSForegroundColorAttributeName value:RGB(247, 89, 64) range:range1];
self.totalPriceLabel.attributedText = attStr;
}
在controller中
ShoppingCartViewController.m
/**选中的商品模型数组*/
@property(nonatomic,strong)NSMutableArray *selectedArray ;
/**底部结算区*/
@property(nonatomic,strong)ShoppingCartBottomMenuView *menuView ;
/**总价格*/
@property (nonatomic, assign) double allSum ;
#pragma mark - ShoppingCartTableViewDelegate
/**添加、减去*/
- (void)shopCartGoodViewCellChange:(ShoppingCartTableViewCell *)cell{
_allSum = 0;
for (ShoppingCartModel *model in self.selectedArray) {
self.allSum += [model.goodsSystemPrice floatValue] * model.number ;
}
_menuView.attAllStr = [NSString stringWithFormat:@"%.2f", self.allSum];
[self insertOrUpdateShoppingCar:cell] ;
}
- (void)shopCartGoodViewCellTextField:(ShoppingCartTableViewCell *)cell{
_allSum = 0;
for (ShoppingCartModel *model in self.selectedArray) {
self.allSum += [model.goodsSystemPrice floatValue] * model.number ;
}
_menuView.attAllStr = [NSString stringWithFormat:@"%.2f", self.allSum];
[self insertOrUpdateShoppingCar:cell] ;
}
/**选中*/
- (void)shopCartGoodViewCell:(ShoppingCartTableViewCell *)cell withSelectedModel:(ShoppingCartModel *)model{
if ([self.selectedArray containsObject:model]) {
[self.selectedArray removeObject:model];
//每当取消选中商品
self.menuView.choiceButton.selected = NO;
model.isSelect = NO;
self.allSum -= [model.goodsSystemPrice floatValue] * model.number;
}else{
//选中之后
[self.selectedArray addObject:model];
model.isSelect = YES;
self.allSum += [model.goodsSystemPrice floatValue] * model.number;
}
if (self.selectedArray.count == self.shoppingCartListArray.count) {
//全部店铺添加
self.menuView.choiceButton.selected = YES;
self.menuView.choiceLabel.text = @"全不选" ;
}else{
self.menuView.choiceButton.selected = NO;
self.menuView.choiceLabel.text = @"全选" ;
}
self.menuView.attAllStr = [NSString stringWithFormat:@"%.2f", self.allSum];
if (self.selectedArray.count > 0) {
self.menuView.payStr = [NSString stringWithFormat:@"(%lu)", self.selectedArray.count];
}else{
self.menuView.payStr = @"" ;
}
[self.shoppingCartTableView reloadData];
}
#pragma mark - ShoppingCartBottomMenuViewDelegate
//底部选中
-(void)shoppingCartbottomPriceView:(ShoppingCartBottomMenuView *)bottonView{
if (bottonView.choiceButton.selected) {
[self.selectedArray removeAllObjects];
[self.selectedArray addObjectsFromArray:self.shoppingCartListArray];
for (ShoppingCartModel *model in self.shoppingCartListArray) {
model.isSelect = YES;
}
self.allSum = 0.0;
//计算总价格
for (ShoppingCartModel *model in self.selectedArray) {
self.allSum += [model.goodsSystemPrice floatValue] * model.number;
}
}else{
[self.selectedArray removeAllObjects];
for (ShoppingCartModel *model in self.shoppingCartListArray) {
model.isSelect = NO;
}
self.allSum = 0.0;
}
bottonView.attAllStr = [NSString stringWithFormat:@"%.2f", self.allSum];
if (self.selectedArray.count > 0) {
self.menuView.payStr = [NSString stringWithFormat:@"(%lu)", self.selectedArray.count];
}else{
self.menuView.payStr = @"" ;
}
[self.shoppingCartTableView reloadData];
}
大致思路就是这样。我们就可以实现购物车功能了。
有不足的地方希望大家积极补充。共勉。。