├── .gitignore ├── GNRTools ├── UINavigationBar+Awesome.h └── UINavigationBar+Awesome.m ├── LICENSE ├── README.md ├── Takeaway ├── Cells │ ├── GNRShopListCell.h │ ├── GNRShopListCell.m │ └── GNRShopListCell.xib ├── Classes │ ├── GNRGoodsListViewController.h │ ├── GNRGoodsListViewController.m │ ├── GNRShopListViewController.h │ └── GNRShopListViewController.m ├── Takeaway.storyboard └── Views │ ├── GNRLinkageTableView │ ├── Cells │ │ ├── GNRGoodsIndexCell.h │ │ ├── GNRGoodsIndexCell.m │ │ ├── GNRGoodsIndexCell.xib │ │ ├── GNRGoodsListCell.h │ │ ├── GNRGoodsListCell.m │ │ └── GNRGoodsListCell.xib │ ├── GNRLinkageTableView.h │ ├── GNRLinkageTableView.m │ ├── Models │ │ ├── GNRGoodsGroup.h │ │ ├── GNRGoodsGroup.m │ │ ├── GNRGoodsListModel.h │ │ ├── GNRGoodsListModel.m │ │ ├── GNRGoodsModel.h │ │ ├── GNRGoodsModel.m │ │ ├── GNRShoppingBag.h │ │ ├── GNRShoppingBag.m │ │ ├── GNRShoppingCart.h │ │ └── GNRShoppingCart.m │ ├── Stepper │ │ ├── GNRCountStepper.h │ │ └── GNRCountStepper.m │ └── Views │ │ ├── GNRSectionHeader.h │ │ ├── GNRSectionHeader.m │ │ ├── GNRSectionHeader.xib │ │ ├── GNRShopHeader.h │ │ ├── GNRShopHeader.m │ │ └── GNRShopHeader.xib │ ├── GNRTitleHeader.h │ ├── GNRTitleHeader.m │ └── ShoppingCart │ ├── Bar │ ├── GNRShoppingBar.h │ ├── GNRShoppingBar.m │ ├── GNRShoppingBarView.h │ ├── GNRShoppingBarView.m │ └── GNRShoppingBarView.xib │ ├── Cart │ ├── GNRCartFooter.h │ ├── GNRCartFooter.m │ ├── GNRCartFooter.xib │ ├── GNRCartGoodsCell.h │ ├── GNRCartGoodsCell.m │ ├── GNRCartGoodsCell.xib │ ├── GNRCartHeader.h │ ├── GNRCartHeader.m │ ├── GNRCartHeader.xib │ ├── GNRShoppingCartView.h │ └── GNRShoppingCartView.m │ └── GNRCartDefine.h ├── record.gif ├── 外卖.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── 外卖 ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── Takeaway │ │ ├── Contents.json │ │ └── ShopList │ │ │ ├── Contents.json │ │ │ ├── shop_goodslist_banner_bg.imageset │ │ │ ├── Contents.json │ │ │ ├── banner@2x.png │ │ │ └── banner@3x.png │ │ │ ├── shoplist_header_line.imageset │ │ │ ├── Contents.json │ │ │ ├── shoplist_header_line@2x.png │ │ │ └── shoplist_header_line@3x.png │ │ │ ├── shoplist_header_location_icon.imageset │ │ │ ├── Contents.json │ │ │ ├── shoplist_header_location_icon@2x.png │ │ │ └── shoplist_header_location_icon@3x.png │ │ │ ├── shoplist_header_quality_icon.imageset │ │ │ ├── Contents.json │ │ │ ├── shoplist_header_quality_icon@2x.png │ │ │ └── shoplist_header_quality_icon@3x.png │ │ │ ├── shoplist_stepper_add_icon.imageset │ │ │ ├── Contents.json │ │ │ ├── jia@2x.png │ │ │ └── jia@3x.png │ │ │ ├── shoplist_stepper_addred_icon.imageset │ │ │ ├── 2加@2x.png │ │ │ ├── 2加@3x.png │ │ │ └── Contents.json │ │ │ ├── shoplist_stepper_sub_icon.imageset │ │ │ ├── Contents.json │ │ │ ├── jian@2x.png │ │ │ └── jian@3x.png │ │ │ ├── shoplist_stepper_subred_icon.imageset │ │ │ ├── 2减@2x.png │ │ │ ├── 2减@3x.png │ │ │ └── Contents.json │ │ │ ├── shoplist_trash_icon.imageset │ │ │ ├── Contents.json │ │ │ ├── trash_@2x.png │ │ │ └── trash_@3x.png │ │ │ └── shopping_cart_icon.imageset │ │ │ ├── Contents.json │ │ │ ├── 购物车@2x.png │ │ │ └── 购物车@3x.png │ └── rsc │ │ ├── Contents.json │ │ └── image.imageset │ │ ├── Contents.json │ │ └── b20160607134009-81.jpg ├── Base.lproj │ └── LaunchScreen.storyboard ├── Info.plist └── main.m ├── 外卖Tests ├── Info.plist └── __Tests.m └── 外卖UITests ├── Info.plist └── __UITests.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | # Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | 55 | #Code Injection 56 | # 57 | # After new code Injection tools there's a generated folder /iOSInjectionProject 58 | # https://github.com/johnno1962/injectionforxcode 59 | 60 | iOSInjectionProject/ 61 | -------------------------------------------------------------------------------- /GNRTools/UINavigationBar+Awesome.h: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBar+Awesome.h 3 | // LTNavigationBar 4 | // 5 | // Created by ltebean on 15-2-15. 6 | // Copyright (c) 2015 ltebean. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UINavigationBar (Awesome) 12 | - (void)lt_setBackgroundColor:(UIColor *)backgroundColor; 13 | - (void)lt_setElementsAlpha:(CGFloat)alpha; 14 | - (void)lt_setTranslationY:(CGFloat)translationY; 15 | - (void)lt_reset; 16 | @end 17 | -------------------------------------------------------------------------------- /GNRTools/UINavigationBar+Awesome.m: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBar+Awesome.m 3 | // LTNavigationBar 4 | // 5 | // Created by ltebean on 15-2-15. 6 | // Copyright (c) 2015 ltebean. All rights reserved. 7 | // 8 | 9 | #import "UINavigationBar+Awesome.h" 10 | #import 11 | 12 | @implementation UINavigationBar (Awesome) 13 | static char overlayKey; 14 | 15 | - (UIView *)overlay 16 | { 17 | return objc_getAssociatedObject(self, &overlayKey); 18 | } 19 | 20 | - (void)setOverlay:(UIView *)overlay 21 | { 22 | objc_setAssociatedObject(self, &overlayKey, overlay, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 23 | } 24 | 25 | - (void)lt_setBackgroundColor:(UIColor *)backgroundColor 26 | { 27 | if (!self.overlay) { 28 | [self setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; 29 | self.overlay = [[UIView alloc] initWithFrame:CGRectMake(0, -20, [UIScreen mainScreen].bounds.size.width, CGRectGetHeight(self.bounds) + 20)]; 30 | self.overlay.userInteractionEnabled = NO; 31 | self.overlay.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; 32 | [self insertSubview:self.overlay atIndex:0]; 33 | } 34 | self.overlay.backgroundColor = backgroundColor; 35 | } 36 | 37 | - (void)lt_setTranslationY:(CGFloat)translationY 38 | { 39 | self.transform = CGAffineTransformMakeTranslation(0, translationY); 40 | } 41 | 42 | - (void)lt_setElementsAlpha:(CGFloat)alpha 43 | { 44 | [[self valueForKey:@"_leftViews"] enumerateObjectsUsingBlock:^(UIView *view, NSUInteger i, BOOL *stop) { 45 | view.alpha = alpha; 46 | }]; 47 | 48 | [[self valueForKey:@"_rightViews"] enumerateObjectsUsingBlock:^(UIView *view, NSUInteger i, BOOL *stop) { 49 | view.alpha = alpha; 50 | }]; 51 | 52 | UIView *titleView = [self valueForKey:@"_titleView"]; 53 | titleView.alpha = alpha; 54 | } 55 | 56 | - (void)lt_reset 57 | { 58 | [self setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault]; 59 | [self.overlay removeFromSuperview]; 60 | self.overlay = nil; 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 GNR 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

经典的外卖双列表 + 购物车 + 加入购物车动画

2 | 3 |

效果展示

4 | 5 |

