The opening

Before writing several mall related, the specification selection, small control what, today put a shopping cart code and implementation logic, also calculate to mall series have an end.

Mall series of articles:

IOS approach mall APP(a) iOS approach mall APP(two common controls for shopping carts) iOS approach mall APP(three WKWebView product specifications select frame packaging) iOS approach mall APP(four runloop application to obtain address book and process)

The main content of this article

Analysis of shopping cart data structure Shopping cart selection processing logic shopping cart quantity change and price calculation shopping cart merchandise deletion and data refresh shopping cart state, price refresh common method





2. PNG

Analysis of data structure of shopping cart





Data structure.png

As can be seen from the figure, all data are contained in a large array, which also contains different levels of arrays differentiated according to different merchants. Each series group corresponds to the data containing each commodity. To facilitate processing, add data to a commodity

        [dict setObject:@NO forKey:@"checked"];
        [dict setObject:@NO forKey:@"checkedSection"];Copy the code

Checked indicates whether an item is checked. CheckedSection indicates whether a group is checked. The default value is NO. Construct a new data source to operate on.

Shopping cart selection processing logic

The first step is to select the button on the left of the cell and set a temporary parameter. When traversing the current group, self-add operation is performed. If the last number is equal to the number of data items in the group, it proves that all the items are selected. If the group button is clicked, iterate through the data and set all row selections to the same status as group selections. Public method of checking both price and checked status. The same is true for all, but the main thing is to use the common price and status update method every time you do it.

#pragma mark - click the button on cell -(void)singleClickWithCell:(UITableViewCell *)cell{NSIndexPath * indexPath = [self.shopCartTableView indexPathForCell:cell]; ShopCartAllDataModel *goodsModel = transformDataArray[indexPath.section][indexPath.row]; goodsModel.checked = ! goodsModel.checked; NSArray *sectionArray = transformDataArray[indexPath.section]; NSInteger totalCount = 0; for (int i = 0; i < sectionArray.count; i++) { ShopCartAllDataModel *goodsModel = transformDataArray[indexPath.section][i]; if (goodsModel.checked) { totalCount++; } } BOOL sectionSelect = (totalCount == sectionArray.count); if (sectionSelect) { ShopCartAllDataModel *model = transformDataArray[indexPath.section][0]; model.checkedSection = YES; }else{ ShopCartAllDataModel *model = transformDataArray[indexPath.section][0]; model.checkedSection = NO; }; [self.shopCartTableView reloadData]; [self checkSelcetState]; [self CalculatedPrice]; } #pragma mark - click on group header try -(void)goto_supplier_action:(UIButton *)sectionBtn{ShopCartAllDataModel *model = transformDataArray[sectionBtn.tag][0]; model.checkedSection =! model.checkedSection; NSArray *sectionArray = transformDataArray[sectionBtn.tag]; for (int i = 0; i < sectionArray.count; i++) { ShopCartAllDataModel *goodsModel = transformDataArray[sectionBtn.tag][i]; goodsModel.checked = model.checkedSection; } [self.shopCartTableView reloadData]; [self checkSelcetState]; [self CalculatedPrice]; } # pragma mark - selection button - (void) clickAllSelctBtn {self. AllSelectBtn. Selected =! self.allSelectBtn.selected; if (self.allSelectBtn.selected) { for (int i= 0; i< transformDataArray.count; i++) { NSMutableArray *temptArray =[[NSMutableArray alloc]initWithArray:transformDataArray[i]]; for (int j= 0; j <temptArray.count; j++) { ShopCartAllDataModel *goodsModel = temptArray[j]; goodsModel.checked =YES; goodsModel.checkedSection =YES; } } [self.shopCartTableView reloadData]; [self CalculatedPrice]; }else{ for (int i= 0; i< transformDataArray.count; i++) { NSMutableArray *temptArray =[[NSMutableArray alloc]initWithArray:transformDataArray[i]]; for (int j= 0; j <temptArray.count; j++) { ShopCartAllDataModel *goodsModel = temptArray[j]; goodsModel.checked =NO; goodsModel.checkedSection =NO; } } [self.shopCartTableView reloadData]; [self CalculatedPrice]; }}Copy the code

The results are as follows:





Selected. GIF

Shopping cart quantity change and price calculation

The change in quantity control is a separately encapsulated View that is added to the cell and handled by the agent on the cell. It is determined that the number cannot be further reduced when it is less than 1. Change the value of the corresponding price field in the Model while controlling the change of the quantity control in the middle during each addition and subtraction so that the price can be recalculated.

# pragma mark - add and subtract button agreement method / / add - (void) clickCountViewAddBtnWithCell: (UITableViewCell *) cell WithCountView: (countNumView *)countView{ NSIndexPath * indexPath = [self.shopCartTableView indexPathForCell:cell]; ShopCartAllDataModel *goodsModel = transformDataArray[indexPath.section][indexPath.row]; countView.reduceBtn.enabled =YES; NSInteger addNum =[countView.countTextfiled.text integerValue]; addNum ++; countView.countTextfiled.text = [NSString stringWithFormat:@"%ld",addNum]; NSDictionary *rowDic =originalArray[indexPath.section][indexPath.row]; goodsModel.market_price = [NSString stringWithFormat:@"%.2f",[[rowDic objectForKey:@"market_price" ] floatValue]*addNum]; [self.shopCartTableView reloadData]; [self checkSelcetState]; [self CalculatedPrice]; } / / reduction - (void) clickCountViewReduceBtnWithCell: (UITableViewCell *) cell WithCountView: (countView countNumView *) { NSIndexPath * indexPath = [self.shopCartTableView indexPathForCell:cell]; ShopCartAllDataModel *goodsModel = transformDataArray[indexPath.section][indexPath.row]; NSInteger reduceNum =[countView.countTextfiled.text integerValue]; NSDictionary *rowDic =originalArray[indexPath.section][indexPath.row]; if ( reduceNum <= 1) { countView.reduceBtn.enabled =NO; goodsModel.market_price = [NSString stringWithFormat:@"%.2f",[[rowDic objectForKey:@"market_price" ] floatValue]*1]; }else{ countView.reduceBtn.enabled =YES; reduceNum --; countView.countTextfiled.text = [NSString stringWithFormat:@"%ld",reduceNum]; goodsModel.market_price = [NSString stringWithFormat:@"%.2f",[[rowDic objectForKey:@"market_price" ] floatValue]*reduceNum]; } [self.shopCartTableView reloadData]; [self checkSelcetState]; [self CalculatedPrice]; }Copy the code

