iOS - 購物車界面的實現(xiàn)

在商城類APP的開發(fā)中,購物車功能是必不可少的。
在上一個app的開發(fā)中生活又對我這個菜鳥下手了,我被安排實現(xiàn)購物車功能WTF ~.~ .吐槽歸吐槽,功能還是要實現(xiàn)滴。。。

購物車

實現(xiàn)思路:

  1. 購物車界面實現(xiàn)的關(guān)鍵是對MVC模式開發(fā)的理解和運用。我們通過在Model中定義一個是否被選中的bool值(isSelect)來改變選擇的狀態(tài)。
    其實MVC這種運用場景還是很多的,比如我們要動態(tài)計算一個cell的高度的時候,我們通常也是會在model中去進行計算,然后將結(jié)果通過一個定義的常量暴露在.h文件中供其他調(diào)用。
  2. 自定義cell,這個就不多說了,不管是復(fù)雜的還是簡單的cell大多數(shù)都是自定義的,這里復(fù)雜的數(shù)據(jù)可能用到富文本,比如這里現(xiàn)價和市場價我是一個label然后用富文本實現(xiàn)的。
  3. 多選的實現(xiàn)是在controller中聲明了一個選中的數(shù)組,然后將選中的model保存到可變數(shù)組中。
  4. 代理的運用。這個功能使用到了很多代理的思想,底部結(jié)算區(qū)也是用代理實現(xiàn)的。(不建議用block,就是代理和block的優(yōu)缺點比較吧)。

下面是代碼的實現(xiàn):

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 - 商品數(shù)量的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];
    //向服務(wù)器發(fā)送請求
    [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;
        //向服務(wù)器發(fā)送請求
        [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;
    }
    //向服務(wù)器發(fā)送請求
    [self.delegate shopCartGoodViewCellChange:self];
    
}

底部結(jié)算區(qū):
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 ; //選擇狀態(tài)

@property(nonatomic,strong)UILabel *totalPriceLabel ; //總價

@property(nonatomic,strong)UIButton *payAccountsButton ; //付款按鈕

@property(nonatomic,strong)UIButton *deleteButton ; //刪除按鈕

/**結(jié)算字符串*/
@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:@"結(jié)算" forState:UIControlStateNormal];
    }else{
        [self.payAccountsButton setTitle:[NSString stringWithFormat:@"結(jié)算%@", 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

/**選中的商品模型數(shù)組*/
@property(nonatomic,strong)NSMutableArray *selectedArray ;

/**底部結(jié)算區(qū)*/
@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];
    
}

大致思路就是這樣。我們就可以實現(xiàn)購物車功能了。
有不足的地方希望大家積極補充。共勉。。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容