6 | -------------------------------------------------------------------------------- /Takeaway/Cells/GNRShopListCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRShopListCell.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GNRShopListCell : UITableViewCell 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Takeaway/Cells/GNRShopListCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRShopListCell.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRShopListCell.h" 10 | 11 | @implementation GNRShopListCell 12 | 13 | - (void)awakeFromNib { 14 | [super awakeFromNib]; 15 | // Initialization code 16 | } 17 | 18 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 19 | [super setSelected:selected animated:animated]; 20 | 21 | // Configure the view for the selected state 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Takeaway/Cells/GNRShopListCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 54 | 63 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Takeaway/Classes/GNRGoodsListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRGoodsListViewController.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GNRGoodsListViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Takeaway/Classes/GNRGoodsListViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRGoodsListViewController.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRGoodsListViewController.h" 10 | #import "UINavigationBar+Awesome.h" 11 | #import "GNRLinkageTableView.h" 12 | #import "GNRShoppingBar.h" 13 | 14 | @interface GNRGoodsListViewController () 15 | 16 | @property (nonatomic,strong) CALayer *dotLayer;//小圆点 17 | @property (nonatomic,assign) CGFloat endPointX; 18 | @property (nonatomic,assign) CGFloat endPointY; 19 | @property (nonatomic,strong) UIBezierPath *path; 20 | 21 | @property (nonatomic, strong)GNRLinkageTableView * goodsListView; 22 | @property (nonatomic, strong)GNRShoppingBar * shoppingBar; 23 | @end 24 | 25 | @implementation GNRGoodsListViewController 26 | 27 | - (void)dealloc{ 28 | NSLog(@"dealloc"); 29 | } 30 | 31 | - (GNRLinkageTableView *)goodsListView{ 32 | if (!_goodsListView) { 33 | _goodsListView = [[GNRLinkageTableView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height-[GNRShoppingBar defaultHeight])]; 34 | _goodsListView.target = self; 35 | _goodsListView.delegate = self; 36 | } 37 | return _goodsListView; 38 | } 39 | 40 | - (GNRShoppingBar *)shoppingBar{ 41 | if (!_shoppingBar) { 42 | _shoppingBar = [GNRShoppingBar barWithStyle:GNRShoppingBarStyleDefault showInView:self.view]; 43 | _shoppingBar.cartView.target = self; 44 | [_shoppingBar.cartView.header.cleanBtn addTarget:self action:@selector(cleanGoodsCartAction:) forControlEvents:UIControlEventTouchUpInside]; 45 | 46 | CGRect rect = [self.view convertRect:_shoppingBar.shoppingBarView.shoppingCartIcon.frame fromView:_shoppingBar.shoppingBarView]; 47 | 48 | _endPointX = rect.origin.x + rect.size.width/2.0; 49 | _endPointY = rect.origin.y + rect.size.height/2.0; 50 | } 51 | return _shoppingBar; 52 | } 53 | 54 | - (void)viewDidLoad { 55 | [super viewDidLoad]; 56 | self.edgesForExtendedLayout = UIRectEdgeAll; 57 | self.automaticallyAdjustsScrollViewInsets = NO; 58 | [self.view addSubview:self.goodsListView]; 59 | [self initData]; 60 | [self.view addSubview:self.shoppingBar]; 61 | } 62 | 63 | 64 | - (void)viewWillAppear:(BOOL)animated{ 65 | [super viewWillAppear:animated]; 66 | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES]; 67 | self.navigationController.navigationBar.tintColor = [UIColor whiteColor]; 68 | [self.navigationController.navigationBar lt_setBackgroundColor:[UIColor colorWithWhite:1 alpha:0]]; 69 | } 70 | 71 | - (void)viewDidAppear:(BOOL)animated{ 72 | [super viewDidAppear:animated]; 73 | [self.navigationController.navigationBar setShadowImage:[UIImage new]]; 74 | [self scrollViewDidScrollForPositionY:self.goodsListView.rightTbView.contentOffset.y]; 75 | } 76 | 77 | - (void)viewDidDisappear:(BOOL)animated{ 78 | [super viewDidDisappear:animated]; 79 | [self.navigationController.navigationBar setShadowImage:nil]; 80 | } 81 | 82 | - (void)viewWillDisappear:(BOOL)animated{ 83 | [super viewWillDisappear:animated]; 84 | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES]; 85 | self.navigationController.navigationBar.tintColor = [UIColor blackColor]; 86 | [self.navigationController.navigationBar lt_reset]; 87 | } 88 | 89 | - (void)initData{ 90 | NSArray * arr = @[ 91 | @{@"title" : @"精选特卖", 92 | @"list" : @[@"甜点组合", @"毛肚", @"菌汤", @"甜点组合", @"毛肚", @"菌汤",@"甜点组合", @"毛肚", @"菌汤"] 93 | }, 94 | @{@"title" : @"饭后(含有茶点)", 95 | @"list" : @[@"甜点组合", @"毛肚", @"菌汤"] 96 | }, 97 | @{@"title" : @"茶点(含有茶点)", 98 | @"list" : @[@"甜点组合", @"毛肚", @"菌汤",@"甜点组合", @"毛肚", @"菌汤"] 99 | }, 100 | @{@"title" : @"素材水果拼盘", 101 | @"list" : @[@"甜点组合", @"毛肚", @"菌汤",@"甜点组合", @"毛肚", @"菌汤",@"甜点组合", @"毛肚", @"菌汤",@"甜点组合", @"毛肚", @"菌汤",] 102 | }, 103 | @{@"title" : @"水果拼盘生鲜果", 104 | @"list" : @[@"甜点组合", @"毛肚", @"菌汤",] 105 | }, 106 | @{@"title" : @"拼盘", 107 | @"list" : @[@"甜点组合"] 108 | }, 109 | @{@"title" : @"烤鱼盘", 110 | @"list" : @[@"甜点组合", @"毛肚", @"菌汤",@"甜点组合", @"毛肚", @"菌汤"] 111 | }, 112 | @{@"title" : @"饮料", 113 | @"list": @[@"甜点组合", @"毛肚", @"菌汤",@"甜点组合", @"毛肚", @"菌汤",@"甜点组合", @"毛肚", @"菌汤",@"甜点组合", @"毛肚", @"菌汤"] 114 | }, 115 | @{@"title": @"小吃", 116 | @"list": @[@"甜点组合", @"毛肚"] 117 | }, 118 | @{@"title" : @"作料", 119 | @"list" : @[@"甜点组合", @"毛肚", @"菌汤"] 120 | }, 121 | @{@"title" : @"主食", 122 | @"list" : @[@"甜点组合", @"毛肚", @"菌汤"] 123 | }, 124 | ]; 125 | 126 | [arr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 127 | GNRGoodsGroup * goodsGroup = [GNRGoodsGroup new]; 128 | goodsGroup.classesName = [obj objectForKey:@"title"]; 129 | NSArray * list = [obj objectForKey:@"list"]; 130 | [list enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 131 | GNRGoodsModel * goods = [GNRGoodsModel new]; 132 | goods.goodsName = obj; 133 | goods.goodsPrice = [NSString stringWithFormat:@"%.2f",(float)arc4random_uniform(100)+50.f]; 134 | [goodsGroup.goodsList addObject:goods]; 135 | }]; 136 | [_goodsListView.goodsList.goodsGroups addObject:goodsGroup]; 137 | }]; 138 | [_goodsListView reloadData]; 139 | 140 | self.shoppingBar.goodsList = _goodsListView.goodsList; 141 | } 142 | 143 | - (void)scrollViewDidScrollForPositionY:(CGFloat)y{ 144 | if (y<=64.f) { 145 | [self.navigationController.navigationBar lt_setBackgroundColor:[UIColor colorWithWhite:1 alpha:y/64.f]]; 146 | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES]; 147 | self.navigationController.navigationBar.tintColor = [UIColor whiteColor]; 148 | [self.navigationController.navigationBar setShadowImage:[UIImage new]]; 149 | 150 | }else{ 151 | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES]; 152 | [self.navigationController.navigationBar lt_setBackgroundColor:[UIColor colorWithWhite:1 alpha:1]]; 153 | self.navigationController.navigationBar.tintColor = [UIColor blackColor]; 154 | [self.navigationController.navigationBar setShadowImage:nil]; 155 | } 156 | } 157 | 158 | //clean 159 | - (void)cleanGoodsCartAction:(id)sender{ 160 | [self.goodsListView.goodsList.shoppingCart clear]; 161 | [self.shoppingBar.cartView dismiss]; 162 | [self.shoppingBar refreshCartBar]; 163 | [self.goodsListView.rightTbView reloadData]; 164 | } 165 | 166 | #pragma mark - stepper delegate 167 | - (void)stepper:(GNRCountStepper *)stepper valueChangedForCount:(NSInteger)count goods:(GNRGoodsModel *)goods{ 168 | if (stepper.style == GNRCountStepperStyleGoodsList) { 169 | //更新购物车中的商品 170 | [self.goodsListView.goodsList.shoppingCart.bags.firstObject updateGoods:goods]; 171 | //更新badgeValue 172 | [self.shoppingBar reloadData]; 173 | }else{//购物车中的 174 | if (count==0) { 175 | [self.goodsListView.goodsList.shoppingCart.bags.firstObject updateGoods:goods]; 176 | } 177 | [self.goodsListView.rightTbView reloadData]; 178 | if (!self.goodsListView.goodsList.shoppingCart.goodsTotalNumber) { 179 | [self.shoppingBar.cartView dismiss]; 180 | [self.shoppingBar refreshCartBar]; 181 | }else{ 182 | [self.shoppingBar reloadData]; 183 | } 184 | } 185 | } 186 | 187 | - (void)stepper:(GNRCountStepper *)stepper addSender:(UIButton *)sender cell:(UITableViewCell *)cell{ 188 | CGRect parentRect = [stepper convertRect:stepper.addBtn.frame toView:self.view]; 189 | [self jumpToCartAnimationWithAddBtnRect:parentRect]; 190 | } 191 | 192 | #pragma mark - 跳入购物车动画 193 | -(void)jumpToCartAnimationWithAddBtnRect:(CGRect)rect{ 194 | CGFloat startX = rect.origin.x; 195 | CGFloat startY = rect.origin.y; 196 | 197 | _path= [UIBezierPath bezierPath]; 198 | [_path moveToPoint:CGPointMake(startX, startY)]; 199 | //三点曲线 200 | [_path addCurveToPoint:CGPointMake(_endPointX, _endPointY) 201 | controlPoint1:CGPointMake(startX, startY) 202 | controlPoint2:CGPointMake(startX - 180, startY - 200)]; 203 | 204 | _dotLayer = [CALayer layer]; 205 | _dotLayer.backgroundColor = [UIColor blackColor].CGColor; 206 | _dotLayer.frame = CGRectMake(0, 0, 14, 14); 207 | _dotLayer.cornerRadius = 14/2.f; 208 | [self.view.layer addSublayer:_dotLayer]; 209 | [self groupAnimation]; 210 | } 211 | 212 | #pragma mark - 开始组合动画 213 | -(void)groupAnimation{ 214 | //路径 215 | CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 216 | animation.path = _path.CGPath; 217 | animation.rotationMode = kCAAnimationRotateAuto; 218 | 219 | //alpha 220 | CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"alpha"]; 221 | alphaAnimation.duration = 0.35f; 222 | alphaAnimation.fromValue = [NSNumber numberWithFloat:1.0]; 223 | alphaAnimation.toValue = [NSNumber numberWithFloat:0]; 224 | alphaAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; 225 | 226 | CAAnimationGroup *groups = [CAAnimationGroup animation]; 227 | groups.animations = @[animation,alphaAnimation]; 228 | groups.duration = 0.6f; 229 | groups.removedOnCompletion = NO; 230 | groups.fillMode = kCAFillModeForwards; 231 | groups.delegate = self; 232 | [groups setValue:@"groupsAnimation" forKey:@"animationName"]; 233 | [_dotLayer addAnimation:groups forKey:nil]; 234 | 235 | [self performSelector:@selector(removeFromLayer:) withObject:_dotLayer afterDelay:0.6f]; 236 | } 237 | 238 | //移除layer 239 | - (void)removeFromLayer:(CALayer *)layerAnimation{ 240 | [layerAnimation removeFromSuperlayer]; 241 | } 242 | 243 | #pragma mark - CAAnimationDelegate 244 | //组合动画结束后 购物车 缩放动画 245 | - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{ 246 | if ([[anim valueForKey:@"animationName"]isEqualToString:@"groupsAnimation"]) { 247 | CABasicAnimation *shakeAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 248 | shakeAnimation.duration = 0.1f; 249 | shakeAnimation.fromValue = [NSNumber numberWithFloat:1]; 250 | shakeAnimation.toValue = [NSNumber numberWithFloat:1.2]; 251 | shakeAnimation.autoreverses = YES; 252 | [_shoppingBar.shoppingBarView.shoppingCartIcon.layer addAnimation:shakeAnimation forKey:nil]; 253 | } 254 | } 255 | 256 | @end 257 | -------------------------------------------------------------------------------- /Takeaway/Classes/GNRShopListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRShopListViewController.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GNRShopListViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Takeaway/Classes/GNRShopListViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRShopListViewController.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRShopListViewController.h" 10 | #import "GNRGoodsListViewController.h" 11 | 12 | #import "GNRShopListCell.h" 13 | #import "GNRTitleHeader.h" 14 | 15 | @interface GNRShopListViewController () 16 | @property (weak, nonatomic) IBOutlet UITableView *tableView; 17 | @property (strong, nonatomic) IBOutlet GNRTitleHeader *titHeader; 18 | 19 | @end 20 | 21 | @implementation GNRShopListViewController 22 | 23 | - (void)viewDidLoad { 24 | [super viewDidLoad]; 25 | self.navigationController.view.backgroundColor = [UIColor whiteColor]; 26 | } 27 | 28 | #pragma mark - delegate 29 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 30 | return 20; 31 | } 32 | 33 | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ 34 | return self.titHeader; 35 | } 36 | 37 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ 38 | return 64.f; 39 | } 40 | 41 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 42 | GNRShopListCell * cell = [tableView dequeueReusableCellWithIdentifier:@"GNRShopListCell"]; 43 | if (cell==nil) { 44 | cell = [[[NSBundle mainBundle]loadNibNamed:@"GNRShopListCell" owner:self options:nil]firstObject]; 45 | } 46 | return cell; 47 | } 48 | 49 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 50 | return 133.f; 51 | } 52 | 53 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 54 | UIStoryboard * SB = [UIStoryboard storyboardWithName:@"Takeaway" bundle:nil]; 55 | GNRGoodsListViewController * goodsList = [SB instantiateViewControllerWithIdentifier:@"GNRGoodsListViewController"]; 56 | [self.navigationController pushViewController:goodsList animated:YES]; 57 | } 58 | 59 | - (void)viewWillAppear:(BOOL)animated{ 60 | [super viewWillAppear:animated]; 61 | NSIndexPath * selectIndexPath = [self.tableView indexPathForSelectedRow]; 62 | if (selectIndexPath) { 63 | [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES]; 64 | } 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /Takeaway/Takeaway.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Cells/GNRGoodsIndexCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRGoodsIndexCell.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | @class GNRGoodsGroup; 11 | @interface GNRGoodsIndexCell : UITableViewCell 12 | 13 | @property (weak, nonatomic) IBOutlet UILabel *nameL; 14 | @property (strong, nonatomic) GNRGoodsGroup * goodsGroup; 15 | @end 16 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Cells/GNRGoodsIndexCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRGoodsIndexCell.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRGoodsIndexCell.h" 10 | #import "GNRGoodsGroup.h" 11 | 12 | @interface GNRGoodsIndexCell () 13 | @property (nonatomic, strong)UIView * selectView; 14 | 15 | @end 16 | 17 | @implementation GNRGoodsIndexCell 18 | 19 | - (void)awakeFromNib { 20 | [super awakeFromNib]; 21 | // Initialization code 22 | _selectView = [[UIView alloc]initWithFrame:self.bounds]; 23 | _selectView.backgroundColor = [UIColor whiteColor]; 24 | self.selectedBackgroundView = _selectView; 25 | 26 | UIView *liner = [[UIView alloc] initWithFrame: CGRectMake(0, 0, 4, 13)]; 27 | liner.backgroundColor = _nameL.textColor; 28 | [_selectView addSubview:liner]; 29 | liner.center = CGPointMake(2, _nameL.center.y); 30 | } 31 | 32 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 33 | [super setSelected:selected animated:animated]; 34 | self.nameL.font = selected?[UIFont boldSystemFontOfSize:15]:[UIFont systemFontOfSize:13]; 35 | } 36 | 37 | - (void)setGoodsGroup:(GNRGoodsGroup *)goodsGroup{ 38 | _goodsGroup = goodsGroup; 39 | [self refreshUI]; 40 | } 41 | 42 | - (void)refreshUI{ 43 | if (_goodsGroup) { 44 | self.nameL.text = _goodsGroup.classesName; 45 | } 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Cells/GNRGoodsIndexCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Cells/GNRGoodsListCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRGoodsListCell.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "GNRCartDefine.h" 11 | 12 | 13 | @interface GNRGoodsListCell : UITableViewCell 14 | @property (weak, nonatomic) iddelegate; 15 | @property (weak, nonatomic) IBOutlet UIImageView *goodsImageV; 16 | @property (weak, nonatomic) IBOutlet UILabel *nameL; 17 | @property (weak, nonatomic) IBOutlet UILabel *priceL; 18 | @property (weak, nonatomic) IBOutlet UIView *stepperSuperView; 19 | @property (strong, nonatomic)GNRCountStepper * stepper; 20 | @property (strong, nonatomic)GNRGoodsModel * goods; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Cells/GNRGoodsListCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRGoodsListCell.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRGoodsListCell.h" 10 | 11 | @implementation GNRGoodsListCell 12 | 13 | - (void)drawRect:(CGRect)rect{ 14 | [super drawRect:rect]; 15 | CGContextRef context = UIGraphicsGetCurrentContext(); 16 | 17 | CGContextSetFillColorWithColor(context, [UIColor clearColor].CGColor); 18 | CGContextFillRect(context, rect); 19 | 20 | //下分割线 21 | CGContextSetStrokeColorWithColor(context, ([UIColor colorWithWhite:0.8 alpha:0.8]).CGColor); 22 | CGContextStrokeRect(context, CGRectMake(16, rect.size.height, rect.size.width, 0.4)); 23 | } 24 | 25 | - (GNRCountStepper *)stepper{ 26 | if (!_stepper) { 27 | _stepper = [[GNRCountStepper alloc]initWithFrame:CGRectZero]; 28 | } 29 | return _stepper; 30 | } 31 | 32 | - (void)awakeFromNib { 33 | [super awakeFromNib]; 34 | [self.stepperSuperView addSubview:self.stepper]; 35 | [self.stepper countChangedBlock:^(NSInteger count) { 36 | if (_goods) { 37 | _goods.number = @(count); 38 | if ([_delegate respondsToSelector:@selector(stepper:valueChangedForCount:goods:)]) { 39 | [_delegate stepper:_stepper valueChangedForCount:count goods:_goods]; 40 | } 41 | } 42 | }]; 43 | __weak typeof(self) wself = self; 44 | [wself.stepper addActionBlock:^(UIButton * btn) { 45 | if ([wself.delegate respondsToSelector:@selector(stepper:addSender:cell:)]) { 46 | [wself.delegate stepper:wself.stepper addSender:btn cell:wself]; 47 | } 48 | }]; 49 | [wself.stepper subActionBlock:^(UIButton * btn) { 50 | if ([wself.delegate respondsToSelector:@selector(stepper:subSender:cell:)]) { 51 | [wself.delegate stepper:wself.stepper subSender:btn cell:wself]; 52 | } 53 | }]; 54 | } 55 | 56 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 57 | [super setSelected:selected animated:animated]; 58 | 59 | // Configure the view for the selected state 60 | } 61 | 62 | - (void)setGoods:(GNRGoodsModel *)goods{ 63 | _goods = goods; 64 | [self refreshUI]; 65 | } 66 | 67 | - (void)layoutSubviews{ 68 | self.stepper.center = CGPointMake(_stepperSuperView.bounds.size.width/2.0, _stepperSuperView.bounds.size.height/2.0); 69 | } 70 | 71 | - (void)refreshUI{ 72 | if (!_goods) { 73 | return; 74 | } 75 | _nameL.text = _goods.goodsName; 76 | _priceL.text = [NSString stringWithFormat:@"¥%@",_goods.goodsPrice]; 77 | _stepper.count = _goods.number.integerValue; 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Cells/GNRGoodsListCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 35 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/GNRLinkageTableView.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRLinkageTableView.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "GNRGoodsListCell.h" 11 | 12 | @protocol GNRLinkageTableViewDelegate 13 | 14 | - (void)scrollViewDidScrollForPositionY:(CGFloat)y; 15 | 16 | @end 17 | 18 | @interface GNRLinkageTableView : UIView 19 | @property (nonatomic, weak) id target; 20 | @property (nonatomic, weak) id delegate; 21 | @property (nonatomic, strong)UITableView * leftTbView; 22 | @property (nonatomic, strong)UITableView * rightTbView; 23 | @property (nonatomic, strong)GNRGoodsListModel * goodsList; 24 | - (void)reloadData; 25 | @end 26 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/GNRLinkageTableView.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRLinkageTableView.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRLinkageTableView.h" 10 | #import "GNRShopHeader.h" 11 | #import "GNRSectionHeader.h" 12 | #import "GNRGoodsIndexCell.h" 13 | 14 | @interface GNRLinkageTableView () 15 | { 16 | BOOL relate; 17 | BOOL topCanChange;//是否可以渐变 18 | CGFloat NavBarHeight; 19 | CGFloat headerHeight; 20 | CGFloat ChangedHeight; 21 | 22 | CGFloat leftWidth; 23 | CGFloat rightWidth; 24 | CGRect BOUNDS; 25 | } 26 | @property (nonatomic, strong)GNRShopHeader * header; 27 | @end 28 | 29 | @implementation GNRLinkageTableView 30 | 31 | - (instancetype)initWithFrame:(CGRect)frame{ 32 | self = [super initWithFrame:frame]; 33 | if (self) { 34 | [self initData]; 35 | [self installTableView]; 36 | } 37 | return self; 38 | } 39 | 40 | - (GNRShopHeader *)header{ 41 | if (!_header) { 42 | _header = [GNRShopHeader header]; 43 | [self addSubview:_header]; 44 | } 45 | return _header; 46 | } 47 | 48 | - (void)initData{ 49 | relate = YES; 50 | NavBarHeight = 64.f; 51 | headerHeight = 152.f; 52 | ChangedHeight = headerHeight - NavBarHeight; 53 | _goodsList = [GNRGoodsListModel new]; 54 | BOUNDS = self.bounds; 55 | leftWidth = 100; 56 | rightWidth = BOUNDS.size.width - leftWidth; 57 | 58 | } 59 | 60 | - (void)reloadData{ 61 | [_leftTbView reloadData]; 62 | [_rightTbView reloadData]; 63 | [self resetFrame]; 64 | } 65 | 66 | - (void)resetFrame{ 67 | if (_rightTbView.contentSize.height-_rightTbView.bounds.size.height>=ChangedHeight) { 68 | self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.bounds.size.width, self.bounds.size.height+ChangedHeight); 69 | _rightTbView.frame = CGRectMake(leftWidth, headerHeight, rightWidth, BOUNDS.size.height-headerHeight+ChangedHeight); 70 | topCanChange = YES; 71 | }else{ 72 | self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.bounds.size.width, self.bounds.size.height); 73 | _rightTbView.frame = CGRectMake(leftWidth, headerHeight, rightWidth, BOUNDS.size.height-headerHeight); 74 | topCanChange = NO; 75 | } 76 | _leftTbView.frame = CGRectMake(0, headerHeight, leftWidth, BOUNDS.size.height-headerHeight); 77 | self.header.frame = CGRectMake(0, 0, BOUNDS.size.width, headerHeight); 78 | } 79 | 80 | - (void)installTableView{ 81 | //haeder 82 | self.header.frame = CGRectMake(0, 0, BOUNDS.size.width, headerHeight); 83 | 84 | _leftTbView = [[UITableView alloc]initWithFrame:CGRectMake(0, headerHeight, leftWidth, BOUNDS.size.height-headerHeight+ChangedHeight) style:UITableViewStylePlain]; 85 | _leftTbView.delegate = self; 86 | _leftTbView.dataSource = self; 87 | _leftTbView.showsVerticalScrollIndicator = NO; 88 | _leftTbView.separatorStyle = UITableViewCellSeparatorStyleNone; 89 | _rightTbView = [[UITableView alloc]initWithFrame:CGRectMake(leftWidth, headerHeight, rightWidth, BOUNDS.size.height-headerHeight+ChangedHeight) style:UITableViewStylePlain]; 90 | _rightTbView.delegate = self; 91 | _rightTbView.dataSource = self; 92 | [self addSubview:_leftTbView]; 93 | [self addSubview:_rightTbView]; 94 | } 95 | 96 | #pragma mark - tableView delegate 97 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ 98 | if (tableView==_leftTbView) { 99 | return 1; 100 | } 101 | return self.goodsList.sectionNumber; 102 | } 103 | 104 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 105 | if (tableView==_leftTbView) { 106 | return self.goodsList.sectionNumber; 107 | } 108 | if (section=0) { 224 | toFrame = CGRectMake(0, -ChangedHeight*y/NavBarHeight, BOUNDS.size.width, self.frame.size.height); 225 | leftToFrame = CGRectMake(0, headerHeight, leftWidth, BOUNDS.size.height-headerHeight+ChangedHeight*y/NavBarHeight); 226 | } 227 | else{ 228 | toFrame = CGRectMake(0, -ChangedHeight, BOUNDS.size.width, self.frame.size.height); 229 | leftToFrame = CGRectMake(0, headerHeight, leftWidth, BOUNDS.size.height-NavBarHeight); 230 | } 231 | leftToFrame = leftToFrame; 232 | [UIView animateWithDuration:0.2 animations:^{ 233 | self.frame = toFrame; 234 | _leftTbView.frame = leftToFrame; 235 | } completion:^(BOOL finished) { 236 | 237 | }]; 238 | if (scrollView.contentOffset.y == 0) {//这里解决点击状态栏回到顶部 左边不滚动的问题 239 | relate = YES; 240 | [_rightTbView reloadData]; 241 | } 242 | }else{ 243 | if (self.frame.origin.y!=0) { 244 | self.frame = CGRectMake(0, 0, BOUNDS.size.width, BOUNDS.size.height); 245 | _leftTbView.frame = CGRectMake(0, headerHeight, leftWidth, BOUNDS.size.height-headerHeight); 246 | } 247 | } 248 | } 249 | } 250 | 251 | 252 | @end 253 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Models/GNRGoodsGroup.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRGoodsGroup.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "GNRGoodsModel.h" 11 | 12 | @interface GNRGoodsGroup : NSObject 13 | @property (nonatomic, strong)NSString * classesName;//分类 14 | @property (nonatomic, strong)NSMutableArray * goodsList; 15 | @end 16 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Models/GNRGoodsGroup.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRGoodsGroup.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRGoodsGroup.h" 10 | 11 | @implementation GNRGoodsGroup 12 | - (instancetype)init{ 13 | self = [super init]; 14 | if (self) { 15 | _goodsList = [NSMutableArray array]; 16 | } 17 | return self; 18 | } 19 | @end 20 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Models/GNRGoodsListModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRGoodsListModel.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "GNRGoodsGroup.h" 11 | #import "GNRShoppingCart.h"//购物车 12 | 13 | @interface GNRGoodsListModel : NSObject 14 | @property (nonatomic, assign)NSInteger sectionNumber; 15 | @property (nonatomic, strong)NSMutableArray * goodsGroups; 16 | @property (nonatomic, strong)GNRShoppingCart * shoppingCart;//购物车 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Models/GNRGoodsListModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRGoodsListModel.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRGoodsListModel.h" 10 | 11 | @implementation GNRGoodsListModel 12 | 13 | - (instancetype)init{ 14 | self = [super init]; 15 | if (self) { 16 | _goodsGroups = [NSMutableArray array]; 17 | _shoppingCart = [GNRShoppingCart new]; 18 | } 19 | return self; 20 | } 21 | 22 | - (NSInteger)sectionNumber{ 23 | return self.goodsGroups.count; 24 | } 25 | 26 | - (void)setGoodsGroups:(NSMutableArray *)goodsGroups{ 27 | _goodsGroups = goodsGroups; 28 | //初始化 29 | [_goodsGroups enumerateObjectsUsingBlock:^(GNRGoodsGroup * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 30 | [obj.goodsList enumerateObjectsUsingBlock:^(GNRGoodsModel * _Nonnull goods, NSUInteger goodsIdx, BOOL * _Nonnull stop) { 31 | if (goods.number.integerValue) {//数量>0则加入购物袋 32 | [_shoppingCart.bags.firstObject updateGoods:goods]; 33 | } 34 | }]; 35 | }]; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Models/GNRGoodsModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRGoodsModel.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GNRGoodsModel : NSObject 12 | 13 | @property (nonatomic, strong)NSString * goodsName; 14 | @property (nonatomic, strong)NSString * goodsImage; 15 | @property (nonatomic, strong)NSString * goodsPrice; 16 | @property (nonatomic, assign)float shouldPayMoney; 17 | @property (nonatomic, strong)NSNumber * number;//购买个数 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Models/GNRGoodsModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRGoodsModel.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRGoodsModel.h" 10 | 11 | @implementation GNRGoodsModel 12 | - (float)shouldPayMoney{ 13 | return self.goodsPrice.floatValue * self.number.integerValue; 14 | } 15 | @end 16 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Models/GNRShoppingBag.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRShoppingBag.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/3. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "GNRGoodsModel.h" 11 | @interface GNRShoppingBag : NSObject 12 | 13 | @property (nonatomic, copy)NSString * identifer;//购物袋编号 14 | @property (nonatomic, assign)NSInteger goodsNumber;//购物袋商品数 15 | @property (nonatomic, assign)float totalPrice; 16 | @property (nonatomic, strong)NSMutableArray * goodsArr;//商品 17 | 18 | //更新购物袋中的商品 19 | - (void)updateGoods:(GNRGoodsModel *)goods; 20 | - (void)clear; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Models/GNRShoppingBag.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRShoppingBag.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/3. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRShoppingBag.h" 10 | 11 | @implementation GNRShoppingBag 12 | 13 | - (NSInteger)goodsNumber{ 14 | __block NSInteger number = 0; 15 | if (_goodsArr.count) { 16 | [_goodsArr enumerateObjectsUsingBlock:^(GNRGoodsModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 17 | number += obj.number.integerValue; 18 | }]; 19 | } 20 | return number; 21 | } 22 | 23 | - (float)totalPrice{ 24 | __block float price = 0; 25 | [_goodsArr enumerateObjectsUsingBlock:^(GNRGoodsModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 26 | price += obj.goodsPrice.floatValue * obj.number.integerValue; 27 | }]; 28 | return price; 29 | } 30 | 31 | - (instancetype)init{ 32 | self = [super init]; 33 | if (self) { 34 | _goodsArr = [NSMutableArray array]; 35 | } 36 | return self; 37 | } 38 | 39 | //更新购物袋中的商品 40 | - (void)updateGoods:(GNRGoodsModel *)goods{ 41 | NSInteger number = goods.number.integerValue;//购物袋中商品的数量 42 | if (number>0) { 43 | if (![_goodsArr containsObject:goods]) { 44 | [_goodsArr addObject:goods]; 45 | } 46 | }else{ 47 | if ([_goodsArr containsObject:goods]) { 48 | [_goodsArr removeObject:goods]; 49 | } 50 | } 51 | } 52 | 53 | //清空购物袋 54 | - (void)clear{ 55 | [_goodsArr enumerateObjectsUsingBlock:^(GNRGoodsModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 56 | obj.number = @0; 57 | }]; 58 | [_goodsArr removeAllObjects]; 59 | } 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Models/GNRShoppingCart.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRShoppingCart.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/3. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "GNRShoppingBag.h" 11 | 12 | @interface GNRShoppingCart : NSObject 13 | @property (nonatomic, assign)NSInteger goodsTotalNumber;//购物车商品总数 14 | @property (nonatomic, assign)float totalPrice; 15 | @property (nonatomic, strong)NSMutableArray * bags;//购物袋 16 | - (void)clear; 17 | @end 18 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Models/GNRShoppingCart.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRShoppingCart.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/3. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRShoppingCart.h" 10 | 11 | @implementation GNRShoppingCart 12 | 13 | - (NSInteger)goodsTotalNumber{ 14 | __block NSInteger number = 0; 15 | if (_bags.count) { 16 | [_bags enumerateObjectsUsingBlock:^(GNRShoppingBag * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 17 | number += obj.goodsNumber; 18 | }]; 19 | } 20 | return number; 21 | } 22 | 23 | - (float)totalPrice{ 24 | __block float price = 0; 25 | if (_bags.count) { 26 | [_bags enumerateObjectsUsingBlock:^(GNRShoppingBag * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 27 | price += obj.totalPrice; 28 | }]; 29 | } 30 | return price; 31 | } 32 | 33 | - (instancetype)init{ 34 | self = [super init]; 35 | if (self) { 36 | //暂时只生成一个购物袋 37 | GNRShoppingBag * bag = [GNRShoppingBag new]; 38 | bag.identifer = @"1"; 39 | _bags = [NSMutableArray arrayWithObjects:bag, nil]; 40 | } 41 | return self; 42 | } 43 | 44 | - (void)clear{ 45 | [self.bags enumerateObjectsUsingBlock:^(GNRShoppingBag * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 46 | [obj clear]; 47 | }]; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Stepper/GNRCountStepper.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRCountStepper.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "GNRCartDefine.h" 11 | 12 | @interface GNRCountStepper : UIView 13 | 14 | @property (nonatomic, strong)UIButton * subBtn; 15 | @property (nonatomic, strong)UIButton * addBtn; 16 | @property (nonatomic, strong)UILabel * numberL; 17 | 18 | @property (nonatomic, assign)NSInteger count; 19 | @property (nonatomic, assign)GNRCountStepperStyle style; 20 | - (void)countChangedBlock:(void(^)(NSInteger count))block; 21 | - (void)addActionBlock:(void(^)(UIButton *))block; 22 | - (void)subActionBlock:(void(^)(UIButton *))block; 23 | @end 24 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Stepper/GNRCountStepper.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRCountStepper.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRCountStepper.h" 10 | 11 | @interface GNRCountStepper () 12 | { 13 | CGFloat Height_MAX; 14 | CGFloat Width_MAX; 15 | CGFloat Width_Btn; 16 | CGFloat Width_Lab; 17 | CGRect BOUNDS_SIZE; 18 | void(^_block)(NSInteger count); 19 | void(^_addActionBlock)(UIButton * btn); 20 | void(^_subActionBlock)(UIButton * btn); 21 | } 22 | 23 | 24 | @end 25 | 26 | @implementation GNRCountStepper 27 | 28 | - (instancetype)init{ 29 | if (self = [super init]) { 30 | [self initData]; 31 | [self installUI]; 32 | } 33 | return self; 34 | } 35 | 36 | - (instancetype)initWithFrame:(CGRect)frame{ 37 | if (self = [super initWithFrame:frame]) { 38 | [self initData]; 39 | [self installUI]; 40 | } 41 | return self; 42 | } 43 | 44 | - (void)initData{ 45 | Width_Btn = 23.f; 46 | Width_Lab = 30.f; 47 | Width_MAX = Width_Lab+Width_Btn*2.f; 48 | Height_MAX = 30.f; 49 | BOUNDS_SIZE = CGRectMake(0, 0, Width_MAX, Height_MAX); 50 | self.bounds = BOUNDS_SIZE; 51 | } 52 | 53 | - (void)installUI{ 54 | _subBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 55 | [_subBtn setImage:[UIImage imageNamed:@"shoplist_stepper_sub_icon"] forState:UIControlStateNormal]; 56 | _subBtn.frame = CGRectMake(0, (Height_MAX-Width_Btn)/2.0, Width_Btn, Width_Btn); 57 | [_subBtn addTarget:self action:@selector(subBtnAction:) forControlEvents:UIControlEventTouchUpInside]; 58 | [self addSubview:_subBtn]; 59 | 60 | _numberL = [[UILabel alloc]initWithFrame:CGRectMake(_subBtn.frame.origin.x+_subBtn.frame.size.width, 0, Width_Lab, Height_MAX)]; 61 | _numberL.textColor = [UIColor blackColor]; 62 | _numberL.textAlignment = NSTextAlignmentCenter; 63 | _numberL.text = @"1"; 64 | _numberL.font = [UIFont systemFontOfSize:13]; 65 | [self addSubview:_numberL]; 66 | 67 | _addBtn = [UIButton buttonWithType:UIButtonTypeCustom]; 68 | [_addBtn setImage:[UIImage imageNamed:@"shoplist_stepper_add_icon"] forState:UIControlStateNormal]; 69 | _addBtn.frame = CGRectMake(_numberL.frame.origin.x+_numberL.frame.size.width, _subBtn.frame.origin.y, Width_Btn, Width_Btn); 70 | [_addBtn addTarget:self action:@selector(addBtnAction:) forControlEvents:UIControlEventTouchUpInside]; 71 | [self addSubview:_addBtn]; 72 | } 73 | 74 | - (void)setStyle:(GNRCountStepperStyle)style{ 75 | _style = style; 76 | [_subBtn setImage:[UIImage imageNamed:style==GNRCountStepperStyleGoodsList?@"shoplist_stepper_sub_icon":@"shoplist_stepper_subred_icon"] forState:UIControlStateNormal]; 77 | [_addBtn setImage:[UIImage imageNamed:style==GNRCountStepperStyleGoodsList?@"shoplist_stepper_add_icon":@"shoplist_stepper_addred_icon"] forState:UIControlStateNormal]; 78 | } 79 | 80 | - (void)setCount:(NSInteger)count{ 81 | _count = count; 82 | if (count<=0) { 83 | _subBtn.hidden = YES; 84 | _numberL.text = @""; 85 | }else{ 86 | _subBtn.hidden = NO; 87 | _numberL.text = @(count).stringValue; 88 | } 89 | } 90 | 91 | - (void)countChangedBlock:(void(^)(NSInteger count))block{ 92 | _block = nil; 93 | _block = [block copy]; 94 | } 95 | 96 | - (void)addActionBlock:(void (^)(UIButton *))block{ 97 | _addActionBlock = nil; 98 | _addActionBlock = [block copy]; 99 | } 100 | 101 | - (void)subActionBlock:(void(^)(UIButton *))block{ 102 | _subActionBlock = nil; 103 | _subActionBlock = [block copy]; 104 | } 105 | 106 | - (void)subBtnAction:(id)sender{ 107 | if (_count>0) { 108 | self.count--; 109 | } 110 | if (_block) { 111 | _block(_count); 112 | } 113 | 114 | if (_subActionBlock) { 115 | _subActionBlock(sender); 116 | } 117 | } 118 | 119 | - (void)addBtnAction:(id)sender{ 120 | self.count++; 121 | if (_block) { 122 | _block(_count); 123 | } 124 | if (_addActionBlock) { 125 | _addActionBlock(sender); 126 | } 127 | } 128 | 129 | @end 130 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Views/GNRSectionHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRSectionHeader.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GNRSectionHeader : UIView 12 | 13 | @property (weak, nonatomic) IBOutlet UILabel *titL; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Views/GNRSectionHeader.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRSectionHeader.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRSectionHeader.h" 10 | 11 | @implementation GNRSectionHeader 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Views/GNRSectionHeader.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Views/GNRShopHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRShopHeader.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/3. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GNRShopHeader : UIView 12 | 13 | @property (weak, nonatomic) IBOutlet UIImageView *logoImgV; 14 | @property (weak, nonatomic) IBOutlet UILabel *nameL; 15 | @property (weak, nonatomic) IBOutlet UILabel *telL; 16 | @property (weak, nonatomic) IBOutlet UILabel *addressL; 17 | + (GNRShopHeader *)header; 18 | @end 19 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Views/GNRShopHeader.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRShopHeader.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/3. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRShopHeader.h" 10 | 11 | @implementation GNRShopHeader 12 | 13 | - (void)layoutSubviews{ 14 | _logoImgV.layer.cornerRadius = _logoImgV.bounds.size.height/2.0; 15 | _logoImgV.layer.borderColor = [UIColor whiteColor].CGColor; 16 | _logoImgV.layer.borderWidth = 1; 17 | _logoImgV.layer.masksToBounds = YES; 18 | } 19 | 20 | + (GNRShopHeader *)header{ 21 | return [[[NSBundle mainBundle]loadNibNamed:@"GNRShopHeader" owner:self options:nil]firstObject];; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRLinkageTableView/Views/GNRShopHeader.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 34 | 40 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRTitleHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRTitleHeader.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GNRTitleHeader : UIView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Takeaway/Views/GNRTitleHeader.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRTitleHeader.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRTitleHeader.h" 10 | 11 | @interface GNRTitleHeader () 12 | @property (weak, nonatomic) IBOutlet UIImageView *icon; 13 | @property (weak, nonatomic) IBOutlet UILabel *titL; 14 | 15 | @end 16 | 17 | @implementation GNRTitleHeader 18 | 19 | 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Takeaway/Views/ShoppingCart/Bar/GNRShoppingBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRShoppingBar.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/3. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "GNRCartDefine.h" 11 | #import "GNRShoppingBarView.h" 12 | 13 | @class GNRGoodsListModel; 14 | @interface GNRShoppingBar : UIView 15 | 16 | @property (nonatomic, assign)GNRShoppingBarStyle style; 17 | @property (nonatomic, strong)GNRGoodsListModel * goodsList; 18 | @property (nonatomic, strong)GNRShoppingCartView * cartView; 19 | @property (nonatomic, strong)GNRShoppingBarView * shoppingBarView; 20 | 21 | + (CGFloat)defaultHeight; 22 | 23 | + (instancetype)barWithStyle:(GNRShoppingBarStyle)style showInView:(UIView *)view; 24 | 25 | - (void)refreshCartBar; 26 | - (void)reloadData; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Takeaway/Views/ShoppingCart/Bar/GNRShoppingBar.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRShoppingBar.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/3. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRShoppingBar.h" 10 | #import "GNRGoodsListModel.h" 11 | 12 | @interface GNRShoppingBar () 13 | { 14 | CGRect SCREEN_BOUNDS; 15 | CGFloat kHeight_Bar_Default; 16 | } 17 | @property (nonatomic, strong)UIView * parentView; 18 | 19 | @end 20 | 21 | @implementation GNRShoppingBar 22 | 23 | + (instancetype)barWithStyle:(GNRShoppingBarStyle)style showInView:(UIView *)view{ 24 | GNRShoppingBar * bar = [[GNRShoppingBar alloc]init]; 25 | bar.style = style; 26 | bar.parentView = view; 27 | return bar; 28 | } 29 | 30 | + (CGFloat)defaultHeight{ 31 | return 49.f; 32 | } 33 | 34 | - (GNRShoppingCartView *)cartView{ 35 | if (!_cartView) { 36 | _cartView = [[GNRShoppingCartView alloc]initWithFrame:CGRectMake(0, 0, self.bounds.size.width, SCREEN_BOUNDS.size.height-self.bounds.size.height)]; 37 | [self.parentView insertSubview:_cartView belowSubview:self]; 38 | } 39 | return _cartView; 40 | } 41 | 42 | - (instancetype)initWithFrame:(CGRect)frame{ 43 | self = [super initWithFrame:frame]; 44 | if (self) { 45 | [self initData]; 46 | } 47 | return self; 48 | } 49 | 50 | - (instancetype)init{ 51 | self = [super init]; 52 | if (self) { 53 | [self initData]; 54 | } 55 | return self; 56 | } 57 | 58 | - (void)initData{ 59 | SCREEN_BOUNDS = [UIScreen mainScreen].bounds; 60 | } 61 | 62 | - (void)layoutSubviews{ 63 | [self resetFrame]; 64 | } 65 | 66 | - (void)resetFrame{ 67 | self.frame = CGRectMake(0, SCREEN_BOUNDS.size.height-kHeight_Bar_Default, SCREEN_BOUNDS.size.width, kHeight_Bar_Default); 68 | self.shoppingBarView.frame = CGRectMake(0, 0, SCREEN_BOUNDS.size.width, kHeight_Bar_Default); 69 | } 70 | 71 | - (void)installUI{ 72 | self.layer.borderColor = [UIColor colorWithWhite:0.8 alpha:0.8].CGColor; 73 | self.layer.borderWidth = 0.4; 74 | 75 | [self resetFrame]; 76 | } 77 | 78 | - (GNRShoppingBarView *)shoppingBarView{ 79 | if (!_shoppingBarView) { 80 | _shoppingBarView = [GNRShoppingBarView view]; 81 | [_shoppingBarView.payBtn addTarget:self action:@selector(payAction:) forControlEvents:UIControlEventTouchUpInside]; 82 | [_shoppingBarView.cartBtn addTarget:self action:@selector(shoppingCartAction:) forControlEvents:UIControlEventTouchUpInside]; 83 | [self addSubview:_shoppingBarView]; 84 | } 85 | return _shoppingBarView; 86 | } 87 | 88 | - (void)setStyle:(GNRShoppingBarStyle)style{ 89 | _style = style; 90 | switch (style) { 91 | case GNRShoppingBarStyleDefault: 92 | { 93 | kHeight_Bar_Default = [GNRShoppingBar defaultHeight]; 94 | [self installUI]; 95 | } 96 | break; 97 | 98 | default: 99 | break; 100 | } 101 | } 102 | 103 | - (void)setGoodsList:(GNRGoodsListModel *)goodsList{ 104 | _goodsList = goodsList; 105 | self.cartView.goodsList = goodsList; 106 | [self reloadData]; 107 | } 108 | 109 | - (void)reloadData{ 110 | [self refreshCartBar]; 111 | [self.cartView reloadData]; 112 | } 113 | 114 | - (void)refreshCartBar{ 115 | [self.shoppingBarView updateBadgeValue:_goodsList.shoppingCart.goodsTotalNumber price:_goodsList.shoppingCart.totalPrice]; 116 | } 117 | 118 | - (void)shoppingCartAction:(id)sender { 119 | if (!self.goodsList.shoppingCart.goodsTotalNumber) { 120 | return; 121 | } 122 | if (self.cartView.shown) { 123 | [self.cartView dismiss]; 124 | }else{ 125 | //赋值 126 | [self.cartView show]; 127 | } 128 | } 129 | 130 | - (void)payAction:(id)sender { 131 | 132 | } 133 | 134 | @end 135 | -------------------------------------------------------------------------------- /Takeaway/Views/ShoppingCart/Bar/GNRShoppingBarView.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRShoppingBarView.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/3. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GNRShoppingBarView : UIView 12 | 13 | @property (weak, nonatomic) IBOutlet UILabel *badgeLabel; 14 | @property (weak, nonatomic) IBOutlet UIView *shoppingCartSuperView; 15 | @property (weak, nonatomic) IBOutlet UIImageView *shoppingCartIcon; 16 | @property (weak, nonatomic) IBOutlet UILabel *priceL; 17 | @property (weak, nonatomic) IBOutlet UIButton *payBtn; 18 | @property (weak, nonatomic) IBOutlet UIButton *cartBtn; 19 | 20 | + (GNRShoppingBarView *)view; 21 | 22 | - (void)updateBadgeValue:(NSInteger)value price:(float)price; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Takeaway/Views/ShoppingCart/Bar/GNRShoppingBarView.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRShoppingBarView.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/3. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRShoppingBarView.h" 10 | 11 | @implementation GNRShoppingBarView 12 | 13 | + (GNRShoppingBarView *)view{ 14 | return (GNRShoppingBarView *)[[[NSBundle mainBundle]loadNibNamed:@"GNRShoppingBarView" owner:self options:nil]firstObject]; 15 | } 16 | 17 | - (instancetype)initWithCoder:(NSCoder *)aDecoder{ 18 | self = [super initWithCoder:aDecoder]; 19 | if (self) { 20 | self.badgeLabel.center = CGPointMake(_shoppingCartIcon.frame.origin.x+_shoppingCartIcon.frame.size.width, _shoppingCartIcon.frame.origin.y); 21 | 22 | } 23 | return self; 24 | } 25 | 26 | - (void)drawRect:(CGRect)rect{ 27 | self.shoppingCartSuperView.layer.borderColor =[UIColor colorWithWhite:0.8 alpha:0.8].CGColor; 28 | self.shoppingCartSuperView.layer.borderWidth = 0.4; 29 | _badgeLabel.layer.cornerRadius = _badgeLabel.bounds.size.height/2.0; 30 | _badgeLabel.layer.masksToBounds = YES; 31 | } 32 | 33 | - (void)updateBadgeValue:(NSInteger)value price:(float)price{ 34 | //badge 35 | self.badgeLabel.hidden = !value; 36 | self.badgeLabel.text = @(value).stringValue; 37 | NSInteger maxCount = 5; 38 | CGFloat textW = 6.f; 39 | CGFloat maxW = maxCount * textW; 40 | CGFloat labW = (self.badgeLabel.text.length + 1.f) * textW; 41 | CGFloat minW = 14.f; 42 | if (labW>maxW) { 43 | labW = maxW; 44 | }else if (labW 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 59 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /Takeaway/Views/ShoppingCart/Cart/GNRCartFooter.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRCartFooter.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/4. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GNRCartFooter : UITableViewCell 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Takeaway/Views/ShoppingCart/Cart/GNRCartFooter.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRCartFooter.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/4. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRCartFooter.h" 10 | 11 | @implementation GNRCartFooter 12 | 13 | - (void)awakeFromNib { 14 | [super awakeFromNib]; 15 | // Initialization code 16 | } 17 | 18 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 19 | [super setSelected:selected animated:animated]; 20 | 21 | // Configure the view for the selected state 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Takeaway/Views/ShoppingCart/Cart/GNRCartFooter.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Takeaway/Views/ShoppingCart/Cart/GNRCartGoodsCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRCartGoodsCell.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/3. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "GNRCartDefine.h" 11 | 12 | @interface GNRCartGoodsCell : UITableViewCell 13 | @property (weak, nonatomic) iddelegate; 14 | 15 | @property (weak, nonatomic) IBOutlet UILabel *nameL; 16 | @property (weak, nonatomic) IBOutlet UILabel *priceLabel; 17 | @property (weak, nonatomic) IBOutlet UIView *stepperSuperView; 18 | @property (nonatomic, strong)GNRCountStepper * stepper; 19 | 20 | - (void)config:(GNRGoodsModel *)goods; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Takeaway/Views/ShoppingCart/Cart/GNRCartGoodsCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRCartGoodsCell.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/3. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRCartGoodsCell.h" 10 | #import "GNRGoodsModel.h" 11 | @implementation GNRCartGoodsCell 12 | 13 | 14 | - (void)drawRect:(CGRect)rect{ 15 | [super drawRect:rect]; 16 | CGContextRef context = UIGraphicsGetCurrentContext(); 17 | 18 | CGContextSetFillColorWithColor(context, [UIColor clearColor].CGColor); 19 | CGContextFillRect(context, rect); 20 | 21 | //下分割线 22 | CGContextSetStrokeColorWithColor(context, ([UIColor colorWithWhite:0.8 alpha:0.8]).CGColor); 23 | CGContextStrokeRect(context, CGRectMake(0, rect.size.height, rect.size.width, 0.4)); 24 | } 25 | 26 | - (GNRCountStepper *)stepper{ 27 | if (!_stepper) { 28 | _stepper = [[GNRCountStepper alloc]initWithFrame:CGRectZero]; 29 | _stepper.style = GNRCountStepperStyleShoppingCart; 30 | } 31 | return _stepper; 32 | } 33 | 34 | - (void)config:(GNRGoodsModel *)goods{ 35 | [self.stepperSuperView addSubview:self.stepper]; 36 | [self.stepper countChangedBlock:^(NSInteger count) { 37 | if (goods) { 38 | goods.number = @(count); 39 | _priceLabel.text = [NSString stringWithFormat:@"¥%.2f",goods.shouldPayMoney]; 40 | if ([_delegate respondsToSelector:@selector(stepper:valueChangedForCount:goods:)]) { 41 | [_delegate stepper:_stepper valueChangedForCount:count goods:goods]; 42 | } 43 | } 44 | }]; 45 | self.stepper.count = goods.number.integerValue; 46 | self.nameL.text = goods.goodsName; 47 | self.priceLabel.text = [NSString stringWithFormat:@"¥%.2f",goods.shouldPayMoney]; 48 | } 49 | 50 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 51 | [super setSelected:selected animated:animated]; 52 | // Configure the view for the selected state 53 | } 54 | 55 | - (void)layoutSubviews{ 56 | self.stepper.center = CGPointMake(_stepperSuperView.bounds.size.width/2.0, _stepperSuperView.bounds.size.height/2.0); 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /Takeaway/Views/ShoppingCart/Cart/GNRCartGoodsCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /Takeaway/Views/ShoppingCart/Cart/GNRCartHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRCartHeader.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/3. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GNRCartHeader : UIView 12 | 13 | @property (weak, nonatomic) IBOutlet UIButton *cleanBtn; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Takeaway/Views/ShoppingCart/Cart/GNRCartHeader.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRCartHeader.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/3. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRCartHeader.h" 10 | 11 | @implementation GNRCartHeader 12 | 13 | - (void)drawRect:(CGRect)rect{ 14 | self.layer.borderColor = [UIColor colorWithWhite:0.8 alpha:0.8].CGColor; 15 | self.layer.borderWidth = 0.4; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Takeaway/Views/ShoppingCart/Cart/GNRCartHeader.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 24 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Takeaway/Views/ShoppingCart/Cart/GNRShoppingCartView.h: -------------------------------------------------------------------------------- 1 | // 2 | // GNRShoppingCartView.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/3. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "GNRCartHeader.h" 11 | #import "GNRCartFooter.h" 12 | @class GNRGoodsListModel; 13 | 14 | @interface GNRShoppingCartView : UIView 15 | @property (nonatomic, assign)BOOL shown; 16 | @property (nonatomic, weak)id target; 17 | @property (nonatomic, strong)GNRGoodsListModel * goodsList; 18 | @property (nonatomic, strong)GNRCartHeader * header; 19 | @property (nonatomic, strong)GNRCartFooter * footer; 20 | @property (nonatomic, strong)UITableView * tableView; 21 | 22 | - (void)show; 23 | - (void)dismiss; 24 | - (void)reloadData; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Takeaway/Views/ShoppingCart/Cart/GNRShoppingCartView.m: -------------------------------------------------------------------------------- 1 | // 2 | // GNRShoppingCartView.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/3. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "GNRShoppingCartView.h" 10 | #import "GNRCartGoodsCell.h" 11 | #import "GNRGoodsListModel.h" 12 | 13 | @interface GNRShoppingCartView () 14 | { 15 | CGRect BOUNDS; 16 | CGFloat Height_Cell; 17 | CGFloat Height_Header; 18 | CGFloat Height_Footer; 19 | CGFloat Height_Max; 20 | CGFloat Height_TB; 21 | CGFloat Height_Default; 22 | CGFloat kDuration; 23 | } 24 | @property (nonatomic, strong)UIView * bgView; 25 | @property (nonatomic, strong)UIView * contentView; 26 | @end 27 | 28 | @implementation GNRShoppingCartView 29 | 30 | - (UIView *)bgView{ 31 | if (!_bgView) { 32 | _bgView = [[UIView alloc]initWithFrame:self.bounds]; 33 | _bgView.backgroundColor = [UIColor colorWithWhite:0.1 alpha:0]; 34 | UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapPressAction:)]; 35 | [_bgView addGestureRecognizer:tap]; 36 | } 37 | return _bgView; 38 | } 39 | 40 | - (void)tapPressAction:(UITapGestureRecognizer *)sender{ 41 | if (sender.state == UIGestureRecognizerStateEnded) { 42 | [self dismiss]; 43 | } 44 | } 45 | 46 | - (UIView *)contentView{ 47 | if (!_contentView) { 48 | _contentView = [[UIView alloc]initWithFrame:CGRectMake(0, BOUNDS.size.height, BOUNDS.size.width, Height_Default)]; 49 | _contentView.backgroundColor = [UIColor whiteColor]; 50 | } 51 | return _contentView; 52 | } 53 | 54 | - (GNRCartHeader *)header{ 55 | if (!_header) { 56 | _header = [[[NSBundle mainBundle]loadNibNamed:@"GNRCartHeader" owner:self options:nil]firstObject]; 57 | _header.frame = CGRectMake(0, 0, BOUNDS.size.width, Height_Header); 58 | 59 | } 60 | return _header; 61 | } 62 | 63 | - (GNRCartFooter *)footer{ 64 | if (!_footer) { 65 | _footer = [[[NSBundle mainBundle]loadNibNamed:@"GNRCartFooter" owner:self options:nil]firstObject]; 66 | _footer.frame = CGRectMake(0, self.tableView.frame.origin.y+self.tableView.frame.size.height, BOUNDS.size.width, Height_Footer); 67 | } 68 | return _footer; 69 | } 70 | 71 | - (UITableView *)tableView{ 72 | if (!_tableView) { 73 | _tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, self.header.bounds.size.height, BOUNDS.size.width, 0) style:UITableViewStylePlain]; 74 | _tableView.delegate = self; 75 | _tableView.dataSource = self; 76 | _tableView.bounces = NO; 77 | [self.contentView addSubview:_tableView]; 78 | } 79 | return _tableView; 80 | } 81 | 82 | - (instancetype)initWithFrame:(CGRect)frame{ 83 | self = [super initWithFrame:frame]; 84 | if (self) { 85 | [self initData]; 86 | [self installUI]; 87 | } 88 | return self; 89 | } 90 | 91 | - (void)initData{ 92 | self.hidden = YES; 93 | kDuration = 0.3; 94 | Height_Header = 32.f; 95 | Height_Footer = 26.f; 96 | Height_Cell = 50; 97 | BOUNDS = self.bounds; 98 | Height_Max = BOUNDS.size.height * 0.56; 99 | [self resizeHeight_TB]; 100 | Height_Default = Height_Header + Height_Footer + Height_TB; 101 | } 102 | 103 | - (void)resizeHeight_TB{ 104 | Height_TB = [[[self.goodsList.shoppingCart.bags firstObject] goodsArr] count] * Height_Cell; 105 | if (Height_TB>Height_Max) { 106 | Height_TB = Height_Max; 107 | } 108 | } 109 | 110 | - (void)installUI{ 111 | [self addSubview:self.bgView]; 112 | [self addSubview:self.contentView]; 113 | [self.contentView addSubview:self.header]; 114 | [self.contentView addSubview:self.tableView]; 115 | [self.contentView addSubview:self.footer]; 116 | } 117 | 118 | - (void)reloadData{ 119 | [self.tableView reloadData]; 120 | [self resetFrameAnimation]; 121 | } 122 | 123 | - (void)resetFrameAnimation{ 124 | [self resizeHeight_TB]; 125 | 126 | CGRect headerFrame = self.header.frame; 127 | headerFrame.origin.y = 0; 128 | 129 | CGRect footerFrame = self.footer.frame; 130 | footerFrame.origin.y = Height_TB + Height_Header; 131 | 132 | CGRect contentFrame = self.contentView.frame; 133 | contentFrame.origin.y = BOUNDS.size.height - Height_TB-Height_Footer-Height_Header; 134 | contentFrame.size.height = Height_TB+Height_Footer+Height_Header; 135 | 136 | CGRect tbFrame = self.tableView.frame; 137 | tbFrame.origin.y = Height_Header; 138 | tbFrame.size.height = Height_TB; 139 | 140 | [UIView animateWithDuration:kDuration delay:0.01 options:UIViewAnimationOptionCurveEaseOut animations:^{ 141 | self.contentView.frame = contentFrame; 142 | } completion:^(BOOL finished) { 143 | 144 | }]; 145 | [UIView animateWithDuration:kDuration delay:0.01 options:UIViewAnimationOptionCurveEaseOut animations:^{ 146 | self.header.frame = headerFrame; 147 | self.tableView.frame = tbFrame; 148 | self.footer.frame = footerFrame; 149 | } completion:^(BOOL finished) { 150 | 151 | }]; 152 | } 153 | 154 | - (void)show{ 155 | _shown = YES; 156 | self.hidden = NO; 157 | 158 | [UIView animateWithDuration:kDuration delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ 159 | self.bgView.backgroundColor = [UIColor colorWithWhite:0.1 alpha:0.6]; 160 | } completion:^(BOOL finished) { 161 | 162 | }]; 163 | 164 | [self reloadData]; 165 | } 166 | 167 | 168 | - (void)dismiss{ 169 | _shown = NO; 170 | [UIView animateWithDuration:kDuration delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ 171 | self.bgView.backgroundColor = [UIColor colorWithWhite:0.2 alpha:0]; 172 | self.contentView.frame = CGRectMake(self.contentView.frame.origin.x, BOUNDS.size.height, self.contentView.bounds.size.width, self.contentView.bounds.size.height); 173 | } completion:^(BOOL finished) { 174 | self.hidden = YES; 175 | }]; 176 | } 177 | 178 | #pragma mark - delegate 179 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 180 | return [[self.goodsList.shoppingCart.bags.firstObject goodsArr] count]; 181 | } 182 | 183 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 184 | GNRCartGoodsCell * cell = [tableView dequeueReusableCellWithIdentifier:@"GNRCartGoodsCell"]; 185 | if (cell==nil) { 186 | cell = [[[NSBundle mainBundle]loadNibNamed:@"GNRCartGoodsCell" owner:self options:nil]firstObject]; 187 | } 188 | GNRGoodsModel * goods = [self.goodsList.shoppingCart.bags.firstObject goodsArr][indexPath.row]; 189 | cell.delegate = _target;//交给controller处理 190 | [cell config:goods]; 191 | return cell; 192 | } 193 | 194 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 195 | return Height_Cell; 196 | } 197 | 198 | @end 199 | -------------------------------------------------------------------------------- /Takeaway/Views/ShoppingCart/GNRCartDefine.h: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // GNRCartDefine.h 4 | // 外卖 5 | // 6 | // Created by LvYuan on 2017/5/4. 7 | // Copyright © 2017年 BattlePetal. All rights reserved. 8 | // 9 | 10 | #ifndef GNRCartDefine_h 11 | #define GNRCartDefine_h 12 | 13 | #import "GNRGoodsListModel.h" 14 | @class GNRCountStepper; 15 | 16 | //stepper风格 17 | typedef NS_ENUM(NSInteger,GNRCountStepperStyle) { 18 | GNRCountStepperStyleGoodsList,//商品列表中的 19 | GNRCountStepperStyleShoppingCart,//购物车中的 20 | }; 21 | 22 | //购物栏风格 23 | typedef NS_ENUM(NSInteger, GNRShoppingBarStyle) { 24 | GNRShoppingBarStyleDefault, 25 | }; 26 | 27 | @protocol GNRGoodsNumberChangedDelegate 28 | 29 | - (void)stepper:(GNRCountStepper *)stepper valueChangedForCount:(NSInteger)count goods:(GNRGoodsModel *)goods; 30 | 31 | - (void)stepper:(GNRCountStepper *)stepper addSender:(UIButton *)sender cell:(UITableViewCell *)cell; 32 | 33 | - (void)stepper:(GNRCountStepper *)stepper subSender:(UIButton *)sender cell:(UITableViewCell *)cell; 34 | 35 | @end 36 | 37 | #import "GNRCountStepper.h" 38 | #import "GNRShoppingCartView.h" 39 | 40 | #endif /* GNRCartDefine_h */ 41 | -------------------------------------------------------------------------------- /record.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/record.gif -------------------------------------------------------------------------------- /外卖.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | D91945371EB8391D00FFD132 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D91945361EB8391D00FFD132 /* main.m */; }; 11 | D919453A1EB8391D00FFD132 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D91945391EB8391D00FFD132 /* AppDelegate.m */; }; 12 | D91945421EB8391D00FFD132 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D91945411EB8391D00FFD132 /* Assets.xcassets */; }; 13 | D91945451EB8391D00FFD132 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D91945431EB8391D00FFD132 /* LaunchScreen.storyboard */; }; 14 | D91945501EB8391D00FFD132 /* __Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = D919454F1EB8391D00FFD132 /* __Tests.m */; }; 15 | D919455B1EB8391D00FFD132 /* __UITests.m in Sources */ = {isa = PBXBuildFile; fileRef = D919455A1EB8391D00FFD132 /* __UITests.m */; }; 16 | D919456E1EB8398C00FFD132 /* GNRShopListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D919456D1EB8398C00FFD132 /* GNRShopListViewController.m */; }; 17 | D91945701EB839A000FFD132 /* Takeaway.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D919456F1EB839A000FFD132 /* Takeaway.storyboard */; }; 18 | D91945741EB85FFF00FFD132 /* GNRShopListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D91945721EB85FFF00FFD132 /* GNRShopListCell.m */; }; 19 | D91945751EB85FFF00FFD132 /* GNRShopListCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D91945731EB85FFF00FFD132 /* GNRShopListCell.xib */; }; 20 | D91945791EB8655700FFD132 /* GNRTitleHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = D91945781EB8655700FFD132 /* GNRTitleHeader.m */; }; 21 | D919457C1EB868C900FFD132 /* GNRGoodsListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D919457B1EB868C900FFD132 /* GNRGoodsListViewController.m */; }; 22 | D943D9051EBB1D81002D52CE /* GNRCartFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = D943D9031EBB1D81002D52CE /* GNRCartFooter.m */; }; 23 | D943D9061EBB1D81002D52CE /* GNRCartFooter.xib in Resources */ = {isa = PBXBuildFile; fileRef = D943D9041EBB1D81002D52CE /* GNRCartFooter.xib */; }; 24 | D9AD5E141EB86EAA00E65F65 /* GNRLinkageTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = D9AD5E0C1EB86EAA00E65F65 /* GNRLinkageTableView.m */; }; 25 | D9AD5E151EB86EAA00E65F65 /* GNRGoodsGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = D9AD5E0F1EB86EAA00E65F65 /* GNRGoodsGroup.m */; }; 26 | D9AD5E161EB86EAA00E65F65 /* GNRGoodsListModel.m in Sources */ = {isa = PBXBuildFile; fileRef = D9AD5E111EB86EAA00E65F65 /* GNRGoodsListModel.m */; }; 27 | D9AD5E171EB86EAA00E65F65 /* GNRGoodsModel.m in Sources */ = {isa = PBXBuildFile; fileRef = D9AD5E131EB86EAA00E65F65 /* GNRGoodsModel.m */; }; 28 | D9AD5E1C1EB86EFA00E65F65 /* GNRGoodsIndexCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D9AD5E1A1EB86EFA00E65F65 /* GNRGoodsIndexCell.m */; }; 29 | D9AD5E1D1EB86EFA00E65F65 /* GNRGoodsIndexCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D9AD5E1B1EB86EFA00E65F65 /* GNRGoodsIndexCell.xib */; }; 30 | D9AD5E211EB8778500E65F65 /* GNRGoodsListCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D9AD5E1F1EB8778500E65F65 /* GNRGoodsListCell.m */; }; 31 | D9AD5E221EB8778500E65F65 /* GNRGoodsListCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D9AD5E201EB8778500E65F65 /* GNRGoodsListCell.xib */; }; 32 | D9AD5E261EB879A200E65F65 /* GNRCountStepper.m in Sources */ = {isa = PBXBuildFile; fileRef = D9AD5E251EB879A200E65F65 /* GNRCountStepper.m */; }; 33 | D9AD5E2A1EB8809B00E65F65 /* GNRSectionHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = D9AD5E291EB8809B00E65F65 /* GNRSectionHeader.m */; }; 34 | D9AD5E2C1EB880A400E65F65 /* GNRSectionHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = D9AD5E2B1EB880A400E65F65 /* GNRSectionHeader.xib */; }; 35 | D9B470A31EB96B8E006AA500 /* UINavigationBar+Awesome.m in Sources */ = {isa = PBXBuildFile; fileRef = D9B470A21EB96B8E006AA500 /* UINavigationBar+Awesome.m */; }; 36 | D9B470A61EB96E61006AA500 /* GNRShopHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = D9B470A51EB96E61006AA500 /* GNRShopHeader.m */; }; 37 | D9B470A81EB96E68006AA500 /* GNRShopHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = D9B470A71EB96E68006AA500 /* GNRShopHeader.xib */; }; 38 | D9B470AE1EB9B3DD006AA500 /* GNRShoppingBar.m in Sources */ = {isa = PBXBuildFile; fileRef = D9B470AD1EB9B3DD006AA500 /* GNRShoppingBar.m */; }; 39 | D9B470B11EB9B563006AA500 /* GNRShoppingBarView.m in Sources */ = {isa = PBXBuildFile; fileRef = D9B470B01EB9B563006AA500 /* GNRShoppingBarView.m */; }; 40 | D9B470B31EB9B569006AA500 /* GNRShoppingBarView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D9B470B21EB9B569006AA500 /* GNRShoppingBarView.xib */; }; 41 | D9B470B81EB9C8E9006AA500 /* GNRShoppingBag.m in Sources */ = {isa = PBXBuildFile; fileRef = D9B470B71EB9C8E9006AA500 /* GNRShoppingBag.m */; }; 42 | D9B470BB1EB9C902006AA500 /* GNRShoppingCart.m in Sources */ = {isa = PBXBuildFile; fileRef = D9B470BA1EB9C902006AA500 /* GNRShoppingCart.m */; }; 43 | D9B470C21EB9DD68006AA500 /* GNRShoppingCartView.m in Sources */ = {isa = PBXBuildFile; fileRef = D9B470C11EB9DD68006AA500 /* GNRShoppingCartView.m */; }; 44 | D9B470C51EB9E481006AA500 /* GNRCartHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = D9B470C41EB9E481006AA500 /* GNRCartHeader.m */; }; 45 | D9B470C71EB9E48B006AA500 /* GNRCartHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = D9B470C61EB9E48B006AA500 /* GNRCartHeader.xib */; }; 46 | D9B470CB1EB9E941006AA500 /* GNRCartGoodsCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D9B470C91EB9E941006AA500 /* GNRCartGoodsCell.m */; }; 47 | D9B470CC1EB9E941006AA500 /* GNRCartGoodsCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D9B470CA1EB9E941006AA500 /* GNRCartGoodsCell.xib */; }; 48 | /* End PBXBuildFile section */ 49 | 50 | /* Begin PBXContainerItemProxy section */ 51 | D919454C1EB8391D00FFD132 /* PBXContainerItemProxy */ = { 52 | isa = PBXContainerItemProxy; 53 | containerPortal = D919452A1EB8391D00FFD132 /* Project object */; 54 | proxyType = 1; 55 | remoteGlobalIDString = D91945311EB8391D00FFD132; 56 | remoteInfo = "外卖"; 57 | }; 58 | D91945571EB8391D00FFD132 /* PBXContainerItemProxy */ = { 59 | isa = PBXContainerItemProxy; 60 | containerPortal = D919452A1EB8391D00FFD132 /* Project object */; 61 | proxyType = 1; 62 | remoteGlobalIDString = D91945311EB8391D00FFD132; 63 | remoteInfo = "外卖"; 64 | }; 65 | /* End PBXContainerItemProxy section */ 66 | 67 | /* Begin PBXFileReference section */ 68 | D91945321EB8391D00FFD132 /* 外卖.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "外卖.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 69 | D91945361EB8391D00FFD132 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 70 | D91945381EB8391D00FFD132 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 71 | D91945391EB8391D00FFD132 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 72 | D91945411EB8391D00FFD132 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 73 | D91945441EB8391D00FFD132 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 74 | D91945461EB8391D00FFD132 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 75 | D919454B1EB8391D00FFD132 /* 外卖Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "外卖Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 76 | D919454F1EB8391D00FFD132 /* __Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = __Tests.m; sourceTree = ""; }; 77 | D91945511EB8391D00FFD132 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 78 | D91945561EB8391D00FFD132 /* 外卖UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "外卖UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 79 | D919455A1EB8391D00FFD132 /* __UITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = __UITests.m; sourceTree = ""; }; 80 | D919455C1EB8391D00FFD132 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 81 | D919456C1EB8398C00FFD132 /* GNRShopListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRShopListViewController.h; sourceTree = ""; }; 82 | D919456D1EB8398C00FFD132 /* GNRShopListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRShopListViewController.m; sourceTree = ""; }; 83 | D919456F1EB839A000FFD132 /* Takeaway.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Takeaway.storyboard; sourceTree = ""; }; 84 | D91945711EB85FFF00FFD132 /* GNRShopListCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRShopListCell.h; sourceTree = ""; }; 85 | D91945721EB85FFF00FFD132 /* GNRShopListCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRShopListCell.m; sourceTree = ""; }; 86 | D91945731EB85FFF00FFD132 /* GNRShopListCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GNRShopListCell.xib; sourceTree = ""; }; 87 | D91945771EB8655700FFD132 /* GNRTitleHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRTitleHeader.h; sourceTree = ""; }; 88 | D91945781EB8655700FFD132 /* GNRTitleHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRTitleHeader.m; sourceTree = ""; }; 89 | D919457A1EB868C900FFD132 /* GNRGoodsListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRGoodsListViewController.h; sourceTree = ""; }; 90 | D919457B1EB868C900FFD132 /* GNRGoodsListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRGoodsListViewController.m; sourceTree = ""; }; 91 | D943D9021EBB1D81002D52CE /* GNRCartFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRCartFooter.h; sourceTree = ""; }; 92 | D943D9031EBB1D81002D52CE /* GNRCartFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRCartFooter.m; sourceTree = ""; }; 93 | D943D9041EBB1D81002D52CE /* GNRCartFooter.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GNRCartFooter.xib; sourceTree = ""; }; 94 | D943D9081EBB2320002D52CE /* GNRCartDefine.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GNRCartDefine.h; sourceTree = ""; }; 95 | D9AD5E0B1EB86EAA00E65F65 /* GNRLinkageTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRLinkageTableView.h; sourceTree = ""; }; 96 | D9AD5E0C1EB86EAA00E65F65 /* GNRLinkageTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRLinkageTableView.m; sourceTree = ""; }; 97 | D9AD5E0E1EB86EAA00E65F65 /* GNRGoodsGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRGoodsGroup.h; sourceTree = ""; }; 98 | D9AD5E0F1EB86EAA00E65F65 /* GNRGoodsGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRGoodsGroup.m; sourceTree = ""; }; 99 | D9AD5E101EB86EAA00E65F65 /* GNRGoodsListModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRGoodsListModel.h; sourceTree = ""; }; 100 | D9AD5E111EB86EAA00E65F65 /* GNRGoodsListModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRGoodsListModel.m; sourceTree = ""; }; 101 | D9AD5E121EB86EAA00E65F65 /* GNRGoodsModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRGoodsModel.h; sourceTree = ""; }; 102 | D9AD5E131EB86EAA00E65F65 /* GNRGoodsModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRGoodsModel.m; sourceTree = ""; }; 103 | D9AD5E191EB86EFA00E65F65 /* GNRGoodsIndexCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRGoodsIndexCell.h; sourceTree = ""; }; 104 | D9AD5E1A1EB86EFA00E65F65 /* GNRGoodsIndexCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRGoodsIndexCell.m; sourceTree = ""; }; 105 | D9AD5E1B1EB86EFA00E65F65 /* GNRGoodsIndexCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GNRGoodsIndexCell.xib; sourceTree = ""; }; 106 | D9AD5E1E1EB8778500E65F65 /* GNRGoodsListCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRGoodsListCell.h; sourceTree = ""; }; 107 | D9AD5E1F1EB8778500E65F65 /* GNRGoodsListCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRGoodsListCell.m; sourceTree = ""; }; 108 | D9AD5E201EB8778500E65F65 /* GNRGoodsListCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GNRGoodsListCell.xib; sourceTree = ""; }; 109 | D9AD5E241EB879A200E65F65 /* GNRCountStepper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRCountStepper.h; sourceTree = ""; }; 110 | D9AD5E251EB879A200E65F65 /* GNRCountStepper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRCountStepper.m; sourceTree = ""; }; 111 | D9AD5E281EB8809B00E65F65 /* GNRSectionHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRSectionHeader.h; sourceTree = ""; }; 112 | D9AD5E291EB8809B00E65F65 /* GNRSectionHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRSectionHeader.m; sourceTree = ""; }; 113 | D9AD5E2B1EB880A400E65F65 /* GNRSectionHeader.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GNRSectionHeader.xib; sourceTree = ""; }; 114 | D9B470A11EB96B8E006AA500 /* UINavigationBar+Awesome.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UINavigationBar+Awesome.h"; sourceTree = ""; }; 115 | D9B470A21EB96B8E006AA500 /* UINavigationBar+Awesome.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UINavigationBar+Awesome.m"; sourceTree = ""; }; 116 | D9B470A41EB96E61006AA500 /* GNRShopHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRShopHeader.h; sourceTree = ""; }; 117 | D9B470A51EB96E61006AA500 /* GNRShopHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRShopHeader.m; sourceTree = ""; }; 118 | D9B470A71EB96E68006AA500 /* GNRShopHeader.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GNRShopHeader.xib; sourceTree = ""; }; 119 | D9B470AC1EB9B3DD006AA500 /* GNRShoppingBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRShoppingBar.h; sourceTree = ""; }; 120 | D9B470AD1EB9B3DD006AA500 /* GNRShoppingBar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRShoppingBar.m; sourceTree = ""; }; 121 | D9B470AF1EB9B563006AA500 /* GNRShoppingBarView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRShoppingBarView.h; sourceTree = ""; }; 122 | D9B470B01EB9B563006AA500 /* GNRShoppingBarView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRShoppingBarView.m; sourceTree = ""; }; 123 | D9B470B21EB9B569006AA500 /* GNRShoppingBarView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GNRShoppingBarView.xib; sourceTree = ""; }; 124 | D9B470B61EB9C8E9006AA500 /* GNRShoppingBag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRShoppingBag.h; sourceTree = ""; }; 125 | D9B470B71EB9C8E9006AA500 /* GNRShoppingBag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRShoppingBag.m; sourceTree = ""; }; 126 | D9B470B91EB9C902006AA500 /* GNRShoppingCart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRShoppingCart.h; sourceTree = ""; }; 127 | D9B470BA1EB9C902006AA500 /* GNRShoppingCart.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRShoppingCart.m; sourceTree = ""; }; 128 | D9B470C01EB9DD68006AA500 /* GNRShoppingCartView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRShoppingCartView.h; sourceTree = ""; }; 129 | D9B470C11EB9DD68006AA500 /* GNRShoppingCartView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRShoppingCartView.m; sourceTree = ""; }; 130 | D9B470C31EB9E481006AA500 /* GNRCartHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRCartHeader.h; sourceTree = ""; }; 131 | D9B470C41EB9E481006AA500 /* GNRCartHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRCartHeader.m; sourceTree = ""; }; 132 | D9B470C61EB9E48B006AA500 /* GNRCartHeader.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GNRCartHeader.xib; sourceTree = ""; }; 133 | D9B470C81EB9E941006AA500 /* GNRCartGoodsCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GNRCartGoodsCell.h; sourceTree = ""; }; 134 | D9B470C91EB9E941006AA500 /* GNRCartGoodsCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GNRCartGoodsCell.m; sourceTree = ""; }; 135 | D9B470CA1EB9E941006AA500 /* GNRCartGoodsCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = GNRCartGoodsCell.xib; sourceTree = ""; }; 136 | /* End PBXFileReference section */ 137 | 138 | /* Begin PBXFrameworksBuildPhase section */ 139 | D919452F1EB8391D00FFD132 /* Frameworks */ = { 140 | isa = PBXFrameworksBuildPhase; 141 | buildActionMask = 2147483647; 142 | files = ( 143 | ); 144 | runOnlyForDeploymentPostprocessing = 0; 145 | }; 146 | D91945481EB8391D00FFD132 /* Frameworks */ = { 147 | isa = PBXFrameworksBuildPhase; 148 | buildActionMask = 2147483647; 149 | files = ( 150 | ); 151 | runOnlyForDeploymentPostprocessing = 0; 152 | }; 153 | D91945531EB8391D00FFD132 /* Frameworks */ = { 154 | isa = PBXFrameworksBuildPhase; 155 | buildActionMask = 2147483647; 156 | files = ( 157 | ); 158 | runOnlyForDeploymentPostprocessing = 0; 159 | }; 160 | /* End PBXFrameworksBuildPhase section */ 161 | 162 | /* Begin PBXGroup section */ 163 | D91945291EB8391D00FFD132 = { 164 | isa = PBXGroup; 165 | children = ( 166 | D9B470A01EB96B8D006AA500 /* GNRTools */, 167 | D91945681EB8394E00FFD132 /* Takeaway */, 168 | D91945341EB8391D00FFD132 /* 外卖 */, 169 | D919454E1EB8391D00FFD132 /* 外卖Tests */, 170 | D91945591EB8391D00FFD132 /* 外卖UITests */, 171 | D91945331EB8391D00FFD132 /* Products */, 172 | ); 173 | sourceTree = ""; 174 | }; 175 | D91945331EB8391D00FFD132 /* Products */ = { 176 | isa = PBXGroup; 177 | children = ( 178 | D91945321EB8391D00FFD132 /* 外卖.app */, 179 | D919454B1EB8391D00FFD132 /* 外卖Tests.xctest */, 180 | D91945561EB8391D00FFD132 /* 外卖UITests.xctest */, 181 | ); 182 | name = Products; 183 | sourceTree = ""; 184 | }; 185 | D91945341EB8391D00FFD132 /* 外卖 */ = { 186 | isa = PBXGroup; 187 | children = ( 188 | D91945381EB8391D00FFD132 /* AppDelegate.h */, 189 | D91945391EB8391D00FFD132 /* AppDelegate.m */, 190 | D91945411EB8391D00FFD132 /* Assets.xcassets */, 191 | D91945431EB8391D00FFD132 /* LaunchScreen.storyboard */, 192 | D91945461EB8391D00FFD132 /* Info.plist */, 193 | D91945351EB8391D00FFD132 /* Supporting Files */, 194 | ); 195 | path = "外卖"; 196 | sourceTree = ""; 197 | }; 198 | D91945351EB8391D00FFD132 /* Supporting Files */ = { 199 | isa = PBXGroup; 200 | children = ( 201 | D91945361EB8391D00FFD132 /* main.m */, 202 | ); 203 | name = "Supporting Files"; 204 | sourceTree = ""; 205 | }; 206 | D919454E1EB8391D00FFD132 /* 外卖Tests */ = { 207 | isa = PBXGroup; 208 | children = ( 209 | D919454F1EB8391D00FFD132 /* __Tests.m */, 210 | D91945511EB8391D00FFD132 /* Info.plist */, 211 | ); 212 | path = "外卖Tests"; 213 | sourceTree = ""; 214 | }; 215 | D91945591EB8391D00FFD132 /* 外卖UITests */ = { 216 | isa = PBXGroup; 217 | children = ( 218 | D919455A1EB8391D00FFD132 /* __UITests.m */, 219 | D919455C1EB8391D00FFD132 /* Info.plist */, 220 | ); 221 | path = "外卖UITests"; 222 | sourceTree = ""; 223 | }; 224 | D91945681EB8394E00FFD132 /* Takeaway */ = { 225 | isa = PBXGroup; 226 | children = ( 227 | D91945761EB8654600FFD132 /* Views */, 228 | D91945691EB8396E00FFD132 /* Cells */, 229 | D919456A1EB8396E00FFD132 /* Classes */, 230 | D919456B1EB8396E00FFD132 /* Models */, 231 | D919456F1EB839A000FFD132 /* Takeaway.storyboard */, 232 | ); 233 | path = Takeaway; 234 | sourceTree = ""; 235 | }; 236 | D91945691EB8396E00FFD132 /* Cells */ = { 237 | isa = PBXGroup; 238 | children = ( 239 | D91945711EB85FFF00FFD132 /* GNRShopListCell.h */, 240 | D91945721EB85FFF00FFD132 /* GNRShopListCell.m */, 241 | D91945731EB85FFF00FFD132 /* GNRShopListCell.xib */, 242 | ); 243 | path = Cells; 244 | sourceTree = ""; 245 | }; 246 | D919456A1EB8396E00FFD132 /* Classes */ = { 247 | isa = PBXGroup; 248 | children = ( 249 | D919456C1EB8398C00FFD132 /* GNRShopListViewController.h */, 250 | D919456D1EB8398C00FFD132 /* GNRShopListViewController.m */, 251 | D919457A1EB868C900FFD132 /* GNRGoodsListViewController.h */, 252 | D919457B1EB868C900FFD132 /* GNRGoodsListViewController.m */, 253 | ); 254 | path = Classes; 255 | sourceTree = ""; 256 | }; 257 | D919456B1EB8396E00FFD132 /* Models */ = { 258 | isa = PBXGroup; 259 | children = ( 260 | ); 261 | path = Models; 262 | sourceTree = ""; 263 | }; 264 | D91945761EB8654600FFD132 /* Views */ = { 265 | isa = PBXGroup; 266 | children = ( 267 | D9B470A91EB9B0E0006AA500 /* ShoppingCart */, 268 | D9AD5E0A1EB86EAA00E65F65 /* GNRLinkageTableView */, 269 | D91945771EB8655700FFD132 /* GNRTitleHeader.h */, 270 | D91945781EB8655700FFD132 /* GNRTitleHeader.m */, 271 | ); 272 | path = Views; 273 | sourceTree = ""; 274 | }; 275 | D9AD5E0A1EB86EAA00E65F65 /* GNRLinkageTableView */ = { 276 | isa = PBXGroup; 277 | children = ( 278 | D9AD5E271EB8805A00E65F65 /* Views */, 279 | D9AD5E231EB8799300E65F65 /* Stepper */, 280 | D9AD5E181EB86ED500E65F65 /* Cells */, 281 | D9AD5E0B1EB86EAA00E65F65 /* GNRLinkageTableView.h */, 282 | D9AD5E0C1EB86EAA00E65F65 /* GNRLinkageTableView.m */, 283 | D9AD5E0D1EB86EAA00E65F65 /* Models */, 284 | ); 285 | path = GNRLinkageTableView; 286 | sourceTree = ""; 287 | }; 288 | D9AD5E0D1EB86EAA00E65F65 /* Models */ = { 289 | isa = PBXGroup; 290 | children = ( 291 | D9AD5E0E1EB86EAA00E65F65 /* GNRGoodsGroup.h */, 292 | D9AD5E0F1EB86EAA00E65F65 /* GNRGoodsGroup.m */, 293 | D9AD5E101EB86EAA00E65F65 /* GNRGoodsListModel.h */, 294 | D9AD5E111EB86EAA00E65F65 /* GNRGoodsListModel.m */, 295 | D9AD5E121EB86EAA00E65F65 /* GNRGoodsModel.h */, 296 | D9AD5E131EB86EAA00E65F65 /* GNRGoodsModel.m */, 297 | D9B470B91EB9C902006AA500 /* GNRShoppingCart.h */, 298 | D9B470BA1EB9C902006AA500 /* GNRShoppingCart.m */, 299 | D9B470B61EB9C8E9006AA500 /* GNRShoppingBag.h */, 300 | D9B470B71EB9C8E9006AA500 /* GNRShoppingBag.m */, 301 | ); 302 | path = Models; 303 | sourceTree = ""; 304 | }; 305 | D9AD5E181EB86ED500E65F65 /* Cells */ = { 306 | isa = PBXGroup; 307 | children = ( 308 | D9AD5E191EB86EFA00E65F65 /* GNRGoodsIndexCell.h */, 309 | D9AD5E1A1EB86EFA00E65F65 /* GNRGoodsIndexCell.m */, 310 | D9AD5E1B1EB86EFA00E65F65 /* GNRGoodsIndexCell.xib */, 311 | D9AD5E1E1EB8778500E65F65 /* GNRGoodsListCell.h */, 312 | D9AD5E1F1EB8778500E65F65 /* GNRGoodsListCell.m */, 313 | D9AD5E201EB8778500E65F65 /* GNRGoodsListCell.xib */, 314 | ); 315 | path = Cells; 316 | sourceTree = ""; 317 | }; 318 | D9AD5E231EB8799300E65F65 /* Stepper */ = { 319 | isa = PBXGroup; 320 | children = ( 321 | D9AD5E241EB879A200E65F65 /* GNRCountStepper.h */, 322 | D9AD5E251EB879A200E65F65 /* GNRCountStepper.m */, 323 | ); 324 | path = Stepper; 325 | sourceTree = ""; 326 | }; 327 | D9AD5E271EB8805A00E65F65 /* Views */ = { 328 | isa = PBXGroup; 329 | children = ( 330 | D9AD5E281EB8809B00E65F65 /* GNRSectionHeader.h */, 331 | D9AD5E291EB8809B00E65F65 /* GNRSectionHeader.m */, 332 | D9AD5E2B1EB880A400E65F65 /* GNRSectionHeader.xib */, 333 | D9B470A41EB96E61006AA500 /* GNRShopHeader.h */, 334 | D9B470A51EB96E61006AA500 /* GNRShopHeader.m */, 335 | D9B470A71EB96E68006AA500 /* GNRShopHeader.xib */, 336 | ); 337 | path = Views; 338 | sourceTree = ""; 339 | }; 340 | D9B470A01EB96B8D006AA500 /* GNRTools */ = { 341 | isa = PBXGroup; 342 | children = ( 343 | D9B470A11EB96B8E006AA500 /* UINavigationBar+Awesome.h */, 344 | D9B470A21EB96B8E006AA500 /* UINavigationBar+Awesome.m */, 345 | ); 346 | path = GNRTools; 347 | sourceTree = ""; 348 | }; 349 | D9B470A91EB9B0E0006AA500 /* ShoppingCart */ = { 350 | isa = PBXGroup; 351 | children = ( 352 | D9B470B51EB9C083006AA500 /* Utils */, 353 | D9B470AA1EB9B0E0006AA500 /* Bar */, 354 | D9B470AB1EB9B0E0006AA500 /* Cart */, 355 | D943D9081EBB2320002D52CE /* GNRCartDefine.h */, 356 | ); 357 | path = ShoppingCart; 358 | sourceTree = ""; 359 | }; 360 | D9B470AA1EB9B0E0006AA500 /* Bar */ = { 361 | isa = PBXGroup; 362 | children = ( 363 | D9B470AC1EB9B3DD006AA500 /* GNRShoppingBar.h */, 364 | D9B470AD1EB9B3DD006AA500 /* GNRShoppingBar.m */, 365 | D9B470AF1EB9B563006AA500 /* GNRShoppingBarView.h */, 366 | D9B470B01EB9B563006AA500 /* GNRShoppingBarView.m */, 367 | D9B470B21EB9B569006AA500 /* GNRShoppingBarView.xib */, 368 | ); 369 | path = Bar; 370 | sourceTree = ""; 371 | }; 372 | D9B470AB1EB9B0E0006AA500 /* Cart */ = { 373 | isa = PBXGroup; 374 | children = ( 375 | D9B470C01EB9DD68006AA500 /* GNRShoppingCartView.h */, 376 | D9B470C11EB9DD68006AA500 /* GNRShoppingCartView.m */, 377 | D9B470C31EB9E481006AA500 /* GNRCartHeader.h */, 378 | D9B470C41EB9E481006AA500 /* GNRCartHeader.m */, 379 | D9B470C61EB9E48B006AA500 /* GNRCartHeader.xib */, 380 | D943D9021EBB1D81002D52CE /* GNRCartFooter.h */, 381 | D943D9031EBB1D81002D52CE /* GNRCartFooter.m */, 382 | D943D9041EBB1D81002D52CE /* GNRCartFooter.xib */, 383 | D9B470C81EB9E941006AA500 /* GNRCartGoodsCell.h */, 384 | D9B470C91EB9E941006AA500 /* GNRCartGoodsCell.m */, 385 | D9B470CA1EB9E941006AA500 /* GNRCartGoodsCell.xib */, 386 | ); 387 | path = Cart; 388 | sourceTree = ""; 389 | }; 390 | D9B470B51EB9C083006AA500 /* Utils */ = { 391 | isa = PBXGroup; 392 | children = ( 393 | ); 394 | path = Utils; 395 | sourceTree = ""; 396 | }; 397 | /* End PBXGroup section */ 398 | 399 | /* Begin PBXNativeTarget section */ 400 | D91945311EB8391D00FFD132 /* 外卖 */ = { 401 | isa = PBXNativeTarget; 402 | buildConfigurationList = D919455F1EB8391D00FFD132 /* Build configuration list for PBXNativeTarget "外卖" */; 403 | buildPhases = ( 404 | D919452E1EB8391D00FFD132 /* Sources */, 405 | D919452F1EB8391D00FFD132 /* Frameworks */, 406 | D91945301EB8391D00FFD132 /* Resources */, 407 | ); 408 | buildRules = ( 409 | ); 410 | dependencies = ( 411 | ); 412 | name = "外卖"; 413 | productName = "外卖"; 414 | productReference = D91945321EB8391D00FFD132 /* 外卖.app */; 415 | productType = "com.apple.product-type.application"; 416 | }; 417 | D919454A1EB8391D00FFD132 /* 外卖Tests */ = { 418 | isa = PBXNativeTarget; 419 | buildConfigurationList = D91945621EB8391D00FFD132 /* Build configuration list for PBXNativeTarget "外卖Tests" */; 420 | buildPhases = ( 421 | D91945471EB8391D00FFD132 /* Sources */, 422 | D91945481EB8391D00FFD132 /* Frameworks */, 423 | D91945491EB8391D00FFD132 /* Resources */, 424 | ); 425 | buildRules = ( 426 | ); 427 | dependencies = ( 428 | D919454D1EB8391D00FFD132 /* PBXTargetDependency */, 429 | ); 430 | name = "外卖Tests"; 431 | productName = "外卖Tests"; 432 | productReference = D919454B1EB8391D00FFD132 /* 外卖Tests.xctest */; 433 | productType = "com.apple.product-type.bundle.unit-test"; 434 | }; 435 | D91945551EB8391D00FFD132 /* 外卖UITests */ = { 436 | isa = PBXNativeTarget; 437 | buildConfigurationList = D91945651EB8391D00FFD132 /* Build configuration list for PBXNativeTarget "外卖UITests" */; 438 | buildPhases = ( 439 | D91945521EB8391D00FFD132 /* Sources */, 440 | D91945531EB8391D00FFD132 /* Frameworks */, 441 | D91945541EB8391D00FFD132 /* Resources */, 442 | ); 443 | buildRules = ( 444 | ); 445 | dependencies = ( 446 | D91945581EB8391D00FFD132 /* PBXTargetDependency */, 447 | ); 448 | name = "外卖UITests"; 449 | productName = "外卖UITests"; 450 | productReference = D91945561EB8391D00FFD132 /* 外卖UITests.xctest */; 451 | productType = "com.apple.product-type.bundle.ui-testing"; 452 | }; 453 | /* End PBXNativeTarget section */ 454 | 455 | /* Begin PBXProject section */ 456 | D919452A1EB8391D00FFD132 /* Project object */ = { 457 | isa = PBXProject; 458 | attributes = { 459 | LastUpgradeCheck = 0830; 460 | ORGANIZATIONNAME = BattlePetal; 461 | TargetAttributes = { 462 | D91945311EB8391D00FFD132 = { 463 | CreatedOnToolsVersion = 8.3; 464 | DevelopmentTeam = 3637NJMX7D; 465 | ProvisioningStyle = Automatic; 466 | }; 467 | D919454A1EB8391D00FFD132 = { 468 | CreatedOnToolsVersion = 8.3; 469 | DevelopmentTeam = 3637NJMX7D; 470 | ProvisioningStyle = Automatic; 471 | TestTargetID = D91945311EB8391D00FFD132; 472 | }; 473 | D91945551EB8391D00FFD132 = { 474 | CreatedOnToolsVersion = 8.3; 475 | DevelopmentTeam = 3637NJMX7D; 476 | ProvisioningStyle = Automatic; 477 | TestTargetID = D91945311EB8391D00FFD132; 478 | }; 479 | }; 480 | }; 481 | buildConfigurationList = D919452D1EB8391D00FFD132 /* Build configuration list for PBXProject "外卖" */; 482 | compatibilityVersion = "Xcode 3.2"; 483 | developmentRegion = English; 484 | hasScannedForEncodings = 0; 485 | knownRegions = ( 486 | en, 487 | Base, 488 | ); 489 | mainGroup = D91945291EB8391D00FFD132; 490 | productRefGroup = D91945331EB8391D00FFD132 /* Products */; 491 | projectDirPath = ""; 492 | projectRoot = ""; 493 | targets = ( 494 | D91945311EB8391D00FFD132 /* 外卖 */, 495 | D919454A1EB8391D00FFD132 /* 外卖Tests */, 496 | D91945551EB8391D00FFD132 /* 外卖UITests */, 497 | ); 498 | }; 499 | /* End PBXProject section */ 500 | 501 | /* Begin PBXResourcesBuildPhase section */ 502 | D91945301EB8391D00FFD132 /* Resources */ = { 503 | isa = PBXResourcesBuildPhase; 504 | buildActionMask = 2147483647; 505 | files = ( 506 | D9AD5E221EB8778500E65F65 /* GNRGoodsListCell.xib in Resources */, 507 | D91945451EB8391D00FFD132 /* LaunchScreen.storyboard in Resources */, 508 | D943D9061EBB1D81002D52CE /* GNRCartFooter.xib in Resources */, 509 | D91945701EB839A000FFD132 /* Takeaway.storyboard in Resources */, 510 | D91945751EB85FFF00FFD132 /* GNRShopListCell.xib in Resources */, 511 | D9B470A81EB96E68006AA500 /* GNRShopHeader.xib in Resources */, 512 | D9B470CC1EB9E941006AA500 /* GNRCartGoodsCell.xib in Resources */, 513 | D91945421EB8391D00FFD132 /* Assets.xcassets in Resources */, 514 | D9AD5E1D1EB86EFA00E65F65 /* GNRGoodsIndexCell.xib in Resources */, 515 | D9AD5E2C1EB880A400E65F65 /* GNRSectionHeader.xib in Resources */, 516 | D9B470C71EB9E48B006AA500 /* GNRCartHeader.xib in Resources */, 517 | D9B470B31EB9B569006AA500 /* GNRShoppingBarView.xib in Resources */, 518 | ); 519 | runOnlyForDeploymentPostprocessing = 0; 520 | }; 521 | D91945491EB8391D00FFD132 /* Resources */ = { 522 | isa = PBXResourcesBuildPhase; 523 | buildActionMask = 2147483647; 524 | files = ( 525 | ); 526 | runOnlyForDeploymentPostprocessing = 0; 527 | }; 528 | D91945541EB8391D00FFD132 /* Resources */ = { 529 | isa = PBXResourcesBuildPhase; 530 | buildActionMask = 2147483647; 531 | files = ( 532 | ); 533 | runOnlyForDeploymentPostprocessing = 0; 534 | }; 535 | /* End PBXResourcesBuildPhase section */ 536 | 537 | /* Begin PBXSourcesBuildPhase section */ 538 | D919452E1EB8391D00FFD132 /* Sources */ = { 539 | isa = PBXSourcesBuildPhase; 540 | buildActionMask = 2147483647; 541 | files = ( 542 | D9B470CB1EB9E941006AA500 /* GNRCartGoodsCell.m in Sources */, 543 | D919453A1EB8391D00FFD132 /* AppDelegate.m in Sources */, 544 | D919457C1EB868C900FFD132 /* GNRGoodsListViewController.m in Sources */, 545 | D9AD5E151EB86EAA00E65F65 /* GNRGoodsGroup.m in Sources */, 546 | D919456E1EB8398C00FFD132 /* GNRShopListViewController.m in Sources */, 547 | D9B470B11EB9B563006AA500 /* GNRShoppingBarView.m in Sources */, 548 | D9B470A61EB96E61006AA500 /* GNRShopHeader.m in Sources */, 549 | D9B470A31EB96B8E006AA500 /* UINavigationBar+Awesome.m in Sources */, 550 | D9AD5E2A1EB8809B00E65F65 /* GNRSectionHeader.m in Sources */, 551 | D9AD5E211EB8778500E65F65 /* GNRGoodsListCell.m in Sources */, 552 | D943D9051EBB1D81002D52CE /* GNRCartFooter.m in Sources */, 553 | D9AD5E161EB86EAA00E65F65 /* GNRGoodsListModel.m in Sources */, 554 | D91945371EB8391D00FFD132 /* main.m in Sources */, 555 | D9B470C21EB9DD68006AA500 /* GNRShoppingCartView.m in Sources */, 556 | D9AD5E261EB879A200E65F65 /* GNRCountStepper.m in Sources */, 557 | D9AD5E141EB86EAA00E65F65 /* GNRLinkageTableView.m in Sources */, 558 | D9B470C51EB9E481006AA500 /* GNRCartHeader.m in Sources */, 559 | D9B470BB1EB9C902006AA500 /* GNRShoppingCart.m in Sources */, 560 | D9B470AE1EB9B3DD006AA500 /* GNRShoppingBar.m in Sources */, 561 | D9AD5E1C1EB86EFA00E65F65 /* GNRGoodsIndexCell.m in Sources */, 562 | D91945791EB8655700FFD132 /* GNRTitleHeader.m in Sources */, 563 | D9AD5E171EB86EAA00E65F65 /* GNRGoodsModel.m in Sources */, 564 | D91945741EB85FFF00FFD132 /* GNRShopListCell.m in Sources */, 565 | D9B470B81EB9C8E9006AA500 /* GNRShoppingBag.m in Sources */, 566 | ); 567 | runOnlyForDeploymentPostprocessing = 0; 568 | }; 569 | D91945471EB8391D00FFD132 /* Sources */ = { 570 | isa = PBXSourcesBuildPhase; 571 | buildActionMask = 2147483647; 572 | files = ( 573 | D91945501EB8391D00FFD132 /* __Tests.m in Sources */, 574 | ); 575 | runOnlyForDeploymentPostprocessing = 0; 576 | }; 577 | D91945521EB8391D00FFD132 /* Sources */ = { 578 | isa = PBXSourcesBuildPhase; 579 | buildActionMask = 2147483647; 580 | files = ( 581 | D919455B1EB8391D00FFD132 /* __UITests.m in Sources */, 582 | ); 583 | runOnlyForDeploymentPostprocessing = 0; 584 | }; 585 | /* End PBXSourcesBuildPhase section */ 586 | 587 | /* Begin PBXTargetDependency section */ 588 | D919454D1EB8391D00FFD132 /* PBXTargetDependency */ = { 589 | isa = PBXTargetDependency; 590 | target = D91945311EB8391D00FFD132 /* 外卖 */; 591 | targetProxy = D919454C1EB8391D00FFD132 /* PBXContainerItemProxy */; 592 | }; 593 | D91945581EB8391D00FFD132 /* PBXTargetDependency */ = { 594 | isa = PBXTargetDependency; 595 | target = D91945311EB8391D00FFD132 /* 外卖 */; 596 | targetProxy = D91945571EB8391D00FFD132 /* PBXContainerItemProxy */; 597 | }; 598 | /* End PBXTargetDependency section */ 599 | 600 | /* Begin PBXVariantGroup section */ 601 | D91945431EB8391D00FFD132 /* LaunchScreen.storyboard */ = { 602 | isa = PBXVariantGroup; 603 | children = ( 604 | D91945441EB8391D00FFD132 /* Base */, 605 | ); 606 | name = LaunchScreen.storyboard; 607 | sourceTree = ""; 608 | }; 609 | /* End PBXVariantGroup section */ 610 | 611 | /* Begin XCBuildConfiguration section */ 612 | D919455D1EB8391D00FFD132 /* Debug */ = { 613 | isa = XCBuildConfiguration; 614 | buildSettings = { 615 | ALWAYS_SEARCH_USER_PATHS = NO; 616 | CLANG_ANALYZER_NONNULL = YES; 617 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 618 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 619 | CLANG_CXX_LIBRARY = "libc++"; 620 | CLANG_ENABLE_MODULES = YES; 621 | CLANG_ENABLE_OBJC_ARC = YES; 622 | CLANG_WARN_BOOL_CONVERSION = YES; 623 | CLANG_WARN_CONSTANT_CONVERSION = YES; 624 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 625 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 626 | CLANG_WARN_EMPTY_BODY = YES; 627 | CLANG_WARN_ENUM_CONVERSION = YES; 628 | CLANG_WARN_INFINITE_RECURSION = YES; 629 | CLANG_WARN_INT_CONVERSION = YES; 630 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 631 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 632 | CLANG_WARN_UNREACHABLE_CODE = YES; 633 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 634 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 635 | COPY_PHASE_STRIP = NO; 636 | DEBUG_INFORMATION_FORMAT = dwarf; 637 | ENABLE_STRICT_OBJC_MSGSEND = YES; 638 | ENABLE_TESTABILITY = YES; 639 | GCC_C_LANGUAGE_STANDARD = gnu99; 640 | GCC_DYNAMIC_NO_PIC = NO; 641 | GCC_NO_COMMON_BLOCKS = YES; 642 | GCC_OPTIMIZATION_LEVEL = 0; 643 | GCC_PREPROCESSOR_DEFINITIONS = ( 644 | "DEBUG=1", 645 | "$(inherited)", 646 | ); 647 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 648 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 649 | GCC_WARN_UNDECLARED_SELECTOR = YES; 650 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 651 | GCC_WARN_UNUSED_FUNCTION = YES; 652 | GCC_WARN_UNUSED_VARIABLE = YES; 653 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 654 | MTL_ENABLE_DEBUG_INFO = YES; 655 | ONLY_ACTIVE_ARCH = YES; 656 | SDKROOT = iphoneos; 657 | TARGETED_DEVICE_FAMILY = "1,2"; 658 | }; 659 | name = Debug; 660 | }; 661 | D919455E1EB8391D00FFD132 /* Release */ = { 662 | isa = XCBuildConfiguration; 663 | buildSettings = { 664 | ALWAYS_SEARCH_USER_PATHS = NO; 665 | CLANG_ANALYZER_NONNULL = YES; 666 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 667 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 668 | CLANG_CXX_LIBRARY = "libc++"; 669 | CLANG_ENABLE_MODULES = YES; 670 | CLANG_ENABLE_OBJC_ARC = YES; 671 | CLANG_WARN_BOOL_CONVERSION = YES; 672 | CLANG_WARN_CONSTANT_CONVERSION = YES; 673 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 674 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 675 | CLANG_WARN_EMPTY_BODY = YES; 676 | CLANG_WARN_ENUM_CONVERSION = YES; 677 | CLANG_WARN_INFINITE_RECURSION = YES; 678 | CLANG_WARN_INT_CONVERSION = YES; 679 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 680 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 681 | CLANG_WARN_UNREACHABLE_CODE = YES; 682 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 683 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 684 | COPY_PHASE_STRIP = NO; 685 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 686 | ENABLE_NS_ASSERTIONS = NO; 687 | ENABLE_STRICT_OBJC_MSGSEND = YES; 688 | GCC_C_LANGUAGE_STANDARD = gnu99; 689 | GCC_NO_COMMON_BLOCKS = YES; 690 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 691 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 692 | GCC_WARN_UNDECLARED_SELECTOR = YES; 693 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 694 | GCC_WARN_UNUSED_FUNCTION = YES; 695 | GCC_WARN_UNUSED_VARIABLE = YES; 696 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 697 | MTL_ENABLE_DEBUG_INFO = NO; 698 | SDKROOT = iphoneos; 699 | TARGETED_DEVICE_FAMILY = "1,2"; 700 | VALIDATE_PRODUCT = YES; 701 | }; 702 | name = Release; 703 | }; 704 | D91945601EB8391D00FFD132 /* Debug */ = { 705 | isa = XCBuildConfiguration; 706 | buildSettings = { 707 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 708 | DEVELOPMENT_TEAM = 3637NJMX7D; 709 | INFOPLIST_FILE = "外卖/Info.plist"; 710 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 711 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 712 | PRODUCT_BUNDLE_IDENTIFIER = "com.occode.--"; 713 | PRODUCT_NAME = "$(TARGET_NAME)"; 714 | }; 715 | name = Debug; 716 | }; 717 | D91945611EB8391D00FFD132 /* Release */ = { 718 | isa = XCBuildConfiguration; 719 | buildSettings = { 720 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 721 | DEVELOPMENT_TEAM = 3637NJMX7D; 722 | INFOPLIST_FILE = "外卖/Info.plist"; 723 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 724 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 725 | PRODUCT_BUNDLE_IDENTIFIER = "com.occode.--"; 726 | PRODUCT_NAME = "$(TARGET_NAME)"; 727 | }; 728 | name = Release; 729 | }; 730 | D91945631EB8391D00FFD132 /* Debug */ = { 731 | isa = XCBuildConfiguration; 732 | buildSettings = { 733 | BUNDLE_LOADER = "$(TEST_HOST)"; 734 | DEVELOPMENT_TEAM = 3637NJMX7D; 735 | INFOPLIST_FILE = "外卖Tests/Info.plist"; 736 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 737 | PRODUCT_BUNDLE_IDENTIFIER = "com.occode.--Tests"; 738 | PRODUCT_NAME = "$(TARGET_NAME)"; 739 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/外卖.app/外卖"; 740 | }; 741 | name = Debug; 742 | }; 743 | D91945641EB8391D00FFD132 /* Release */ = { 744 | isa = XCBuildConfiguration; 745 | buildSettings = { 746 | BUNDLE_LOADER = "$(TEST_HOST)"; 747 | DEVELOPMENT_TEAM = 3637NJMX7D; 748 | INFOPLIST_FILE = "外卖Tests/Info.plist"; 749 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 750 | PRODUCT_BUNDLE_IDENTIFIER = "com.occode.--Tests"; 751 | PRODUCT_NAME = "$(TARGET_NAME)"; 752 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/外卖.app/外卖"; 753 | }; 754 | name = Release; 755 | }; 756 | D91945661EB8391D00FFD132 /* Debug */ = { 757 | isa = XCBuildConfiguration; 758 | buildSettings = { 759 | DEVELOPMENT_TEAM = 3637NJMX7D; 760 | INFOPLIST_FILE = "外卖UITests/Info.plist"; 761 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 762 | PRODUCT_BUNDLE_IDENTIFIER = "com.occode.--UITests"; 763 | PRODUCT_NAME = "$(TARGET_NAME)"; 764 | TEST_TARGET_NAME = "外卖"; 765 | }; 766 | name = Debug; 767 | }; 768 | D91945671EB8391D00FFD132 /* Release */ = { 769 | isa = XCBuildConfiguration; 770 | buildSettings = { 771 | DEVELOPMENT_TEAM = 3637NJMX7D; 772 | INFOPLIST_FILE = "外卖UITests/Info.plist"; 773 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 774 | PRODUCT_BUNDLE_IDENTIFIER = "com.occode.--UITests"; 775 | PRODUCT_NAME = "$(TARGET_NAME)"; 776 | TEST_TARGET_NAME = "外卖"; 777 | }; 778 | name = Release; 779 | }; 780 | /* End XCBuildConfiguration section */ 781 | 782 | /* Begin XCConfigurationList section */ 783 | D919452D1EB8391D00FFD132 /* Build configuration list for PBXProject "外卖" */ = { 784 | isa = XCConfigurationList; 785 | buildConfigurations = ( 786 | D919455D1EB8391D00FFD132 /* Debug */, 787 | D919455E1EB8391D00FFD132 /* Release */, 788 | ); 789 | defaultConfigurationIsVisible = 0; 790 | defaultConfigurationName = Release; 791 | }; 792 | D919455F1EB8391D00FFD132 /* Build configuration list for PBXNativeTarget "外卖" */ = { 793 | isa = XCConfigurationList; 794 | buildConfigurations = ( 795 | D91945601EB8391D00FFD132 /* Debug */, 796 | D91945611EB8391D00FFD132 /* Release */, 797 | ); 798 | defaultConfigurationIsVisible = 0; 799 | defaultConfigurationName = Release; 800 | }; 801 | D91945621EB8391D00FFD132 /* Build configuration list for PBXNativeTarget "外卖Tests" */ = { 802 | isa = XCConfigurationList; 803 | buildConfigurations = ( 804 | D91945631EB8391D00FFD132 /* Debug */, 805 | D91945641EB8391D00FFD132 /* Release */, 806 | ); 807 | defaultConfigurationIsVisible = 0; 808 | defaultConfigurationName = Release; 809 | }; 810 | D91945651EB8391D00FFD132 /* Build configuration list for PBXNativeTarget "外卖UITests" */ = { 811 | isa = XCConfigurationList; 812 | buildConfigurations = ( 813 | D91945661EB8391D00FFD132 /* Debug */, 814 | D91945671EB8391D00FFD132 /* Release */, 815 | ); 816 | defaultConfigurationIsVisible = 0; 817 | defaultConfigurationName = Release; 818 | }; 819 | /* End XCConfigurationList section */ 820 | }; 821 | rootObject = D919452A1EB8391D00FFD132 /* Project object */; 822 | } 823 | -------------------------------------------------------------------------------- /外卖.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /外卖/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /外卖/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /外卖/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shop_goodslist_banner_bg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "banner@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "banner@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shop_goodslist_banner_bg.imageset/banner@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shop_goodslist_banner_bg.imageset/banner@2x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shop_goodslist_banner_bg.imageset/banner@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shop_goodslist_banner_bg.imageset/banner@3x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_header_line.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "shoplist_header_line@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "shoplist_header_line@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_header_line.imageset/shoplist_header_line@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shoplist_header_line.imageset/shoplist_header_line@2x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_header_line.imageset/shoplist_header_line@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shoplist_header_line.imageset/shoplist_header_line@3x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_header_location_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "shoplist_header_location_icon@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "shoplist_header_location_icon@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_header_location_icon.imageset/shoplist_header_location_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shoplist_header_location_icon.imageset/shoplist_header_location_icon@2x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_header_location_icon.imageset/shoplist_header_location_icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shoplist_header_location_icon.imageset/shoplist_header_location_icon@3x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_header_quality_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "shoplist_header_quality_icon@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "shoplist_header_quality_icon@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_header_quality_icon.imageset/shoplist_header_quality_icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shoplist_header_quality_icon.imageset/shoplist_header_quality_icon@2x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_header_quality_icon.imageset/shoplist_header_quality_icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shoplist_header_quality_icon.imageset/shoplist_header_quality_icon@3x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_add_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "jia@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "jia@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_add_icon.imageset/jia@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_add_icon.imageset/jia@2x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_add_icon.imageset/jia@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_add_icon.imageset/jia@3x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_addred_icon.imageset/2加@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_addred_icon.imageset/2加@2x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_addred_icon.imageset/2加@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_addred_icon.imageset/2加@3x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_addred_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "2加@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "2加@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_sub_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "jian@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "jian@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_sub_icon.imageset/jian@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_sub_icon.imageset/jian@2x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_sub_icon.imageset/jian@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_sub_icon.imageset/jian@3x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_subred_icon.imageset/2减@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_subred_icon.imageset/2减@2x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_subred_icon.imageset/2减@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_subred_icon.imageset/2减@3x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_stepper_subred_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "2减@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "2减@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_trash_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "trash_@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "trash_@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_trash_icon.imageset/trash_@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shoplist_trash_icon.imageset/trash_@2x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shoplist_trash_icon.imageset/trash_@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shoplist_trash_icon.imageset/trash_@3x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shopping_cart_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "购物车@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "购物车@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shopping_cart_icon.imageset/购物车@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shopping_cart_icon.imageset/购物车@2x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/Takeaway/ShopList/shopping_cart_icon.imageset/购物车@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/Takeaway/ShopList/shopping_cart_icon.imageset/购物车@3x.png -------------------------------------------------------------------------------- /外卖/Assets.xcassets/rsc/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /外卖/Assets.xcassets/rsc/image.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "b20160607134009-81.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /外卖/Assets.xcassets/rsc/image.imageset/b20160607134009-81.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly918/TakeawayList-ShoppingCart/d25509b8d99670c4f34cf9074b545fd13d81b3e1/外卖/Assets.xcassets/rsc/image.imageset/b20160607134009-81.jpg -------------------------------------------------------------------------------- /外卖/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /外卖/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Takeaway 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UIRequiresFullScreen 32 | 33 | UIStatusBarHidden 34 | 35 | UIStatusBarStyle 36 | UIStatusBarStyleDefault 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationLandscapeLeft 41 | UIInterfaceOrientationLandscapeRight 42 | 43 | UISupportedInterfaceOrientations~ipad 44 | 45 | UIInterfaceOrientationPortrait 46 | UIInterfaceOrientationPortraitUpsideDown 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | UIViewControllerBasedStatusBarAppearance 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /外卖/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // 外卖 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /外卖Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /外卖Tests/__Tests.m: -------------------------------------------------------------------------------- 1 | // 2 | // __Tests.m 3 | // 外卖Tests 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface __Tests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation __Tests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /外卖UITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /外卖UITests/__UITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // __UITests.m 3 | // 外卖UITests 4 | // 5 | // Created by LvYuan on 2017/5/2. 6 | // Copyright © 2017年 BattlePetal. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface __UITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation __UITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | --------------------------------------------------------------------------------