The implementation effect is as follows:





Price change.gif

Shopping cart item deletion with data refresh

The deletion of goods should first be stored in the data to be deleted, and the information that matches the selected state is stored in an array. For example, we store the order id of an item as a deletion identifier.

# pragma mark - settlement button - (void) clickMakeSureBtn {the if (self. RightTopBtn. Selected) {/ / delete selected goods for (int I = 0; i< transformDataArray.count; i++) { NSMutableArray *temptArray =[[NSMutableArray alloc]initWithArray:transformDataArray[i]]; for (int j= 0; j <temptArray.count; j++) { ShopCartAllDataModel *goodsModel = temptArray[j]; If (goodsModel. Checked & & self. RightTopBtn. Selected) {/ / delete the data into an array [deleteGoodsArray addObject: goodsModel. Goods_sn];  [self deletaGoods]; }else{[self deletaGoods]; }}}}else{// select item for (int I = 0; i< transformDataArray.count; i++) { NSMutableArray *temptArray =[[NSMutableArray alloc]initWithArray:transformDataArray[i]]; for (int j= 0; j <temptArray.count; j++) { ShopCartAllDataModel *goodsModel = temptArray[j]; If (goodsModel.checked) {// get the selected data information}}}}}Copy the code

The deletion of commodity information is not to delete the corresponding coordinates of the two-dimensional array, but to traverse the entire data source and determine whether the array deleteGoodsArray used to store the deleted data contains the ID of the current traversal data. If not, it is added to a new data source. In this way, the end of the traversal, A new data source is an array of all data sources that do not contain deleted data, which is used to replace the original data source data, refresh the list, and delete data.

-(void)deletaGoods{NSMutableArray *backDetailArray = [[NSMutableArray alloc]init];  for (int i= 0; i< transformDataArray.count; i++) { NSMutableArray *temptArray =[[NSMutableArray alloc]initWithArray:transformDataArray[i]]; NSMutableArray *sectionDetailArray = [[NSMutableArray alloc]init]; for (int j= 0; j <temptArray.count; j++) { ShopCartAllDataModel *goodsModel = temptArray[j]; if (! [deleteGoodsArray containsObject:goodsModel.goods_sn]) { [sectionDetailArray addObject:transformDataArray[i][j]]; } } if (sectionDetailArray.count) { [backDetailArray addObject:sectionDetailArray]; } } [transformDataArray removeAllObjects]; [transformDataArray addObjectsFromArray:backDetailArray]; [self.shopCartTableView reloadData]; [self CalculatedPrice]; }Copy the code

The implementation effect is as follows:





Deleted. GIF

Public method for shopping cart status, price refresh

There are two main public methods for traversing the selected state and refreshing the price data after each operation.

#pragma mark -(void)checkSelcetState{NSInteger totalSelected = 0; NSInteger realRowNum = 0; for (int i= 0; i< transformDataArray.count; i++) { NSMutableArray *temptArray =[[NSMutableArray alloc]initWithArray:transformDataArray[i]]; for (int j= 0; j <temptArray.count; j++) { ShopCartAllDataModel *goodsModel = temptArray[j]; realRowNum ++; if (goodsModel.checked) { totalSelected ++; } } } if (totalSelected == realRowNum) { self.allSelectBtn.selected =YES; }else{ self.allSelectBtn.selected =NO; }} #pragma mark - CalculatedPrice -(void)CalculatedPrice{float price = 0; for (int i= 0; i< transformDataArray.count; i++) { NSMutableArray *temptArray =[[NSMutableArray alloc]initWithArray:transformDataArray[i]]; for (int j= 0; j <temptArray.count; j++) { ShopCartAllDataModel *goodsModel = temptArray[j]; if (goodsModel.checked) { price = price+ [goodsModel.market_price floatValue]; }} self.pricelabel. text = [NSString stringWithFormat:@"%.2f yuan ",price]; }Copy the code

That’s the core, and we’ve simply implemented a simple little shopping cart logic. As for some expired items added to shopping cart, the processing logic of removed items will be gradually updated to Git in the future. Just in order to achieve a simple function, some places may not write concise and standard, mainly hope to summarize the train of thought to practice. If you have a git address, don’t say you don’t want to put it there





Deny three lian.jpg

Git address, like the star 😜

The code is here, look here: Shopping cart project code ShopCartTest

Afterword.

After more than a year of building a shopping mall, I wrote several articles more or less related to the project. Finally, I added a shopping cart. After all, a shopping mall without a shopping cart is not a real shopping mall. Next, I will probably switch to a new project and see if THERE is a chance to write another series. These articles can be a summary of my own, and I hope they will be helpful to students in need.