根据项目需求。理解成不需要全选按钮,选中,不需要记录。实时计算,重复商品+1
定制xib的cell。
block有二个方法,加和减。
为啥写这篇,原因这次把自己坑怕了。
一开始是找了二个demo,一个是有选择的购物车,一个是类似淘宝购物车的demo,当然肯定不够完善,需要自己修改,后来看了一眼需求,好吧,这二个都用不到。so自己写了下,代码比较杂,比较多。
主要碰到的问题
第一个,也是最坑自己的:tableview返回cell代理方法不执行,都返回个数了,就是不返回cell。搜索了很多,大致好像七个答案,一个个是过去。最后还是没有呢,我就想是不是数据没同步?加载延迟0.5秒,ok。问题在于写在block的回调里面,所以reloaddata也要放在里面。以前还真的没注意。
第二个是啥呢,cell上处理键盘,我记得有个第三方库的,忘了用,结果就比较坑了,一开始是在写在cell里,后面才改到vc。
第三个是处理键盘下去计算价格,cell上的textfiled通过一直改变字的那个代理方法,得到cell。在手势里再调用cell的方法。
其他一些小问题。还有一点问题还没处理好。先记录下,先贴下大概代码。
cell.h
#import "KeyboardToolBar.h" #import <UIKit/UIKit.h> #import "CSGoods.h" typedef void(^LZNumberChangedBlock)(NSInteger number); @interface CartCell : UITableViewCell<UITextFieldDelegate> @property (weak, nonatomic) IBOutlet UIButton *cut; @property (weak, nonatomic) IBOutlet UIButton *add; @property (assign,nonatomic)NSInteger lzNumber; @property (weak, nonatomic) IBOutlet UIImageView *headerImageView; @property (weak, nonatomic) IBOutlet UILabel *nameLable; @property (weak, nonatomic) IBOutlet UILabel *desLable; @property (weak, nonatomic) IBOutlet UILabel *priceLable; @property (weak, nonatomic) IBOutlet UITextField *cutTextfield; - (void)LZReloadDataWithModel:(CSGoods*)model; - (void)LZNumberAddWithBlock:(LZNumberChangedBlock)block; - (void)LZNumberCutWithBlock:(LZNumberChangedBlock)block; -(void)doneEdit;
cell.m
#import <Foundation/Foundation.h> #import "UIViewDone.h" #import "CartCell.h" @implementation CartCell { LZNumberChangedBlock numberAddBlock; LZNumberChangedBlock numberCutBlock; } - (void)awakeFromNib { [super awakeFromNib]; // Initialization code } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; // Configure the view for the selected state } -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier] ) { self = [[[NSBundle mainBundle]loadNibNamed:@"CartCell" owner:nil options:nil]objectAtIndex:0]; [_headerImageView zy_cornerRadiusRoundingRect]; // self.cutTextfield.delegate = self; UIViewDone *viewDone = [[UIViewDone alloc]init]; [viewDone.buttonDone addTarget:self action:@selector(doneEdit) forControlEvents:UIControlEventTouchUpInside]; self.cutTextfield.inputAccessoryView = viewDone; [[[UIApplication sharedApplication] keyWindow] endEditing:YES]; self.cutTextfield.keyboardType = UIKeyboardTypeNumberPad; self.cutTextfield.returnKeyType = UIReturnKeyDone; } return self; } #pragma mark - public method - (void)LZReloadDataWithModel:(CSGoods*)model { [self.headerImageView sd_setImageWithURL:[NSURL URLWithString:model.goods_image_url]]; self.nameLable.text = model.goods_name; self.desLable.text = model.goods_name; self.priceLable.text = model.goods_price; if (model.seleNum.length) { self.cutTextfield.text = model.seleNum; }else{ self.cutTextfield.text = model.goods_num; } [self doneEdit]; } - (void)LZNumberAddWithBlock:(LZNumberChangedBlock)block { numberAddBlock = block; } - (void)LZNumberCutWithBlock:(LZNumberChangedBlock)block { numberCutBlock = block; } #pragma mark - 重写setter方法 - (void)setLzNumber:(NSInteger)lzNumber { _lzNumber = lzNumber; //self.numberLabel.text = [NSString stringWithFormat:@"%ld",(long)lzNumber]; self.cutTextfield.text = [NSString stringWithFormat:@"%ld",(long)lzNumber]; } -(BOOL)textFieldShouldReturn:(UITextField *)textField{ //NSInteger count = [self.numberLabel.text integerValue]; NSLog(@"执行"); NSInteger count = [self.cutTextfield.text integerValue]; if (numberAddBlock) { numberAddBlock(count); } [textField resignFirstResponder]; return YES; } -(void)doneEdit{ NSInteger count = [self.cutTextfield.text integerValue]; if (numberAddBlock) { numberAddBlock(count); } [self.cutTextfield resignFirstResponder]; } - (IBAction)cut:(id)sender { NSInteger count = [self.cutTextfield.text integerValue]; count--; if(count <= 0){ return ; } if (numberCutBlock) { numberCutBlock(count); } } - (IBAction)add:(id)sender { NSInteger count = [self.cutTextfield.text integerValue]; count++; if (numberAddBlock) { numberAddBlock(count); } }
购物车控制器xib 因为项目全是xib so 接着xib 否则一半手写布局,一半xib,风格太乱。
#import "KeyboardToolBar.h" #import <UIKit/UIKit.h> #import "CSGoods.h" @interface CartViewController : UIViewController @property (nonatomic,strong)NSString *type; @property (nonatomic,copy)NSString *goods_codeid; @property (nonatomic,copy)NSString *order_id; @property (nonatomic,copy)NSString *order_sn; @property (nonatomic,strong)CSGoods *myGoods;
.m
#import "CSOrder.h" #import "OrderListViewController.h" #import "FirstViewController.h" #import "UIViewDone.h" #import "RootViewController.h" #import "GoodsAddAndEditViewController.h" #import "CartViewController.h" #import "CartCell.h" #import "CMBAddonCloudStore.h" #import "UIViewController+Extend.h" #import "UIViewController+NavigationItem.h" #import "UIViewController+BackButtonHandler.h" @interface CartViewController ()<UITableViewDelegate,UITableViewDataSource,UITextFieldDelegate,UIGestureRecognizerDelegate> { NSDictionary *dict; UIViewDone *viewDone; NSDictionary *dicorder; NSDictionary *dicpay; CSOrder* order; CartCell *selecell; } @property (weak, nonatomic) IBOutlet UIButton *sendBtn; @property (strong, nonatomic) NSMutableArray *dataArray; @property (weak, nonatomic) IBOutlet UILabel *last_label; @property (weak, nonatomic) IBOutlet UITableView *table; @property (strong, nonatomic) UILabel *labelallNum; @property (strong, nonatomic) UILabel *dis_countNum; @property (strong, nonatomic) UILabel *orderNum; @property (strong, nonatomic) UITextField *cutPricetextfield; @property (nonatomic, assign)float originalPrice; @end @implementation CartViewController - (void)viewDidLoad { [super viewDidLoad]; [KeyboardToolBar registerKeyboardToolBar:self.self.cutPricetextfield]; [[[UIApplication sharedApplication] keyWindow] endEditing:YES]; [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; viewDone = [[UIViewDone alloc]init]; [viewDone.buttonDone addTarget:self action:@selector(doneEdit) forControlEvents:UIControlEventTouchUpInside]; [[[UIApplication sharedApplication] keyWindow] endEditing:YES]; if ([self.type isEqualToString:@"扫码收款"]) { _table.tableHeaderView = [self headerView]; [_sendBtn setTitle:@"扫码收款" forState:UIControlStateNormal]; NSString *titlename = @"扫码收款"; self.title = APPDEL.travelerLogin?[NSString stringWithFormat:@"%@%@",titlename,[self travelerLoginTitle]]:titlename; }else{ UIBarButtonItem *btnpay = [[UIBarButtonItem alloc]initWithTitle:@"继续扫码" style:UIBarButtonItemStylePlain target:self action:@selector(mymoney)]; self.navigationItem.rightBarButtonItem = btnpay; NSString *titlename = @"购物车"; self.title = APPDEL.travelerLogin?[NSString stringWithFormat:@"%@%@",titlename,[self travelerLoginTitle]]:titlename; } _table.tableFooterView = [self footerView]; [self addAGesutreRecognizerForYourView]; _dataArray = [NSMutableArray new]; [self loadData]; // Do any additional setup after loading the view from its nib. } -(void)viewWillAppear:(BOOL)animated{ if ([self.type isEqualToString:@"扫码收款"]) { _table.tableHeaderView = [self headerView]; [_sendBtn setTitle:@"扫码收款" forState:UIControlStateNormal]; NSString *titlename = @"扫码收款"; self.title = APPDEL.travelerLogin?[NSString stringWithFormat:@"%@%@",titlename,[self travelerLoginTitle]]:titlename; }else{ UIBarButtonItem *btnpay = [[UIBarButtonItem alloc]initWithTitle:@"继续扫码" style:UIBarButtonItemStylePlain target:self action:@selector(mymoney)]; self.navigationItem.rightBarButtonItem = btnpay; NSString *titlename = @"购物车"; self.title = APPDEL.travelerLogin?[NSString stringWithFormat:@"%@%@",titlename,[self travelerLoginTitle]]:titlename; } _table.tableFooterView = [self footerView]; } - (void)addAGesutreRecognizerForYourView { UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesturedDetected:)]; // 手势类型随你喜欢。 tapGesture.delegate = self; [self.table addGestureRecognizer:tapGesture]; } -(UIView*)headerView{ UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 60)]; UIView *viewsmall = [[UIView alloc] initWithFrame:CGRectMake(0, 3, kScreenWidth, 54)]; view.backgroundColor = [UIColor colorWithWhite:0.9 alpha:0.8]; viewsmall.backgroundColor = [UIColor whiteColor]; [view addSubview:viewsmall]; UILabel *labeltype = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 60, 51)]; labeltype.font = [UIFont systemFontOfSize:14]; labeltype.text = @"订单号:"; [viewsmall addSubview:labeltype]; _orderNum = [[UILabel alloc] initWithFrame:CGRectMake(60, 0, kScreenWidth-60, 51)]; _orderNum.font = [UIFont systemFontOfSize:14]; [viewsmall addSubview:_orderNum]; return view; } -(UIView*)footerView{ UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 82)]; view.backgroundColor = [UIColor colorWithWhite:0.9 alpha:0.8]; UIView *viewtop = [[UIView alloc] initWithFrame:CGRectMake(0, 1, kScreenWidth, 40)]; viewtop.backgroundColor = [UIColor whiteColor]; UIView *viewbottom = [[UIView alloc] initWithFrame:CGRectMake(0, 41, kScreenWidth, 40)]; viewbottom.backgroundColor = [UIColor whiteColor]; [view addSubview:viewbottom]; [view addSubview:viewtop]; UILabel *labeltype = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 80,40)]; labeltype.text = @"商品金额:"; labeltype.font = [UIFont systemFontOfSize:14]; [viewtop addSubview:labeltype]; _labelallNum = [[UILabel alloc] initWithFrame:CGRectMake(kScreenWidth-160, 0, 150, 40)]; _labelallNum.textAlignment = NSTextAlignmentRight; _labelallNum.font = [UIFont systemFontOfSize:14]; _labelallNum.textColor = RGBACOLOR(255, 88, 77, 1); [viewtop addSubview:_labelallNum]; UILabel *labelone = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 80, 40)]; labelone.font = [UIFont systemFontOfSize:14]; labelone.text = @"优惠金额:"; [viewbottom addSubview:labelone]; _dis_countNum = [[UILabel alloc] initWithFrame:CGRectMake(kScreenWidth-160, 2, 150, 36)]; _dis_countNum.textAlignment = NSTextAlignmentRight; _dis_countNum.font = [UIFont systemFontOfSize:14]; _dis_countNum.textColor = RGBACOLOR(255, 88, 77, 1); _dis_countNum.hidden = YES; [viewbottom addSubview:_dis_countNum]; _cutPricetextfield = [[UITextField alloc] initWithFrame:CGRectMake(kScreenWidth-100, 2, 90, 36)]; _cutPricetextfield.textAlignment = NSTextAlignmentCenter; _cutPricetextfield.layer.borderColor = RGBACOLOR(255, 88, 77, 1).CGColor; _cutPricetextfield.layer.borderWidth = 1; _cutPricetextfield.keyboardType = UIKeyboardTypeDecimalPad; self.cutPricetextfield.inputAccessoryView = viewDone; _cutPricetextfield.delegate = self; [viewbottom addSubview:_cutPricetextfield]; [self.view addSubview:view]; UIView *lineView = [[UIView alloc]init]; lineView.frame = CGRectMake(10, 40, kScreenWidth-20, 1); lineView.backgroundColor = [UIColor lightGrayColor]; [view addSubview:lineView]; return view; } -(void)loadData{ if (![CheckNetwork isExistenceNetwork]) { return; } [KVNProgress showAnimated:NO whileExecutingBlock:^{ } completionBlock:^{ } }]; // [self performSelector:@selector(reloadTable) withObject:nil afterDelay:0.5]; } -(void)toolArray:(CSGoods*)goods{ if (goods == nil) { return; } if (APPDEL.AppDelcart.count) { BOOL addNum = NULL ; //判断有无,yes时加1; for (CSGoods* arrgoods in APPDEL.AppDelcart) { if ([arrgoods.goods_id isEqualToString:goods.goods_id]) { addNum = YES; } } if (addNum) { for (CSGoods* arrgoods in APPDEL.AppDelcart) { if ([arrgoods.goods_id isEqualToString:goods.goods_id]) { NSLog(@"sele%@",arrgoods.seleNum); arrgoods.seleNum = [NSString stringWithFormat:@"%d",[arrgoods.seleNum intValue] +1]; } } }else{ [APPDEL.AppDelcart addObject:goods]; goods.seleNum = @"1"; } }else{ [APPDEL.AppDelcart addObject:goods]; goods.seleNum = @"1"; } _dataArray = APPDEL.AppDelcart; [self.table reloadData]; } -(BOOL) navigationShouldPopOnBackButton ///在这个方法里写返回按钮的事件处理 { [APPDEL.AppDelcart removeAllObjects]; //这里写要处理的代码 [self popToViewController:[FirstViewController class]]; return YES;//返回NO 不会执行 } - (IBAction)sendBtn:(id)sender { } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 100; } -(void)tableView:(UITableView*)tableView willDisplayCell:(UITableViewCell*)cell forRowAtIndexPath:(NSIndexPath*)indexPath { [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; } #pragma mark --- UITableViewDataSource & UITableViewDelegate - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return _dataArray.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (!_dataArray.count) { UITableViewCell *cell = [[UITableViewCell alloc]init]; return cell; } CartCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CartReusableCell"]; if (cell == nil) { cell = [[CartCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"CartReusableCell"]; } CSGoods *model = [_dataArray safeObjectAtIndex:indexPath.row]; __block typeof(cell)wsCell = cell; cell.cutTextfield.delegate = self; [cell LZNumberAddWithBlock:^(NSInteger number) { wsCell.lzNumber = number; model.goods_num = [NSString stringWithFormat:@"%ld",(long)number]; model.seleNum = [NSString stringWithFormat:@"%ld",(long)number]; [_dataArray replaceObjectAtIndex:indexPath.row withObject:model]; [self countPrice]; }]; [cell LZNumberCutWithBlock:^(NSInteger number) { wsCell.lzNumber = number; model.goods_num = [NSString stringWithFormat:@"%ld",(long)number]; model.seleNum = [NSString stringWithFormat:@"%ld",(long)number]; [_dataArray replaceObjectAtIndex:indexPath.row withObject:model]; [self countPrice]; }]; if ([self.type isEqualToString:@"扫码收款"]) { cell.cut.enabled = NO; cell.add.enabled = NO; cell.cutTextfield.userInteractionEnabled = NO; } [cell LZReloadDataWithModel:model]; return cell; } -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ } -(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath { return @"删除"; } -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"确定要删除该商品?删除后无法恢复!" preferredStyle:1]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { CSGoods *model = [_dataArray objectAtIndex:indexPath.row]; [_dataArray removeObjectAtIndex:indexPath.row]; [APPDEL.AppDelcart removeObject:model]; // 删除 [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; [self countPrice]; //如果删除的时候数据紊乱,可延迟0.5s刷新一下 [self performSelector:@selector(reloadTable) withObject:nil afterDelay:0.5]; }]; UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; [alert addAction:okAction]; [alert addAction:cancel]; [self presentViewController:alert animated:YES completion:nil]; } } /** * @author LQQ, 16-02-18 11:02:16 * * 计算已选中商品金额 */ -(void)countPrice { double totlePrice = 0.0; for (CSGoods *model in _dataArray) { double price = [model.goods_price doubleValue]; totlePrice += price*[model.goods_num doubleValue]; } _originalPrice = totlePrice; NSString *string = [NSString stringWithFormat:@"¥%.2f",totlePrice]; self.labelallNum.attributedText = [self LZSetString:string]; [self getAllprice]; } - (NSMutableAttributedString*)LZSetString:(NSString*)string { NSMutableAttributedString *LZString = [[NSMutableAttributedString alloc]initWithString:string]; NSRange rang = [string rangeOfString:@"合计:"]; [LZString addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:rang]; [LZString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:14] range:rang]; return LZString; } - (void)reloadTable { [self.table reloadData]; } #pragma mark 键盘出现 -(void)keyboardWillShow:(NSNotification *)note { CGRect keyBoardRect=[note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; _table.contentInset = UIEdgeInsetsMake(0, 0, keyBoardRect.size.height, 0); } #pragma mark 键盘消失 -(void)keyboardWillHide:(NSNotification *)note { _table.contentInset = UIEdgeInsetsMake(64, 0, 0, 0); } //扫码支付 -(void)mymoney{ [MobClick event:@"smzf"]; //扫码支付 RootViewController *scan = [[RootViewController alloc]init]; scan.title = @"扫码支付"; scan.type = @"code"; NSDictionary *dictN = @{@"type":@"code",@"hide":@"hide"}; [[NSNotificationCenter defaultCenter] postNotificationName:@"hideCodeView" object:nil userInfo: dictN]; [self.navigationController pushViewController:scan animated:YES]; } -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{ //get cell if (!(_cutPricetextfield == textField)) { //找到cell 在手势按钮中使用 selecell = (CartCell*)[[textField superview] superview]; // NSIndexPath *indexPath = [_table indexPathForCell:selecell]; } BOOL isHaveDian = YES; if ([textField.text rangeOfString:@"."].location == NSNotFound) { isHaveDian = NO; } if ([string length] > 0) { unichar single = [string characterAtIndex:0];//当前输入的字符 if ((single >= '0' && single <= '9') || single == '.') {//数据格式正确 //首字母不能为0和小数点 if([textField.text length] == 0){ if(single == '.') { [textField.text stringByReplacingCharactersInRange:range withString:@""]; return NO; } } //输入的字符是否是小数点 if (single == '.') { if(!isHaveDian)//text中还没有小数点 { isHaveDian = YES; return YES; }else{ [textField.text stringByReplacingCharactersInRange:range withString:@""]; return NO; } }else{ if (isHaveDian) {//存在小数点 //判断小数点的位数 NSRange ran = [textField.text rangeOfString:@"."]; if (range.location - ran.location <= 2) { return YES; }else{ return NO; } }else{ return YES; } } }else{//输入的数据格式不正确 [textField.text stringByReplacingCharactersInRange:range withString:@""]; return NO; } } else { return YES; } } - (void)textFieldEditChanged:(UITextField *)textField { [self getAllprice]; } -(void)getAllprice{ float lastNum = _originalPrice - [_cutPricetextfield.text floatValue]; if (lastNum <= 0) { [CheckNetwork promptMessageview:@"价格出错"]; return; } NSString *string = [NSString stringWithFormat:@"合计:¥%.2f",lastNum]; _last_label.attributedText = [self LZSetString:string]; [[[UIApplication sharedApplication] keyWindow] endEditing:YES]; [self.cutPricetextfield resignFirstResponder]; } - (BOOL)isPureInt:(NSString *)string{ NSScanner* scan = [NSScanner scannerWithString:string]; int val; return [scan scanInt:&val] && [scan isAtEnd]; } - (void)tapGesturedDetected:(UITapGestureRecognizer *)recognizer { [selecell doneEdit]; [self countPrice]; } - (void)doneEdit{ [self countPrice]; } - (BOOL)textFieldShouldReturn:(UITextField *)textField{ [self doneEdit]; return YES; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. }