├── .DS_Store ├── LocaShopCar ├── Assets.xcassets │ ├── Contents.json │ ├── tm_mcart_checked@2x.png │ ├── tm_mcart_unchecked@2x.png │ ├── tm_mcart_checked.imageset │ │ ├── tm_mcart_checked@2x.png │ │ └── Contents.json │ ├── tm_mcart_unchecked.imageset │ │ ├── tm_mcart_unchecked@2x.png │ │ └── Contents.json │ └── AppIcon.appiconset │ │ └── Contents.json ├── IQKeyboardManager │ ├── Resources │ │ └── IQKeyboardManager.bundle │ │ │ ├── IQButtonBarArrowLeft@2x.png │ │ │ ├── IQButtonBarArrowLeft@3x.png │ │ │ ├── IQButtonBarArrowRight@2x.png │ │ │ ├── IQButtonBarArrowRight@3x.png │ │ │ ├── zh-Hans │ │ │ └── IQKeyboardManager.strings │ │ │ ├── zh-Hant │ │ │ └── IQKeyboardManager.strings │ │ │ ├── en.lproj │ │ │ └── IQKeyboardManager.strings │ │ │ ├── de.lproj │ │ │ └── IQKeyboardManager.strings │ │ │ ├── fr.lproj │ │ │ └── IQKeyboardManager.strings │ │ │ └── es.lproj │ │ │ └── IQKeyboardManager.strings │ ├── IQToolbar │ │ ├── IQPreviousNextView.m │ │ ├── IQBarButtonItem.h │ │ ├── IQPreviousNextView.h │ │ ├── IQToolbar.h │ │ ├── IQTitleBarButtonItem.h │ │ ├── IQTitleBarButtonItem.m │ │ ├── IQBarButtonItem.m │ │ └── IQToolbar.m │ ├── Categories │ │ ├── IQUIScrollView+Additions.h │ │ ├── IQUIViewController+Additions.h │ │ ├── IQUIViewController+Additions.m │ │ ├── IQNSArray+Sort.h │ │ ├── IQUIWindow+Hierarchy.h │ │ ├── IQUITextFieldView+Additions.h │ │ ├── IQUIScrollView+Additions.m │ │ ├── IQUIWindow+Hierarchy.m │ │ ├── IQUITextFieldView+Additions.m │ │ ├── IQNSArray+Sort.m │ │ └── IQUIView+Hierarchy.h │ ├── IQTextView │ │ ├── IQTextView.h │ │ └── IQTextView.m │ ├── Constants │ │ ├── IQKeyboardManagerConstantsInternal.h │ │ └── IQKeyboardManagerConstants.h │ └── IQKeyboardReturnKeyHandler.h ├── ShopCarModel.m ├── ShopCarGruopModel.m ├── ShopCarController.h ├── fmdb │ ├── FMDB.h │ ├── FMDatabasePool.h │ ├── FMDatabaseQueue.h │ ├── FMDatabaseQueue.m │ ├── FMDatabaseAdditions.m │ └── FMDatabaseAdditions.h ├── MJExtension │ ├── MJFoundation.h │ ├── MJExtension.h │ ├── MJPropertyKey.h │ ├── MJPropertyKey.m │ ├── MJExtensionConst.m │ ├── MJPropertyType.h │ ├── NSObject+MJCoding.h │ ├── NSString+MJExtension.h │ ├── MJProperty.h │ ├── MJFoundation.m │ ├── NSObject+MJCoding.m │ ├── MJPropertyType.m │ ├── MJExtensionConst.h │ ├── NSObject+MJClass.h │ ├── NSObject+MJProperty.h │ ├── NSString+MJExtension.m │ ├── NSObject+MJClass.m │ └── MJProperty.m ├── AppDelegate.h ├── GoodsController.h ├── LTDBHelper.h ├── main.m ├── ShopCarHeaderView.h ├── ShopCarGruopModel.h ├── LTDBShopCar.h ├── ShopCarModel.h ├── GoodsCell.h ├── LTDBHelper.m ├── Info.plist ├── Base.lproj │ └── LaunchScreen.storyboard ├── AppDelegate.m ├── ShopCarHeaderView.m ├── GoodsController.m ├── GoodsCell.m ├── LTDBShopCar.m ├── GuoupGood.plist └── ShopCarController.m ├── LocaShopCar.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ ├── ty.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ ├── xhl.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ └── letian.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── xhl.xcuserdatad │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ └── LocaShopCar.xcscheme │ ├── ty.xcuserdatad │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ └── LocaShopCar.xcscheme │ └── letian.xcuserdatad │ ├── xcschemes │ ├── xcschememanagement.plist │ └── LocaShopCar.xcscheme │ └── xcdebugger │ └── Breakpoints_v2.xcbkptlist └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xhl916235259/LocaShopCar/HEAD/.DS_Store -------------------------------------------------------------------------------- /LocaShopCar/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /LocaShopCar/Assets.xcassets/tm_mcart_checked@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xhl916235259/LocaShopCar/HEAD/LocaShopCar/Assets.xcassets/tm_mcart_checked@2x.png -------------------------------------------------------------------------------- /LocaShopCar/Assets.xcassets/tm_mcart_unchecked@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xhl916235259/LocaShopCar/HEAD/LocaShopCar/Assets.xcassets/tm_mcart_unchecked@2x.png -------------------------------------------------------------------------------- /LocaShopCar/Assets.xcassets/tm_mcart_checked.imageset/tm_mcart_checked@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xhl916235259/LocaShopCar/HEAD/LocaShopCar/Assets.xcassets/tm_mcart_checked.imageset/tm_mcart_checked@2x.png -------------------------------------------------------------------------------- /LocaShopCar/Assets.xcassets/tm_mcart_unchecked.imageset/tm_mcart_unchecked@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xhl916235259/LocaShopCar/HEAD/LocaShopCar/Assets.xcassets/tm_mcart_unchecked.imageset/tm_mcart_unchecked@2x.png -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Resources/IQKeyboardManager.bundle/IQButtonBarArrowLeft@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xhl916235259/LocaShopCar/HEAD/LocaShopCar/IQKeyboardManager/Resources/IQKeyboardManager.bundle/IQButtonBarArrowLeft@2x.png -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Resources/IQKeyboardManager.bundle/IQButtonBarArrowLeft@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xhl916235259/LocaShopCar/HEAD/LocaShopCar/IQKeyboardManager/Resources/IQKeyboardManager.bundle/IQButtonBarArrowLeft@3x.png -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Resources/IQKeyboardManager.bundle/IQButtonBarArrowRight@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xhl916235259/LocaShopCar/HEAD/LocaShopCar/IQKeyboardManager/Resources/IQKeyboardManager.bundle/IQButtonBarArrowRight@2x.png -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Resources/IQKeyboardManager.bundle/IQButtonBarArrowRight@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xhl916235259/LocaShopCar/HEAD/LocaShopCar/IQKeyboardManager/Resources/IQKeyboardManager.bundle/IQButtonBarArrowRight@3x.png -------------------------------------------------------------------------------- /LocaShopCar.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /LocaShopCar.xcodeproj/project.xcworkspace/xcuserdata/ty.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xhl916235259/LocaShopCar/HEAD/LocaShopCar.xcodeproj/project.xcworkspace/xcuserdata/ty.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /LocaShopCar.xcodeproj/project.xcworkspace/xcuserdata/xhl.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xhl916235259/LocaShopCar/HEAD/LocaShopCar.xcodeproj/project.xcworkspace/xcuserdata/xhl.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /LocaShopCar.xcodeproj/project.xcworkspace/xcuserdata/letian.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xhl916235259/LocaShopCar/HEAD/LocaShopCar.xcodeproj/project.xcworkspace/xcuserdata/letian.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /LocaShopCar/ShopCarModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // ShopCarModel.m 3 | // LocaShopCar 4 | // 5 | // Created by xhl on 16/7/17. 6 | // Copyright © 2016年 xhl. All rights reserved. 7 | // 8 | 9 | #import "ShopCarModel.h" 10 | 11 | @implementation ShopCarModel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /LocaShopCar/ShopCarGruopModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // ShopCarGruopModel.m 3 | // LocaShopCar 4 | // 5 | // Created by xhl on 16/7/17. 6 | // Copyright © 2016年 xhl. All rights reserved. 7 | // 8 | 9 | #import "ShopCarGruopModel.h" 10 | 11 | @implementation ShopCarGruopModel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /LocaShopCar/ShopCarController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ShopCarController.h 3 | // LocaShopCar 4 | // 5 | // Created by xhl on 16/7/17. 6 | // Copyright © 2016年 xhl. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ShopCarController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /LocaShopCar/fmdb/FMDB.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | FOUNDATION_EXPORT double FMDBVersionNumber; 4 | FOUNDATION_EXPORT const unsigned char FMDBVersionString[]; 5 | 6 | #import "FMDatabase.h" 7 | #import "FMResultSet.h" 8 | #import "FMDatabaseAdditions.h" 9 | #import "FMDatabaseQueue.h" 10 | #import "FMDatabasePool.h" 11 | -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/MJFoundation.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJFoundation.h 3 | // MJExtensionExample 4 | // 5 | // Created by MJ Lee on 14/7/16. 6 | // Copyright (c) 2014年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MJFoundation : NSObject 12 | + (BOOL)isClassFromFoundation:(Class)c; 13 | @end 14 | -------------------------------------------------------------------------------- /LocaShopCar/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // LocaShopCar 4 | // 5 | // Created by xhl on 16/7/17. 6 | // Copyright © 2016年 xhl. 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 | -------------------------------------------------------------------------------- /LocaShopCar/GoodsController.h: -------------------------------------------------------------------------------- 1 | // 2 | // GoodsController.h 3 | // LocaShopCar 4 | // 5 | // Created by xhl on 16/7/17. 6 | // Copyright © 2016年 xhl. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GoodsController : UITableViewController 12 | 13 | /** 添加商品回调 */ 14 | @property (nonatomic,copy) void (^callBack) (id model); 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /LocaShopCar/LTDBHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // LTDBHelper.h 3 | // LocaShopCar 4 | // 5 | // Created by xhl on 16/7/17. 6 | // Copyright © 2016年 xhl. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "FMDB.h" 12 | 13 | @interface LTDBHelper : NSObject 14 | 15 | @property(nonatomic,strong)FMDatabase *db; 16 | 17 | 18 | +(LTDBHelper*) shareDatabase; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /LocaShopCar/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // LocaShopCar 4 | // 5 | // Created by xhl on 16/7/17. 6 | // Copyright © 2016年 xhl. 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 | -------------------------------------------------------------------------------- /LocaShopCar/Assets.xcassets/tm_mcart_checked.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tm_mcart_checked@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /LocaShopCar/Assets.xcassets/tm_mcart_unchecked.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tm_mcart_unchecked@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LocaShopCar 2 | 本地购物车,分组展示,看很多人对做本地购物车比较头疼,特此写一个demo供大家学习,如有不足的地方,请提出建议,欢迎加QQ(916235259)私聊- - 3 | 写了两种,一种是不分组的,还有一种是分组的 4 | 分组的使用了两张表,一张是shopCar2购物车的,还有一张是shopTab商家信息的 5 | 查询的时候无非就是先遍历商家信息,通过goodsId判断shopCar2表中是否存在这个商家的信息,然后就是拼接格式。 6 | demo中实现了商品+,-,删除等功能,都是通过kvo去绑定商品数量的变化然后更新相应的视图。后期将会加上,单选,全选,组删除,计算总价格,如果大家有更好的思路可以随时联系我,建议两个demo都看一下,比较有什么不同。 7 | 如果需要添加数据测试,请注意当前组的shopId保持一致,每种商品的goodsId不能相同。 8 | 但是一般来说购物车这块功能都是放在服务端的,自己本地实现实现知道一下思路也好,具体的代码里面有注释。 git地址: https://github.com/xhl916235259/LocaShopCar 欢迎Start,欢迎指正。 -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Resources/IQKeyboardManager.bundle/zh-Hans/IQKeyboardManager.strings: -------------------------------------------------------------------------------- 1 | 2 | "enabled" = "开启"; 3 | 4 | "disabled" = "关闭"; 5 | 6 | "already disabled" = "已经开启"; 7 | 8 | "already enabled" = "已经关闭"; 9 | 10 | "You must set UIWindow.rootViewController in your AppDelegate to work with IQKeyboardManager" = "为了使用IQKeyboardManager,必须在你的 AppDelegate 中设置 UIWindow.rootViewController。"; 11 | 12 | "Previous" = "前一个"; 13 | "Next" = "下一个"; 14 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Resources/IQKeyboardManager.bundle/zh-Hant/IQKeyboardManager.strings: -------------------------------------------------------------------------------- 1 | 2 | "enabled" = "開啟"; 3 | 4 | "disabled" = "關閉"; 5 | 6 | "already disabled" = "已經開啟"; 7 | 8 | "already enabled" = "已經關閉"; 9 | 10 | "You must set UIWindow.rootViewController in your AppDelegate to work with IQKeyboardManager" = "為了使用IQKeyboardManager,必須在妳的 AppDelegate 中設置 UIWindow.rootViewController。"; 11 | 12 | "Previous" = "前一個"; 13 | "Next" = "下一個"; 14 | -------------------------------------------------------------------------------- /LocaShopCar/ShopCarHeaderView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ShopCarHeaderView.h 3 | // LocaShopCar 4 | // 5 | // Created by letian on 16/8/23. 6 | // Copyright © 2016年 xhl. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class ShopCarGruopModel; 12 | @interface ShopCarHeaderView : UITableViewHeaderFooterView 13 | 14 | + (instancetype)backHeaderViewWithTableView:(UITableView *)tableView; 15 | 16 | - (void)headerViewDataWtihModel:(ShopCarGruopModel *)model; 17 | 18 | /** 回调 */ 19 | @property (nonatomic,copy) dispatch_block_t callBack; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/MJExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJExtension.h 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 小码哥. All rights reserved. 7 | // 代码地址:https://github.com/CoderMJLee/MJExtension 8 | // 代码地址:http://code4app.com/ios/%E5%AD%97%E5%85%B8-JSON-%E4%B8%8E%E6%A8%A1%E5%9E%8B%E7%9A%84%E8%BD%AC%E6%8D%A2/5339992a933bf062608b4c57 9 | 10 | #import "NSObject+MJCoding.h" 11 | #import "NSObject+MJProperty.h" 12 | #import "NSObject+MJClass.h" 13 | #import "NSObject+MJKeyValue.h" 14 | #import "NSString+MJExtension.h" 15 | #import "MJExtensionConst.h" -------------------------------------------------------------------------------- /LocaShopCar/ShopCarGruopModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ShopCarGruopModel.h 3 | // LocaShopCar 4 | // 5 | // Created by xhl on 16/7/17. 6 | // Copyright © 2016年 xhl. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ShopCarGruopModel : NSObject 12 | 13 | /** 商家ID */ 14 | @property (nonatomic,copy) NSString * shopId; 15 | 16 | /** 商家名字 */ 17 | @property (nonatomic,copy) NSString * shopName; 18 | 19 | /** 商品集合 */ 20 | @property (nonatomic,strong) NSMutableArray * goods; 21 | 22 | /** 是否选中 */ 23 | @property (nonatomic,assign,getter=isSelect) BOOL select; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Resources/IQKeyboardManager.bundle/en.lproj/IQKeyboardManager.strings: -------------------------------------------------------------------------------- 1 | 2 | "enabled" = "enabled"; 3 | 4 | "disabled" = "disabled"; 5 | 6 | "already disabled" = "already disabled"; 7 | 8 | "already enabled" = "already enabled"; 9 | 10 | "You must set UIWindow.rootViewController in your AppDelegate to work with IQKeyboardManager" = "You must set UIWindow.rootViewController in your AppDelegate to work with IQKeyboardManager"; 11 | 12 | "Previous" = "Previous"; 13 | "Next" = "Next"; 14 | -------------------------------------------------------------------------------- /LocaShopCar.xcodeproj/xcuserdata/xhl.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Resources/IQKeyboardManager.bundle/de.lproj/IQKeyboardManager.strings: -------------------------------------------------------------------------------- 1 | 2 | "enabled" = "aktiviert"; 3 | 4 | "disabled" = "deaktiviert"; 5 | 6 | "already disabled" = "bereits deaktiviert"; 7 | 8 | "already enabled" = "bereits aktiviert"; 9 | 10 | "You must set UIWindow.rootViewController in your AppDelegate to work with IQKeyboardManager" = "Sie müssen im AppDelegate UIWindow.rootViewController setzen um mit IQKeyboardManager zu arbeiten"; 11 | 12 | "Previous" = "Zurück"; 13 | "Next" = "Vor"; 14 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Resources/IQKeyboardManager.bundle/fr.lproj/IQKeyboardManager.strings: -------------------------------------------------------------------------------- 1 | 2 | "enabled" = "activé"; 3 | 4 | "disabled" = "désactivé"; 5 | 6 | "already disabled" = "déjà désactivé"; 7 | 8 | "already enabled" = "déjà activé"; 9 | 10 | "You must set UIWindow.rootViewController in your AppDelegate to work with IQKeyboardManager" = "Vous devez définir UIWindow.rootViewController dans votre AppDelegate pour IQKeyboardManager fonctionne"; 11 | 12 | "Previous" = "Précédent"; 13 | "Next" = "Suivant"; 14 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Resources/IQKeyboardManager.bundle/es.lproj/IQKeyboardManager.strings: -------------------------------------------------------------------------------- 1 | 2 | "enabled" = "activado"; 3 | 4 | "disabled" = "desactivado"; 5 | 6 | "already disabled" = "ya está desactivado"; 7 | 8 | "already enabled" = "ya está activado"; 9 | 10 | "You must set UIWindow.rootViewController in your AppDelegate to work with IQKeyboardManager" = "Debe establecer UIWindow.rootViewController en su AppDelegate para trabajar con IQKeyboardManager"; 11 | 12 | "Previous" = "Anterior"; 13 | 14 | "Next" = "Siguiente"; 15 | -------------------------------------------------------------------------------- /LocaShopCar.xcodeproj/xcuserdata/ty.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | LocaShopCar.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | DB937B7B1D3B9FF300CBC634 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /LocaShopCar.xcodeproj/xcuserdata/xhl.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | LocaShopCar.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | DB937B7B1D3B9FF300CBC634 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /LocaShopCar.xcodeproj/xcuserdata/letian.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | LocaShopCar.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | DB937B7B1D3B9FF300CBC634 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /LocaShopCar/LTDBShopCar.h: -------------------------------------------------------------------------------- 1 | // 2 | // LTDBShopCar.h 3 | // LocaShopCar 4 | // 5 | // Created by xhl on 16/7/17. 6 | // Copyright © 2016年 xhl. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "LTDBHelper.h" 11 | #import "ShopCarModel.h" 12 | #import "ShopCarGruopModel.h" 13 | 14 | @interface LTDBShopCar : NSObject 15 | 16 | @property(nonatomic,strong)FMDatabase *db; 17 | 18 | //创建单例 19 | +(LTDBShopCar*) shareInstance; 20 | 21 | //查询 22 | -(NSArray *)getShopCarModel; 23 | //更新 24 | -(void)updateUser:(ShopCarModel *)shopCarModel; 25 | //删除 26 | -(void)deleteShopCarModel:(ShopCarModel *)shopCarModel; 27 | //增加 28 | -(void)insertUser:(ShopCarModel *)shopCarModel; 29 | 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/MJPropertyKey.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJPropertyKey.h 3 | // MJExtensionExample 4 | // 5 | // Created by MJ Lee on 15/8/11. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef enum { 12 | MJPropertyKeyTypeDictionary = 0, // 字典的key 13 | MJPropertyKeyTypeArray // 数组的key 14 | } MJPropertyKeyType; 15 | 16 | /** 17 | * 属性的key 18 | */ 19 | @interface MJPropertyKey : NSObject 20 | /** key的名字 */ 21 | @property (copy, nonatomic) NSString *name; 22 | /** key的种类,可能是@"10",可能是@"age" */ 23 | @property (assign, nonatomic) MJPropertyKeyType type; 24 | 25 | /** 26 | * 根据当前的key,也就是name,从object(字典或者数组)中取值 27 | */ 28 | - (id)valueInObject:(id)object; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/MJPropertyKey.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJPropertyKey.m 3 | // MJExtensionExample 4 | // 5 | // Created by MJ Lee on 15/8/11. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJPropertyKey.h" 10 | 11 | @implementation MJPropertyKey 12 | 13 | - (id)valueInObject:(id)object 14 | { 15 | if ([object isKindOfClass:[NSDictionary class]] && self.type == MJPropertyKeyTypeDictionary) { 16 | return object[self.name]; 17 | } else if ([object isKindOfClass:[NSArray class]] && self.type == MJPropertyKeyTypeArray) { 18 | NSArray *array = object; 19 | NSUInteger index = self.name.intValue; 20 | if (index < array.count) return array[index]; 21 | return nil; 22 | } 23 | return nil; 24 | } 25 | @end 26 | -------------------------------------------------------------------------------- /LocaShopCar/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /LocaShopCar/ShopCarModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // ShopCarModel.h 3 | // LocaShopCar 4 | // 5 | // Created by xhl on 16/7/17. 6 | // Copyright © 2016年 xhl. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ShopCarModel : NSObject 12 | 13 | /** 商品Id */ 14 | @property (nonatomic,copy) NSString * goodsId; 15 | 16 | /** 商家Id */ 17 | @property (nonatomic,copy) NSString * shopId; 18 | 19 | /** 商品标题 */ 20 | @property (nonatomic,copy) NSString * title; 21 | 22 | /** 商品价格 */ 23 | @property (nonatomic,assign) double price; 24 | 25 | /** 选中商品价格 */ 26 | @property (nonatomic,assign) double allPrice; 27 | 28 | /** 选中商品数量 */ 29 | @property (nonatomic,assign) int goodsSelectCount; 30 | 31 | /** 是否选中 */ 32 | @property (nonatomic,assign,getter=isSelect) BOOL select; 33 | 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /LocaShopCar/GoodsCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // GoodsCell.h 3 | // LocaShopCar 4 | // 5 | // Created by xhl on 16/7/17. 6 | // Copyright © 2016年 xhl. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef enum : NSUInteger { 12 | GoodsCellType, 13 | ShopCarCellType, 14 | 15 | } CellType; 16 | 17 | @class ShopCarGruopModel; 18 | @interface GoodsCell : UITableViewCell 19 | 20 | - (void) cellDataWithModel:(NSIndexPath*)indexPath andGroupModel:(ShopCarGruopModel *)model; 21 | 22 | /** 选中回调 */ 23 | @property (nonatomic,copy) dispatch_block_t callBlock; 24 | 25 | /** 购买点击回调 */ 26 | @property (nonatomic,copy) dispatch_block_t btBlock; 27 | 28 | /** 删除回调 */ 29 | @property (nonatomic,copy) dispatch_block_t deleteBlock; 30 | 31 | /** cell类型 */ 32 | @property (nonatomic,assign) CellType cellType; 33 | 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/MJExtensionConst.m: -------------------------------------------------------------------------------- 1 | #ifndef __MJExtensionConst__M__ 2 | #define __MJExtensionConst__M__ 3 | 4 | #import 5 | 6 | /** 7 | * 成员变量类型(属性类型) 8 | */ 9 | NSString *const MJPropertyTypeInt = @"i"; 10 | NSString *const MJPropertyTypeShort = @"s"; 11 | NSString *const MJPropertyTypeFloat = @"f"; 12 | NSString *const MJPropertyTypeDouble = @"d"; 13 | NSString *const MJPropertyTypeLong = @"l"; 14 | NSString *const MJPropertyTypeLongLong = @"q"; 15 | NSString *const MJPropertyTypeChar = @"c"; 16 | NSString *const MJPropertyTypeBOOL1 = @"c"; 17 | NSString *const MJPropertyTypeBOOL2 = @"b"; 18 | NSString *const MJPropertyTypePointer = @"*"; 19 | 20 | NSString *const MJPropertyTypeIvar = @"^{objc_ivar=}"; 21 | NSString *const MJPropertyTypeMethod = @"^{objc_method=}"; 22 | NSString *const MJPropertyTypeBlock = @"@?"; 23 | NSString *const MJPropertyTypeClass = @"#"; 24 | NSString *const MJPropertyTypeSEL = @":"; 25 | NSString *const MJPropertyTypeId = @"@"; 26 | 27 | #endif -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/MJPropertyType.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJPropertyType.h 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 小码哥. All rights reserved. 7 | // 包装一种类型 8 | 9 | #import 10 | 11 | /** 12 | * 包装一种类型 13 | */ 14 | @interface MJPropertyType : NSObject 15 | /** 类型标识符 */ 16 | @property (nonatomic, copy) NSString *code; 17 | 18 | /** 是否为id类型 */ 19 | @property (nonatomic, readonly, getter=isIdType) BOOL idType; 20 | 21 | /** 是否为基本数字类型:int、float等 */ 22 | @property (nonatomic, readonly, getter=isNumberType) BOOL numberType; 23 | 24 | /** 是否为BOOL类型 */ 25 | @property (nonatomic, readonly, getter=isBoolType) BOOL boolType; 26 | 27 | /** 对象类型(如果是基本数据类型,此值为nil) */ 28 | @property (nonatomic, readonly) Class typeClass; 29 | 30 | /** 类型是否来自于Foundation框架,比如NSString、NSArray */ 31 | @property (nonatomic, readonly, getter = isFromFoundation) BOOL fromFoundation; 32 | /** 类型是否不支持KVC */ 33 | @property (nonatomic, readonly, getter = isKVCDisabled) BOOL KVCDisabled; 34 | 35 | /** 36 | * 获得缓存的类型对象 37 | */ 38 | + (instancetype)cachedTypeWithCode:(NSString *)code; 39 | @end -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/NSObject+MJCoding.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+MJCoding.h 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MJExtensionConst.h" 11 | 12 | /** 13 | * Codeing协议 14 | */ 15 | @protocol MJCoding 16 | @optional 17 | /** 18 | * 这个数组中的属性名才会进行归档 19 | */ 20 | + (NSArray *)mj_allowedCodingPropertyNames; 21 | /** 22 | * 这个数组中的属性名将会被忽略:不进行归档 23 | */ 24 | + (NSArray *)mj_ignoredCodingPropertyNames; 25 | @end 26 | 27 | @interface NSObject (MJCoding) 28 | /** 29 | * 解码(从文件中解析对象) 30 | */ 31 | - (void)mj_decode:(NSCoder *)decoder; 32 | /** 33 | * 编码(将对象写入文件中) 34 | */ 35 | - (void)mj_encode:(NSCoder *)encoder; 36 | @end 37 | 38 | /** 39 | 归档的实现 40 | */ 41 | #define MJCodingImplementation \ 42 | - (id)initWithCoder:(NSCoder *)decoder \ 43 | { \ 44 | if (self = [super init]) { \ 45 | [self mj_decode:decoder]; \ 46 | } \ 47 | return self; \ 48 | } \ 49 | \ 50 | - (void)encodeWithCoder:(NSCoder *)encoder \ 51 | { \ 52 | [self mj_encode:encoder]; \ 53 | } 54 | 55 | #define MJExtensionCodingImplementation MJCodingImplementation -------------------------------------------------------------------------------- /LocaShopCar/LTDBHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // LTDBHelper.m 3 | // LocaShopCar 4 | // 5 | // Created by xhl on 16/7/17. 6 | // Copyright © 2016年 xhl. All rights reserved. 7 | // 8 | 9 | #import "LTDBHelper.h" 10 | 11 | 12 | @implementation LTDBHelper 13 | 14 | //创建单例 15 | +(LTDBHelper*)shareDatabase{ 16 | static dispatch_once_t onceToken; 17 | static LTDBHelper *sharedInstance=nil; 18 | dispatch_once(&onceToken, ^{ 19 | sharedInstance=[[LTDBHelper alloc]init]; 20 | [sharedInstance createDB]; 21 | }); 22 | [sharedInstance openDB]; 23 | return sharedInstance; 24 | } 25 | 26 | 27 | //创建数据库课 28 | -(void)createDB 29 | { 30 | if(self.db != nil) 31 | { 32 | return; 33 | } 34 | NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 35 | NSString *dbFilePath = [filePath stringByAppendingString:@"/cashe.db"]; 36 | self.db = [FMDatabase databaseWithPath:dbFilePath]; 37 | } 38 | 39 | //打开数据库 40 | -(void)openDB 41 | { 42 | if (![self.db open]) { 43 | [self.db open]; 44 | } 45 | //为数据库设置缓存,提高查询效率 46 | [self.db setShouldCacheStatements:YES]; 47 | } 48 | 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/NSString+MJExtension.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+MJExtension.h 3 | // MJExtensionExample 4 | // 5 | // Created by MJ Lee on 15/6/7. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MJExtensionConst.h" 11 | 12 | @interface NSString (MJExtension) 13 | /** 14 | * 驼峰转下划线(loveYou -> love_you) 15 | */ 16 | - (NSString *)mj_underlineFromCamel; 17 | /** 18 | * 下划线转驼峰(love_you -> loveYou) 19 | */ 20 | - (NSString *)mj_camelFromUnderline; 21 | /** 22 | * 首字母变大写 23 | */ 24 | - (NSString *)mj_firstCharUpper; 25 | /** 26 | * 首字母变小写 27 | */ 28 | - (NSString *)mj_firstCharLower; 29 | 30 | - (BOOL)mj_isPureInt; 31 | 32 | - (NSURL *)mj_url; 33 | @end 34 | 35 | @interface NSString (MJExtensionDeprecated_v_2_5_16) 36 | - (NSString *)underlineFromCamel MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***"); 37 | - (NSString *)camelFromUnderline MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***"); 38 | - (NSString *)firstCharUpper MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***"); 39 | - (NSString *)firstCharLower MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***"); 40 | - (BOOL)isPureInt MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***"); 41 | - (NSURL *)url MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***"); 42 | @end 43 | -------------------------------------------------------------------------------- /LocaShopCar.xcodeproj/xcuserdata/letian.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 18 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /LocaShopCar/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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/IQToolbar/IQPreviousNextView.m: -------------------------------------------------------------------------------- 1 | // 2 | // IQPreviousNextView.m 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "IQPreviousNextView.h" 25 | 26 | @implementation IQPreviousNextView 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/IQToolbar/IQBarButtonItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // IQBarButtonItem.h 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | 25 | #import 26 | 27 | /** 28 | IQBarButtonItem used for IQToolbar. 29 | */ 30 | @interface IQBarButtonItem : UIBarButtonItem 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/MJProperty.h: -------------------------------------------------------------------------------- 1 | // 2 | // MJProperty.h 3 | // MJExtensionExample 4 | // 5 | // Created by MJ Lee on 15/4/17. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 包装一个成员属性 8 | 9 | #import 10 | #import 11 | #import "MJPropertyType.h" 12 | #import "MJPropertyKey.h" 13 | 14 | /** 15 | * 包装一个成员 16 | */ 17 | @interface MJProperty : NSObject 18 | /** 成员属性 */ 19 | @property (nonatomic, assign) objc_property_t property; 20 | /** 成员属性的名字 */ 21 | @property (nonatomic, readonly) NSString *name; 22 | 23 | /** 成员属性的类型 */ 24 | @property (nonatomic, readonly) MJPropertyType *type; 25 | /** 成员属性来源于哪个类(可能是父类) */ 26 | @property (nonatomic, assign) Class srcClass; 27 | 28 | /**** 同一个成员属性 - 父类和子类的行为可能不一致(originKey、propertyKeys、objectClassInArray) ****/ 29 | /** 设置最原始的key */ 30 | - (void)setOriginKey:(id)originKey forClass:(Class)c; 31 | /** 对应着字典中的多级key(里面存放的数组,数组里面都是MJPropertyKey对象) */ 32 | - (NSArray *)propertyKeysForClass:(Class)c; 33 | 34 | /** 模型数组中的模型类型 */ 35 | - (void)setObjectClassInArray:(Class)objectClass forClass:(Class)c; 36 | - (Class)objectClassInArrayForClass:(Class)c; 37 | /**** 同一个成员变量 - 父类和子类的行为可能不一致(key、keys、objectClassInArray) ****/ 38 | 39 | /** 40 | * 设置object的成员变量值 41 | */ 42 | - (void)setValue:(id)value forObject:(id)object; 43 | /** 44 | * 得到object的成员属性值 45 | */ 46 | - (id)valueForObject:(id)object; 47 | 48 | /** 49 | * 初始化 50 | */ 51 | + (instancetype)cachedPropertyWithProperty:(objc_property_t)property; 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/MJFoundation.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJFoundation.m 3 | // MJExtensionExample 4 | // 5 | // Created by MJ Lee on 14/7/16. 6 | // Copyright (c) 2014年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJFoundation.h" 10 | #import "MJExtensionConst.h" 11 | #import 12 | 13 | static NSSet *foundationClasses_; 14 | 15 | @implementation MJFoundation 16 | 17 | + (NSSet *)foundationClasses 18 | { 19 | if (foundationClasses_ == nil) { 20 | // 集合中没有NSObject,因为几乎所有的类都是继承自NSObject,具体是不是NSObject需要特殊判断 21 | foundationClasses_ = [NSSet setWithObjects: 22 | [NSURL class], 23 | [NSDate class], 24 | [NSValue class], 25 | [NSData class], 26 | [NSError class], 27 | [NSArray class], 28 | [NSDictionary class], 29 | [NSString class], 30 | [NSAttributedString class], nil]; 31 | } 32 | return foundationClasses_; 33 | } 34 | 35 | + (BOOL)isClassFromFoundation:(Class)c 36 | { 37 | if (c == [NSObject class] || c == [NSManagedObject class]) return YES; 38 | 39 | __block BOOL result = NO; 40 | [[self foundationClasses] enumerateObjectsUsingBlock:^(Class foundationClass, BOOL *stop) { 41 | if ([c isSubclassOfClass:foundationClass]) { 42 | result = YES; 43 | *stop = YES; 44 | } 45 | }]; 46 | return result; 47 | } 48 | @end 49 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/IQToolbar/IQPreviousNextView.h: -------------------------------------------------------------------------------- 1 | // 2 | // IQPreviousNextView.h 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import 25 | 26 | /** 27 | If you need to enable previous/next toolbar button with some complex hierarchy where your textFields are not in same view, then make the top view as IQPreviousNextView. 28 | */ 29 | @interface IQPreviousNextView : UIView 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Categories/IQUIScrollView+Additions.h: -------------------------------------------------------------------------------- 1 | // 2 | // IQUIScrollView+Additions.h 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import 25 | 26 | 27 | @interface UIScrollView (Additions) 28 | 29 | /** 30 | Restore scrollViewContentOffset when resigning from scrollView. Default is NO. 31 | */ 32 | @property(nonatomic, assign) BOOL shouldRestoreScrollViewContentOffset; 33 | 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Categories/IQUIViewController+Additions.h: -------------------------------------------------------------------------------- 1 | // 2 | // IQUIViewController+Additions.h 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import 25 | 26 | @interface UIViewController (Additions) 27 | 28 | /** 29 | Top/Bottom Layout constraint which help library to manage keyboardTextField distance 30 | */ 31 | @property(nullable, nonatomic, strong) IBOutlet NSLayoutConstraint *IQLayoutGuideConstraint; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/IQTextView/IQTextView.h: -------------------------------------------------------------------------------- 1 | // 2 | // IQTextView.h 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "IQKeyboardManagerConstants.h" 25 | 26 | #import 27 | 28 | /** 29 | UITextView with placeholder support 30 | */ 31 | @interface IQTextView : UITextView 32 | 33 | /** 34 | Set textView's placeholder text. Default is nil. 35 | */ 36 | @property(nullable, nonatomic,copy) IBInspectable NSString *placeholder; 37 | 38 | @end 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /LocaShopCar/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 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Categories/IQUIViewController+Additions.m: -------------------------------------------------------------------------------- 1 | // 2 | // IQUIViewController+Additions.m 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "IQUIViewController+Additions.h" 25 | #import 26 | 27 | @implementation UIViewController (Additions) 28 | 29 | -(void)setIQLayoutGuideConstraint:(NSLayoutConstraint *)IQLayoutGuideConstraint 30 | { 31 | objc_setAssociatedObject(self, @selector(IQLayoutGuideConstraint), IQLayoutGuideConstraint, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 32 | } 33 | 34 | -(NSLayoutConstraint *)IQLayoutGuideConstraint 35 | { 36 | return objc_getAssociatedObject(self, @selector(IQLayoutGuideConstraint)); 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Categories/IQNSArray+Sort.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+Sort.h 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import 25 | 26 | /** 27 | UIView.subviews sorting category. 28 | */ 29 | @interface NSArray (IQ_NSArray_Sort) 30 | 31 | ///-------------- 32 | /// @name Sorting 33 | ///-------------- 34 | 35 | /** 36 | Returns the array by sorting the UIView's by their tag property. 37 | */ 38 | @property (nonatomic, readonly, copy) NSArray * _Nonnull sortedArrayByTag; 39 | 40 | /** 41 | Returns the array by sorting the UIView's by their tag property. 42 | */ 43 | @property (nonatomic, readonly, copy) NSArray * _Nonnull sortedArrayByPosition; 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Categories/IQUIWindow+Hierarchy.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIWindow+Hierarchy.h 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import 25 | 26 | @class UIViewController; 27 | 28 | /** 29 | UIWindow hierarchy category. 30 | */ 31 | @interface UIWindow (IQ_UIWindow_Hierarchy) 32 | 33 | ///---------------------- 34 | /// @name viewControllers 35 | ///---------------------- 36 | 37 | /** 38 | Returns the current Top Most ViewController in hierarchy. 39 | */ 40 | @property (nullable, nonatomic, readonly, strong) UIViewController *topMostController; 41 | 42 | /** 43 | Returns the topViewController in stack of topMostController. 44 | */ 45 | @property (nullable, nonatomic, readonly, strong) UIViewController *currentViewController; 46 | 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Categories/IQUITextFieldView+Additions.h: -------------------------------------------------------------------------------- 1 | // 2 | // IQUITextFieldView+Additions.h 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import 25 | 26 | /** 27 | UIView category for managing UITextField/UITextView 28 | */ 29 | 30 | @interface UIView (Additions) 31 | 32 | /** 33 | To set customized distance from keyboard for textField/textView. Can't be less than zero 34 | */ 35 | @property(nonatomic, assign) CGFloat keyboardDistanceFromTextField; 36 | 37 | @end 38 | 39 | ///------------------------------------------- 40 | /// @name Custom KeyboardDistanceFromTextField 41 | ///------------------------------------------- 42 | 43 | /** 44 | Uses default keyboard distance for textField. 45 | */ 46 | extern CGFloat const kIQUseDefaultKeyboardDistance; 47 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Categories/IQUIScrollView+Additions.m: -------------------------------------------------------------------------------- 1 | // 2 | // IQUIScrollView+Additions.m 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "IQUIScrollView+Additions.h" 25 | #import 26 | 27 | @implementation UIScrollView (Additions) 28 | 29 | -(void)setShouldRestoreScrollViewContentOffset:(BOOL)shouldRestoreScrollViewContentOffset 30 | { 31 | objc_setAssociatedObject(self, @selector(shouldRestoreScrollViewContentOffset), @(shouldRestoreScrollViewContentOffset), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 32 | } 33 | 34 | -(BOOL)shouldRestoreScrollViewContentOffset 35 | { 36 | NSNumber *shouldRestoreScrollViewContentOffset = objc_getAssociatedObject(self, @selector(shouldRestoreScrollViewContentOffset)); 37 | 38 | return [shouldRestoreScrollViewContentOffset boolValue]; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/NSObject+MJCoding.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+MJCoding.m 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "NSObject+MJCoding.h" 10 | #import "NSObject+MJClass.h" 11 | #import "NSObject+MJProperty.h" 12 | #import "MJProperty.h" 13 | 14 | @implementation NSObject (MJCoding) 15 | 16 | - (void)mj_encode:(NSCoder *)encoder 17 | { 18 | Class clazz = [self class]; 19 | 20 | NSArray *allowedCodingPropertyNames = [clazz mj_totalAllowedCodingPropertyNames]; 21 | NSArray *ignoredCodingPropertyNames = [clazz mj_totalIgnoredCodingPropertyNames]; 22 | 23 | [clazz mj_enumerateProperties:^(MJProperty *property, BOOL *stop) { 24 | // 检测是否被忽略 25 | if (allowedCodingPropertyNames.count && ![allowedCodingPropertyNames containsObject:property.name]) return; 26 | if ([ignoredCodingPropertyNames containsObject:property.name]) return; 27 | 28 | id value = [property valueForObject:self]; 29 | if (value == nil) return; 30 | [encoder encodeObject:value forKey:property.name]; 31 | }]; 32 | } 33 | 34 | - (void)mj_decode:(NSCoder *)decoder 35 | { 36 | Class clazz = [self class]; 37 | 38 | NSArray *allowedCodingPropertyNames = [clazz mj_totalAllowedCodingPropertyNames]; 39 | NSArray *ignoredCodingPropertyNames = [clazz mj_totalIgnoredCodingPropertyNames]; 40 | 41 | [clazz mj_enumerateProperties:^(MJProperty *property, BOOL *stop) { 42 | // 检测是否被忽略 43 | if (allowedCodingPropertyNames.count && ![allowedCodingPropertyNames containsObject:property.name]) return; 44 | if ([ignoredCodingPropertyNames containsObject:property.name]) return; 45 | 46 | id value = [decoder decodeObjectForKey:property.name]; 47 | if (value == nil) { // 兼容以前的MJExtension版本 48 | value = [decoder decodeObjectForKey:[@"_" stringByAppendingString:property.name]]; 49 | } 50 | if (value == nil) return; 51 | [property setValue:value forObject:self]; 52 | }]; 53 | } 54 | @end 55 | -------------------------------------------------------------------------------- /LocaShopCar/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // LocaShopCar 4 | // 5 | // Created by xhl on 16/7/17. 6 | // Copyright © 2016年 xhl. 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 | return YES; 20 | } 21 | 22 | - (void)applicationWillResignActive:(UIApplication *)application { 23 | // 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. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | - (void)applicationDidEnterBackground:(UIApplication *)application { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | - (void)applicationWillEnterForeground:(UIApplication *)application { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | - (void)applicationDidBecomeActive:(UIApplication *)application { 37 | // 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. 38 | } 39 | 40 | - (void)applicationWillTerminate:(UIApplication *)application { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Constants/IQKeyboardManagerConstantsInternal.h: -------------------------------------------------------------------------------- 1 | // 2 | // IQKeyboardManagerConstantsInternal.h 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #ifndef IQKeyboardManagerConstantsInternal_h 25 | #define IQKeyboardManagerConstantsInternal_h 26 | 27 | 28 | ///----------------------------------- 29 | /// @name IQLayoutGuidePosition 30 | ///----------------------------------- 31 | 32 | /** 33 | `IQLayoutGuidePositionNone` 34 | If there are no IQLayoutGuideConstraint associated with viewController 35 | 36 | `IQLayoutGuidePositionTop` 37 | If provided IQLayoutGuideConstraint is associated with with viewController topLayoutGuide 38 | 39 | `IQLayoutGuidePositionBottom` 40 | If provided IQLayoutGuideConstraint is associated with with viewController bottomLayoutGuide 41 | */ 42 | typedef NS_ENUM(NSInteger, IQLayoutGuidePosition) { 43 | IQLayoutGuidePositionNone, 44 | IQLayoutGuidePositionTop, 45 | IQLayoutGuidePositionBottom, 46 | }; 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Categories/IQUIWindow+Hierarchy.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIWindow+Hierarchy.m 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "IQUIWindow+Hierarchy.h" 25 | #import 26 | 27 | @implementation UIWindow (IQ_UIWindow_Hierarchy) 28 | 29 | - (UIViewController*)topMostController 30 | { 31 | UIViewController *topController = [self rootViewController]; 32 | 33 | // Getting topMost ViewController 34 | while ([topController presentedViewController]) topController = [topController presentedViewController]; 35 | 36 | // Returning topMost ViewController 37 | return topController; 38 | } 39 | 40 | - (UIViewController*)currentViewController; 41 | { 42 | UIViewController *currentViewController = [self topMostController]; 43 | 44 | while ([currentViewController isKindOfClass:[UINavigationController class]] && [(UINavigationController*)currentViewController topViewController]) 45 | currentViewController = [(UINavigationController*)currentViewController topViewController]; 46 | 47 | return currentViewController; 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/MJPropertyType.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJPropertyType.m 3 | // MJExtension 4 | // 5 | // Created by mj on 14-1-15. 6 | // Copyright (c) 2014年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJPropertyType.h" 10 | #import "MJExtension.h" 11 | #import "MJFoundation.h" 12 | #import "MJExtensionConst.h" 13 | 14 | @implementation MJPropertyType 15 | 16 | static NSMutableDictionary *types_; 17 | + (void)initialize 18 | { 19 | types_ = [NSMutableDictionary dictionary]; 20 | } 21 | 22 | + (instancetype)cachedTypeWithCode:(NSString *)code 23 | { 24 | MJExtensionAssertParamNotNil2(code, nil); 25 | 26 | MJPropertyType *type = types_[code]; 27 | if (type == nil) { 28 | type = [[self alloc] init]; 29 | type.code = code; 30 | types_[code] = type; 31 | } 32 | return type; 33 | } 34 | 35 | #pragma mark - 公共方法 36 | - (void)setCode:(NSString *)code 37 | { 38 | _code = code; 39 | 40 | MJExtensionAssertParamNotNil(code); 41 | 42 | if ([code isEqualToString:MJPropertyTypeId]) { 43 | _idType = YES; 44 | } else if (code.length == 0) { 45 | _KVCDisabled = YES; 46 | } else if (code.length > 3 && [code hasPrefix:@"@\""]) { 47 | // 去掉@"和",截取中间的类型名称 48 | _code = [code substringWithRange:NSMakeRange(2, code.length - 3)]; 49 | _typeClass = NSClassFromString(_code); 50 | _fromFoundation = [MJFoundation isClassFromFoundation:_typeClass]; 51 | _numberType = [_typeClass isSubclassOfClass:[NSNumber class]]; 52 | 53 | } else if ([code isEqualToString:MJPropertyTypeSEL] || 54 | [code isEqualToString:MJPropertyTypeIvar] || 55 | [code isEqualToString:MJPropertyTypeMethod]) { 56 | _KVCDisabled = YES; 57 | } 58 | 59 | // 是否为数字类型 60 | NSString *lowerCode = _code.lowercaseString; 61 | NSArray *numberTypes = @[MJPropertyTypeInt, MJPropertyTypeShort, MJPropertyTypeBOOL1, MJPropertyTypeBOOL2, MJPropertyTypeFloat, MJPropertyTypeDouble, MJPropertyTypeLong, MJPropertyTypeLongLong, MJPropertyTypeChar]; 62 | if ([numberTypes containsObject:lowerCode]) { 63 | _numberType = YES; 64 | 65 | if ([lowerCode isEqualToString:MJPropertyTypeBOOL1] 66 | || [lowerCode isEqualToString:MJPropertyTypeBOOL2]) { 67 | _boolType = YES; 68 | } 69 | } 70 | } 71 | @end 72 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/IQToolbar/IQToolbar.h: -------------------------------------------------------------------------------- 1 | // 2 | // IQToolbar.h 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import 25 | 26 | /** 27 | IQToolbar for IQKeyboardManager. 28 | */ 29 | @interface IQToolbar : UIToolbar 30 | 31 | /** 32 | Title font for toolbar. 33 | */ 34 | @property(nullable, nonatomic, strong) UIFont *titleFont; 35 | 36 | /** 37 | Toolbar done title 38 | */ 39 | @property(nullable, nonatomic, strong) NSString *doneTitle; 40 | 41 | /** 42 | Toolbar done image 43 | */ 44 | @property(nullable, nonatomic, strong) UIImage *doneImage; 45 | 46 | /** 47 | Toolbar title 48 | */ 49 | @property(nullable, nonatomic, strong) NSString *title; 50 | 51 | /** 52 | Optional target & action to behave toolbar title button as clickable button 53 | 54 | @param target Target object. 55 | @param action Target Selector. 56 | */ 57 | -(void)setTitleTarget:(nullable id)target action:(nullable SEL)action; 58 | 59 | /** 60 | Customized Invocation to be called on title button action. titleInvocation is internally created using setTitleTarget:action: method. 61 | */ 62 | @property (nullable, strong, nonatomic) NSInvocation *titleInvocation; 63 | 64 | @end 65 | 66 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Categories/IQUITextFieldView+Additions.m: -------------------------------------------------------------------------------- 1 | // 2 | // IQUITextFieldView+Additions.m 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "IQUITextFieldView+Additions.h" 25 | #import 26 | 27 | @implementation UIView (Additions) 28 | 29 | -(void)setKeyboardDistanceFromTextField:(CGFloat)keyboardDistanceFromTextField 30 | { 31 | //Can't be less than zero. Minimum is zero. 32 | keyboardDistanceFromTextField = MAX(keyboardDistanceFromTextField, 0); 33 | 34 | objc_setAssociatedObject(self, @selector(keyboardDistanceFromTextField), [NSNumber numberWithFloat:keyboardDistanceFromTextField], OBJC_ASSOCIATION_RETAIN_NONATOMIC); 35 | } 36 | 37 | -(CGFloat)keyboardDistanceFromTextField 38 | { 39 | NSNumber *keyboardDistanceFromTextField = objc_getAssociatedObject(self, @selector(keyboardDistanceFromTextField)); 40 | 41 | return (keyboardDistanceFromTextField)?[keyboardDistanceFromTextField floatValue]:kIQUseDefaultKeyboardDistance; 42 | } 43 | 44 | @end 45 | 46 | ///------------------------------------ 47 | /// @name keyboardDistanceFromTextField 48 | ///------------------------------------ 49 | 50 | /** 51 | Uses default keyboard distance for textField. 52 | */ 53 | CGFloat const kIQUseDefaultKeyboardDistance = CGFLOAT_MAX; 54 | 55 | -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/MJExtensionConst.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef __MJExtensionConst__H__ 3 | #define __MJExtensionConst__H__ 4 | 5 | #import 6 | 7 | // 过期 8 | #define MJExtensionDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead) 9 | 10 | // 构建错误 11 | #define MJExtensionBuildError(clazz, msg) \ 12 | NSError *error = [NSError errorWithDomain:msg code:250 userInfo:nil]; \ 13 | [clazz setMj_error:error]; 14 | 15 | // 日志输出 16 | #ifdef DEBUG 17 | #define MJExtensionLog(...) NSLog(__VA_ARGS__) 18 | #else 19 | #define MJExtensionLog(...) 20 | #endif 21 | 22 | /** 23 | * 断言 24 | * @param condition 条件 25 | * @param returnValue 返回值 26 | */ 27 | #define MJExtensionAssertError(condition, returnValue, clazz, msg) \ 28 | [clazz setMj_error:nil]; \ 29 | if ((condition) == NO) { \ 30 | MJExtensionBuildError(clazz, msg); \ 31 | return returnValue;\ 32 | } 33 | 34 | #define MJExtensionAssert2(condition, returnValue) \ 35 | if ((condition) == NO) return returnValue; 36 | 37 | /** 38 | * 断言 39 | * @param condition 条件 40 | */ 41 | #define MJExtensionAssert(condition) MJExtensionAssert2(condition, ) 42 | 43 | /** 44 | * 断言 45 | * @param param 参数 46 | * @param returnValue 返回值 47 | */ 48 | #define MJExtensionAssertParamNotNil2(param, returnValue) \ 49 | MJExtensionAssert2((param) != nil, returnValue) 50 | 51 | /** 52 | * 断言 53 | * @param param 参数 54 | */ 55 | #define MJExtensionAssertParamNotNil(param) MJExtensionAssertParamNotNil2(param, ) 56 | 57 | /** 58 | * 打印所有的属性 59 | */ 60 | #define MJLogAllIvars \ 61 | -(NSString *)description \ 62 | { \ 63 | return [self mj_keyValues].description; \ 64 | } 65 | #define MJExtensionLogAllProperties MJLogAllIvars 66 | 67 | /** 68 | * 类型(属性类型) 69 | */ 70 | extern NSString *const MJPropertyTypeInt; 71 | extern NSString *const MJPropertyTypeShort; 72 | extern NSString *const MJPropertyTypeFloat; 73 | extern NSString *const MJPropertyTypeDouble; 74 | extern NSString *const MJPropertyTypeLong; 75 | extern NSString *const MJPropertyTypeLongLong; 76 | extern NSString *const MJPropertyTypeChar; 77 | extern NSString *const MJPropertyTypeBOOL1; 78 | extern NSString *const MJPropertyTypeBOOL2; 79 | extern NSString *const MJPropertyTypePointer; 80 | 81 | extern NSString *const MJPropertyTypeIvar; 82 | extern NSString *const MJPropertyTypeMethod; 83 | extern NSString *const MJPropertyTypeBlock; 84 | extern NSString *const MJPropertyTypeClass; 85 | extern NSString *const MJPropertyTypeSEL; 86 | extern NSString *const MJPropertyTypeId; 87 | 88 | #endif -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/NSObject+MJClass.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+MJClass.h 3 | // MJExtensionExample 4 | // 5 | // Created by MJ Lee on 15/8/11. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** 12 | * 遍历所有类的block(父类) 13 | */ 14 | typedef void (^MJClassesEnumeration)(Class c, BOOL *stop); 15 | 16 | /** 这个数组中的属性名才会进行字典和模型的转换 */ 17 | typedef NSArray * (^MJAllowedPropertyNames)(); 18 | /** 这个数组中的属性名才会进行归档 */ 19 | typedef NSArray * (^MJAllowedCodingPropertyNames)(); 20 | 21 | /** 这个数组中的属性名将会被忽略:不进行字典和模型的转换 */ 22 | typedef NSArray * (^MJIgnoredPropertyNames)(); 23 | /** 这个数组中的属性名将会被忽略:不进行归档 */ 24 | typedef NSArray * (^MJIgnoredCodingPropertyNames)(); 25 | 26 | /** 27 | * 类相关的扩展 28 | */ 29 | @interface NSObject (MJClass) 30 | /** 31 | * 遍历所有的类 32 | */ 33 | + (void)mj_enumerateClasses:(MJClassesEnumeration)enumeration; 34 | + (void)mj_enumerateAllClasses:(MJClassesEnumeration)enumeration; 35 | 36 | #pragma mark - 属性白名单配置 37 | /** 38 | * 这个数组中的属性名才会进行字典和模型的转换 39 | * 40 | * @param allowedPropertyNames 这个数组中的属性名才会进行字典和模型的转换 41 | */ 42 | + (void)mj_setupAllowedPropertyNames:(MJAllowedPropertyNames)allowedPropertyNames; 43 | 44 | /** 45 | * 这个数组中的属性名才会进行字典和模型的转换 46 | */ 47 | + (NSMutableArray *)mj_totalAllowedPropertyNames; 48 | 49 | #pragma mark - 属性黑名单配置 50 | /** 51 | * 这个数组中的属性名将会被忽略:不进行字典和模型的转换 52 | * 53 | * @param ignoredPropertyNames 这个数组中的属性名将会被忽略:不进行字典和模型的转换 54 | */ 55 | + (void)mj_setupIgnoredPropertyNames:(MJIgnoredPropertyNames)ignoredPropertyNames; 56 | 57 | /** 58 | * 这个数组中的属性名将会被忽略:不进行字典和模型的转换 59 | */ 60 | + (NSMutableArray *)mj_totalIgnoredPropertyNames; 61 | 62 | #pragma mark - 归档属性白名单配置 63 | /** 64 | * 这个数组中的属性名才会进行归档 65 | * 66 | * @param allowedCodingPropertyNames 这个数组中的属性名才会进行归档 67 | */ 68 | + (void)mj_setupAllowedCodingPropertyNames:(MJAllowedCodingPropertyNames)allowedCodingPropertyNames; 69 | 70 | /** 71 | * 这个数组中的属性名才会进行字典和模型的转换 72 | */ 73 | + (NSMutableArray *)mj_totalAllowedCodingPropertyNames; 74 | 75 | #pragma mark - 归档属性黑名单配置 76 | /** 77 | * 这个数组中的属性名将会被忽略:不进行归档 78 | * 79 | * @param ignoredCodingPropertyNames 这个数组中的属性名将会被忽略:不进行归档 80 | */ 81 | + (void)mj_setupIgnoredCodingPropertyNames:(MJIgnoredCodingPropertyNames)ignoredCodingPropertyNames; 82 | 83 | /** 84 | * 这个数组中的属性名将会被忽略:不进行归档 85 | */ 86 | + (NSMutableArray *)mj_totalIgnoredCodingPropertyNames; 87 | 88 | #pragma mark - 内部使用 89 | + (void)mj_setupBlockReturnValue:(id (^)())block key:(const char *)key; 90 | @end 91 | -------------------------------------------------------------------------------- /LocaShopCar/ShopCarHeaderView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ShopCarHeaderView.m 3 | // LocaShopCar 4 | // 5 | // Created by letian on 16/8/23. 6 | // Copyright © 2016年 xhl. All rights reserved. 7 | // 8 | 9 | #import "ShopCarHeaderView.h" 10 | #import "ShopCarGruopModel.h" 11 | #import "ShopCarModel.h" 12 | 13 | @interface ShopCarHeaderView () 14 | 15 | /** label */ 16 | @property (nonatomic,weak) UILabel * shopName; 17 | 18 | /** 全选button */ 19 | @property (nonatomic,weak) UIButton * selectButton; 20 | 21 | /** 实体 */ 22 | @property (nonatomic,strong) ShopCarGruopModel * model; 23 | 24 | 25 | @end 26 | 27 | 28 | @implementation ShopCarHeaderView 29 | 30 | 31 | + (instancetype)backHeaderViewWithTableView:(UITableView *)tableView 32 | { 33 | ShopCarHeaderView * headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:NSStringFromClass(self)]; 34 | 35 | if (headerView == nil) { 36 | headerView = [[ShopCarHeaderView alloc] initWithReuseIdentifier:NSStringFromClass(self)]; 37 | } 38 | return headerView; 39 | } 40 | 41 | - (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier 42 | { 43 | if (self = [super initWithReuseIdentifier:reuseIdentifier]) { 44 | 45 | self.contentView.backgroundColor = [UIColor whiteColor]; 46 | UIButton * selectButton = [UIButton buttonWithType:UIButtonTypeCustom]; 47 | selectButton.backgroundColor = [UIColor whiteColor]; 48 | [self.contentView addSubview:selectButton]; 49 | selectButton.frame = CGRectMake(9, 0, 40, 40); 50 | [selectButton addTarget:self action:@selector(viewClick) forControlEvents:UIControlEventTouchUpInside]; 51 | self.selectButton = selectButton; 52 | 53 | UILabel * headerLbl = [[UILabel alloc] initWithFrame:CGRectMake(49, 0, [UIScreen mainScreen].bounds.size.width-40, 40)]; 54 | headerLbl.backgroundColor = [UIColor whiteColor]; 55 | headerLbl.textColor = [UIColor blueColor]; 56 | [self.contentView addSubview:headerLbl]; 57 | self.shopName = headerLbl; 58 | } 59 | 60 | return self; 61 | } 62 | 63 | - (void)headerViewDataWtihModel:(ShopCarGruopModel *)model; 64 | { 65 | self.model = model; 66 | 67 | self.shopName.text = [NSString stringWithFormat:@" %@",model.shopName]; 68 | 69 | UIImage * selectImg = model.isSelect ? [UIImage imageNamed:@"tm_mcart_checked"] : [UIImage imageNamed:@"tm_mcart_unchecked"]; 70 | [self.selectButton setImage:selectImg forState:UIControlStateNormal]; 71 | } 72 | 73 | - (void)viewClick 74 | { 75 | self.model.select = !self.model.select; 76 | 77 | for (ShopCarModel * model in self.model.goods) { 78 | model.select = self.model.select; 79 | } 80 | 81 | if (self.callBack) { 82 | self.callBack(); 83 | } 84 | } 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Categories/IQNSArray+Sort.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+Sort.m 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "IQNSArray+Sort.h" 25 | #import "IQUIView+Hierarchy.h" 26 | 27 | #import 28 | 29 | @implementation NSArray (IQ_NSArray_Sort) 30 | 31 | - (NSArray*)sortedArrayByTag 32 | { 33 | return [self sortedArrayUsingComparator:^NSComparisonResult(UIView *view1, UIView *view2) { 34 | 35 | if ([view1 respondsToSelector:@selector(tag)] && [view2 respondsToSelector:@selector(tag)]) 36 | { 37 | if ([view1 tag] < [view2 tag]) return NSOrderedAscending; 38 | 39 | else if ([view1 tag] > [view2 tag]) return NSOrderedDescending; 40 | 41 | else return NSOrderedSame; 42 | } 43 | else 44 | return NSOrderedSame; 45 | }]; 46 | } 47 | 48 | - (NSArray*)sortedArrayByPosition 49 | { 50 | return [self sortedArrayUsingComparator:^NSComparisonResult(UIView *view1, UIView *view2) { 51 | 52 | CGFloat x1 = CGRectGetMinX(view1.frame); 53 | CGFloat y1 = CGRectGetMinY(view1.frame); 54 | CGFloat x2 = CGRectGetMinX(view2.frame); 55 | CGFloat y2 = CGRectGetMinY(view2.frame); 56 | 57 | if (y1 < y2) return NSOrderedAscending; 58 | 59 | else if (y1 > y2) return NSOrderedDescending; 60 | 61 | //Else both y are same so checking for x positions 62 | else if (x1 < x2) return NSOrderedAscending; 63 | 64 | else if (x1 > x2) return NSOrderedDescending; 65 | 66 | else return NSOrderedSame; 67 | }]; 68 | } 69 | 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/IQToolbar/IQTitleBarButtonItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // IQTitleBarButtonItem.h 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import 25 | #import "IQKeyboardManagerConstants.h" 26 | #import "IQBarButtonItem.h" 27 | 28 | /** 29 | BarButtonItem with title text. 30 | */ 31 | @interface IQTitleBarButtonItem : IQBarButtonItem 32 | 33 | /** 34 | Font to be used in bar button. Default is (system font 12.0 bold). 35 | */ 36 | @property(nullable, nonatomic, strong) UIFont *font; 37 | 38 | /** 39 | selectableTextColor to be used for displaying button text when button is enabled. 40 | */ 41 | @property(nullable, nonatomic, strong) UIColor *selectableTextColor; 42 | 43 | /** 44 | Initialize with frame and title. 45 | 46 | @param title Title of barButtonItem. 47 | */ 48 | -(nonnull instancetype)initWithTitle:(nullable NSString *)title NS_DESIGNATED_INITIALIZER; 49 | 50 | /** 51 | Optional target & action to behave toolbar title button as clickable button 52 | 53 | @param target Target object. 54 | @param action Target Selector. 55 | */ 56 | -(void)setTitleTarget:(nullable id)target action:(nullable SEL)action; 57 | 58 | /** 59 | Customized Invocation to be called on title button action. titleInvocation is internally created using setTitleTarget:action: method. 60 | */ 61 | @property (nullable, strong, nonatomic) NSInvocation *titleInvocation; 62 | 63 | /** 64 | Unavailable. Please use initWithFrame:title: method 65 | */ 66 | -(nonnull instancetype)init NS_UNAVAILABLE; 67 | 68 | /** 69 | Unavailable. Please use initWithFrame:title: method 70 | */ 71 | -(nonnull instancetype)initWithCoder:(nullable NSCoder *)aDecoder NS_UNAVAILABLE; 72 | 73 | /** 74 | Unavailable. Please use initWithFrame:title: method 75 | */ 76 | + (nonnull instancetype)new NS_UNAVAILABLE; 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/NSObject+MJProperty.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+MJProperty.h 3 | // MJExtensionExample 4 | // 5 | // Created by MJ Lee on 15/4/17. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MJExtensionConst.h" 11 | 12 | @class MJProperty; 13 | 14 | /** 15 | * 遍历成员变量用的block 16 | * 17 | * @param property 成员的包装对象 18 | * @param stop YES代表停止遍历,NO代表继续遍历 19 | */ 20 | typedef void (^MJPropertiesEnumeration)(MJProperty *property, BOOL *stop); 21 | 22 | /** 将属性名换为其他key去字典中取值 */ 23 | typedef NSDictionary * (^MJReplacedKeyFromPropertyName)(); 24 | typedef id (^MJReplacedKeyFromPropertyName121)(NSString *propertyName); 25 | /** 数组中需要转换的模型类 */ 26 | typedef NSDictionary * (^MJObjectClassInArray)(); 27 | /** 用于过滤字典中的值 */ 28 | typedef id (^MJNewValueFromOldValue)(id object, id oldValue, MJProperty *property); 29 | 30 | /** 31 | * 成员属性相关的扩展 32 | */ 33 | @interface NSObject (MJProperty) 34 | #pragma mark - 遍历 35 | /** 36 | * 遍历所有的成员 37 | */ 38 | + (void)mj_enumerateProperties:(MJPropertiesEnumeration)enumeration; 39 | 40 | #pragma mark - 新值配置 41 | /** 42 | * 用于过滤字典中的值 43 | * 44 | * @param newValueFormOldValue 用于过滤字典中的值 45 | */ 46 | + (void)mj_setupNewValueFromOldValue:(MJNewValueFromOldValue)newValueFormOldValue; 47 | + (id)mj_getNewValueFromObject:(__unsafe_unretained id)object oldValue:(__unsafe_unretained id)oldValue property:(__unsafe_unretained MJProperty *)property; 48 | 49 | #pragma mark - key配置 50 | /** 51 | * 将属性名换为其他key去字典中取值 52 | * 53 | * @param replacedKeyFromPropertyName 将属性名换为其他key去字典中取值 54 | */ 55 | + (void)mj_setupReplacedKeyFromPropertyName:(MJReplacedKeyFromPropertyName)replacedKeyFromPropertyName; 56 | /** 57 | * 将属性名换为其他key去字典中取值 58 | * 59 | * @param replacedKeyFromPropertyName121 将属性名换为其他key去字典中取值 60 | */ 61 | + (void)mj_setupReplacedKeyFromPropertyName121:(MJReplacedKeyFromPropertyName121)replacedKeyFromPropertyName121; 62 | 63 | #pragma mark - array model class配置 64 | /** 65 | * 数组中需要转换的模型类 66 | * 67 | * @param objectClassInArray 数组中需要转换的模型类 68 | */ 69 | + (void)mj_setupObjectClassInArray:(MJObjectClassInArray)objectClassInArray; 70 | @end 71 | 72 | @interface NSObject (MJPropertyDeprecated_v_2_5_16) 73 | + (void)enumerateProperties:(MJPropertiesEnumeration)enumeration MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***"); 74 | + (void)setupNewValueFromOldValue:(MJNewValueFromOldValue)newValueFormOldValue MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***"); 75 | + (id)getNewValueFromObject:(__unsafe_unretained id)object oldValue:(__unsafe_unretained id)oldValue property:(__unsafe_unretained MJProperty *)property MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***"); 76 | + (void)setupReplacedKeyFromPropertyName:(MJReplacedKeyFromPropertyName)replacedKeyFromPropertyName MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***"); 77 | + (void)setupReplacedKeyFromPropertyName121:(MJReplacedKeyFromPropertyName121)replacedKeyFromPropertyName121 MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***"); 78 | + (void)setupObjectClassInArray:(MJObjectClassInArray)objectClassInArray MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***"); 79 | @end -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/NSString+MJExtension.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+MJExtension.m 3 | // MJExtensionExample 4 | // 5 | // Created by MJ Lee on 15/6/7. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "NSString+MJExtension.h" 10 | 11 | @implementation NSString (MJExtension) 12 | - (NSString *)mj_underlineFromCamel 13 | { 14 | if (self.length == 0) return self; 15 | NSMutableString *string = [NSMutableString string]; 16 | for (NSUInteger i = 0; i= 2) [string appendString:[cmp substringFromIndex:1]]; 40 | } else { 41 | [string appendString:cmp]; 42 | } 43 | } 44 | return string; 45 | } 46 | 47 | - (NSString *)mj_firstCharLower 48 | { 49 | if (self.length == 0) return self; 50 | NSMutableString *string = [NSMutableString string]; 51 | [string appendString:[NSString stringWithFormat:@"%c", [self characterAtIndex:0]].lowercaseString]; 52 | if (self.length >= 2) [string appendString:[self substringFromIndex:1]]; 53 | return string; 54 | } 55 | 56 | - (NSString *)mj_firstCharUpper 57 | { 58 | if (self.length == 0) return self; 59 | NSMutableString *string = [NSMutableString string]; 60 | [string appendString:[NSString stringWithFormat:@"%c", [self characterAtIndex:0]].uppercaseString]; 61 | if (self.length >= 2) [string appendString:[self substringFromIndex:1]]; 62 | return string; 63 | } 64 | 65 | - (BOOL)mj_isPureInt 66 | { 67 | NSScanner *scan = [NSScanner scannerWithString:self]; 68 | int val; 69 | return [scan scanInt:&val] && [scan isAtEnd]; 70 | } 71 | 72 | - (NSURL *)mj_url 73 | { 74 | // [self stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"!$&'()*+,-./:;=?@_~%#[]"]]; 75 | 76 | return [NSURL URLWithString:(NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)self, (CFStringRef)@"!$&'()*+,-./:;=?@_~%#[]", NULL,kCFStringEncodingUTF8))]; 77 | } 78 | @end 79 | 80 | @implementation NSString (MJExtensionDeprecated_v_2_5_16) 81 | - (NSString *)underlineFromCamel 82 | { 83 | return self.mj_underlineFromCamel; 84 | } 85 | 86 | - (NSString *)camelFromUnderline 87 | { 88 | return self.mj_camelFromUnderline; 89 | } 90 | 91 | - (NSString *)firstCharLower 92 | { 93 | return self.mj_firstCharLower; 94 | } 95 | 96 | - (NSString *)firstCharUpper 97 | { 98 | return self.mj_firstCharUpper; 99 | } 100 | 101 | - (BOOL)isPureInt 102 | { 103 | return self.mj_isPureInt; 104 | } 105 | 106 | - (NSURL *)url 107 | { 108 | return self.mj_url; 109 | } 110 | @end 111 | -------------------------------------------------------------------------------- /LocaShopCar.xcodeproj/xcuserdata/ty.xcuserdatad/xcschemes/LocaShopCar.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /LocaShopCar.xcodeproj/xcuserdata/xhl.xcuserdatad/xcschemes/LocaShopCar.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /LocaShopCar.xcodeproj/xcuserdata/letian.xcuserdatad/xcschemes/LocaShopCar.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/IQKeyboardReturnKeyHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // IQKeyboardReturnKeyHandler.h 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "IQKeyboardManagerConstants.h" 25 | 26 | #import 27 | #import 28 | 29 | #import 30 | #import 31 | 32 | @class UITextField,UIView, UIViewController; 33 | 34 | /** 35 | Manages the return key to work like next/done in a view hierarchy. 36 | */ 37 | @interface IQKeyboardReturnKeyHandler : NSObject 38 | 39 | ///---------------------- 40 | /// @name Initializations 41 | ///---------------------- 42 | 43 | /** 44 | Add all the textFields available in UIViewController's view. 45 | */ 46 | -(nonnull instancetype)initWithViewController:(nullable UIViewController*)controller NS_DESIGNATED_INITIALIZER; 47 | 48 | /** 49 | Unavailable. Please use initWithViewController: or init method 50 | */ 51 | -(nonnull instancetype)initWithCoder:(nullable NSCoder *)aDecoder NS_UNAVAILABLE; 52 | 53 | ///--------------- 54 | /// @name Settings 55 | ///--------------- 56 | 57 | /** 58 | Delegate of textField/textView. 59 | */ 60 | @property(nullable, nonatomic, weak) id delegate; 61 | 62 | /** 63 | Set the last textfield return key type. Default is UIReturnKeyDefault. 64 | */ 65 | @property(nonatomic, assign) UIReturnKeyType lastTextFieldReturnKeyType; 66 | 67 | ///---------------------------------------------- 68 | /// @name Registering/Unregistering textFieldView 69 | ///---------------------------------------------- 70 | 71 | /** 72 | Should pass UITextField/UITextView instance. Assign textFieldView delegate to self, change it's returnKeyType. 73 | 74 | @param textFieldView UITextField/UITextView object to register. 75 | */ 76 | -(void)addTextFieldView:(nonnull UIView*)textFieldView; 77 | 78 | /** 79 | Should pass UITextField/UITextView instance. Restore it's textFieldView delegate and it's returnKeyType. 80 | 81 | @param textFieldView UITextField/UITextView object to unregister. 82 | */ 83 | -(void)removeTextFieldView:(nonnull UIView*)textFieldView; 84 | 85 | /** 86 | Add all the UITextField/UITextView responderView's. 87 | 88 | @param UIView object to register all it's responder subviews. 89 | */ 90 | -(void)addResponderFromView:(nonnull UIView*)view; 91 | 92 | /** 93 | Remove all the UITextField/UITextView responderView's. 94 | 95 | @param UIView object to unregister all it's responder subviews. 96 | */ 97 | -(void)removeResponderFromView:(nonnull UIView*)view; 98 | 99 | @end 100 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/IQTextView/IQTextView.m: -------------------------------------------------------------------------------- 1 | // 2 | // IQTextView.m 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "IQTextView.h" 25 | 26 | #import 27 | #import 28 | 29 | @interface IQTextView () 30 | 31 | -(void)refreshPlaceholder; 32 | 33 | @end 34 | 35 | @implementation IQTextView 36 | { 37 | UILabel *placeHolderLabel; 38 | } 39 | 40 | @synthesize placeholder = _placeholder; 41 | 42 | -(void)initialize 43 | { 44 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshPlaceholder) name:UITextViewTextDidChangeNotification object:self]; 45 | } 46 | 47 | -(void)dealloc 48 | { 49 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 50 | } 51 | 52 | - (instancetype)init 53 | { 54 | self = [super init]; 55 | if (self) { 56 | [self initialize]; 57 | } 58 | return self; 59 | } 60 | 61 | -(void)awakeFromNib 62 | { 63 | [super awakeFromNib]; 64 | [self initialize]; 65 | } 66 | 67 | -(void)refreshPlaceholder 68 | { 69 | if([[self text] length]) 70 | { 71 | [placeHolderLabel setAlpha:0]; 72 | } 73 | else 74 | { 75 | [placeHolderLabel setAlpha:1]; 76 | } 77 | 78 | [self setNeedsLayout]; 79 | [self layoutIfNeeded]; 80 | } 81 | 82 | - (void)setText:(NSString *)text 83 | { 84 | [super setText:text]; 85 | [self refreshPlaceholder]; 86 | } 87 | 88 | -(void)setFont:(UIFont *)font 89 | { 90 | [super setFont:font]; 91 | placeHolderLabel.font = self.font; 92 | 93 | [self setNeedsLayout]; 94 | [self layoutIfNeeded]; 95 | } 96 | 97 | -(void)layoutSubviews 98 | { 99 | [super layoutSubviews]; 100 | 101 | [placeHolderLabel sizeToFit]; 102 | placeHolderLabel.frame = CGRectMake(8, 8, CGRectGetWidth(self.frame)-16, CGRectGetHeight(placeHolderLabel.frame)); 103 | } 104 | 105 | -(void)setPlaceholder:(NSString *)placeholder 106 | { 107 | _placeholder = placeholder; 108 | 109 | if ( placeHolderLabel == nil ) 110 | { 111 | placeHolderLabel = [[UILabel alloc] init]; 112 | placeHolderLabel.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight); 113 | placeHolderLabel.lineBreakMode = NSLineBreakByWordWrapping; 114 | placeHolderLabel.numberOfLines = 0; 115 | placeHolderLabel.font = self.font; 116 | placeHolderLabel.backgroundColor = [UIColor clearColor]; 117 | placeHolderLabel.textColor = [UIColor colorWithWhite:0.7 alpha:1.0]; 118 | placeHolderLabel.alpha = 0; 119 | [self addSubview:placeHolderLabel]; 120 | } 121 | 122 | placeHolderLabel.text = self.placeholder; 123 | [self refreshPlaceholder]; 124 | } 125 | 126 | //When any text changes on textField, the delegate getter is called. At this time we refresh the textView's placeholder 127 | -(id)delegate 128 | { 129 | [self refreshPlaceholder]; 130 | return [super delegate]; 131 | } 132 | 133 | @end 134 | -------------------------------------------------------------------------------- /LocaShopCar/GoodsController.m: -------------------------------------------------------------------------------- 1 | // 2 | // GoodsController.m 3 | // LocaShopCar 4 | // 5 | // Created by xhl on 16/7/17. 6 | // Copyright © 2016年 xhl. All rights reserved. 7 | // 8 | 9 | #import "GoodsController.h" 10 | #import "MJExtension.h" 11 | #import "ShopCarModel.h" 12 | #import "ShopCarGruopModel.h" 13 | #import "GoodsCell.h" 14 | #import "LTDBShopCar.h" 15 | 16 | @interface GoodsController () 17 | 18 | @property (strong,nonatomic) NSMutableArray * cellDatas; 19 | 20 | @end 21 | 22 | @implementation GoodsController 23 | 24 | - (void)viewDidLoad { 25 | [super viewDidLoad]; 26 | // Do any additional setup after loading the view. 27 | } 28 | 29 | - (void)didReceiveMemoryWarning { 30 | [super didReceiveMemoryWarning]; 31 | // Dispose of any resources that can be recreated. 32 | } 33 | 34 | - (NSMutableArray *)cellDatas 35 | { 36 | if (!_cellDatas) { 37 | _cellDatas = [NSMutableArray array]; 38 | 39 | //模型嵌套 40 | [ShopCarGruopModel mj_setupObjectClassInArray:^NSDictionary *{ 41 | return @{ 42 | @"goods" : @"ShopCarModel", 43 | // @"statuses" : [Status class] 44 | }; 45 | }]; 46 | 47 | NSString * path = [[NSBundle mainBundle] pathForResource:@"GuoupGood.plist" ofType:nil]; 48 | 49 | [_cellDatas addObjectsFromArray:[ShopCarGruopModel mj_objectArrayWithFile:path]]; 50 | } 51 | 52 | return _cellDatas; 53 | } 54 | 55 | - (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 56 | { 57 | ShopCarGruopModel *groupModel = self.cellDatas[section]; 58 | UILabel * headerLbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 30)]; 59 | headerLbl.backgroundColor = [UIColor whiteColor]; 60 | headerLbl.textColor = [UIColor blueColor]; 61 | headerLbl.text = [NSString stringWithFormat:@" %@",groupModel.shopName]; 62 | return headerLbl; 63 | } 64 | 65 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 66 | { 67 | return 30; 68 | } 69 | 70 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 71 | { 72 | return self.cellDatas.count; 73 | } 74 | 75 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 76 | { 77 | return 90; 78 | } 79 | 80 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 81 | { 82 | ShopCarGruopModel *groupModel = self.cellDatas[section]; 83 | return groupModel.goods.count; 84 | } 85 | 86 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 87 | { 88 | ShopCarGruopModel *groupModel = self.cellDatas[indexPath.section]; 89 | GoodsCell * cell = [tableView dequeueReusableCellWithIdentifier:@"GoodsCell"]; 90 | [cell cellDataWithModel:indexPath andGroupModel:groupModel]; 91 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 92 | __weak typeof(self) weakSelf = self; 93 | cell.btBlock = ^(){ 94 | [weakSelf dealWithResult:indexPath]; 95 | }; 96 | return cell; 97 | } 98 | 99 | //添加到数据库 100 | - (void)dealWithResult:(NSIndexPath *)indexPath 101 | { 102 | NSLog(@"点击了第%@行购买",@(indexPath.row)); 103 | UIAlertController * alertVc = [UIAlertController alertControllerWithTitle:@"提示" message:@"是否购买" preferredStyle:UIAlertControllerStyleAlert]; 104 | UIAlertAction * leftAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { 105 | 106 | }]; 107 | UIAlertAction * rightAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 108 | ShopCarGruopModel *groupModel = self.cellDatas[indexPath.section]; 109 | [[LTDBShopCar shareInstance] insertUser:groupModel.goods[indexPath.row]]; 110 | 111 | if (self.callBack) { 112 | self.callBack(groupModel.goods[indexPath.row]); 113 | } 114 | 115 | }]; 116 | [alertVc addAction:leftAction]; 117 | [alertVc addAction:rightAction]; 118 | [self presentViewController:alertVc animated:YES completion:nil]; 119 | } 120 | 121 | @end 122 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/IQToolbar/IQTitleBarButtonItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // IQTitleBarButtonItem.m 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "IQTitleBarButtonItem.h" 25 | #import "IQKeyboardManagerConstants.h" 26 | #import "IQKeyboardManagerConstantsInternal.h" 27 | #import 28 | #import 29 | 30 | @implementation IQTitleBarButtonItem 31 | { 32 | UIView *_titleView; 33 | UIButton *_titleButton; 34 | } 35 | @synthesize font = _font; 36 | 37 | 38 | -(nonnull instancetype)initWithTitle:(nullable NSString *)title 39 | { 40 | self = [super init]; 41 | if (self) 42 | { 43 | _titleView = [[UIView alloc] init]; 44 | _titleView.backgroundColor = [UIColor clearColor]; 45 | _titleView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; 46 | 47 | _titleButton = [UIButton buttonWithType:UIButtonTypeSystem]; 48 | _titleButton.enabled = NO; 49 | _titleButton.titleLabel.numberOfLines = 3; 50 | [_titleButton setTitleColor:[UIColor colorWithRed:0.0 green:0.5 blue:1.0 alpha:1.0] forState:UIControlStateNormal]; 51 | [_titleButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateDisabled]; 52 | [_titleButton setBackgroundColor:[UIColor clearColor]]; 53 | [_titleButton.titleLabel setTextAlignment:NSTextAlignmentCenter]; 54 | _titleButton.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; 55 | [self setTitle:title]; 56 | [self setFont:[UIFont systemFontOfSize:13.0]]; 57 | [_titleView addSubview:_titleButton]; 58 | self.customView = _titleView; 59 | } 60 | return self; 61 | } 62 | 63 | -(void)setFont:(UIFont *)font 64 | { 65 | _font = font; 66 | 67 | if (font) 68 | { 69 | _titleButton.titleLabel.font = font; 70 | } 71 | else 72 | { 73 | _titleButton.titleLabel.font = [UIFont systemFontOfSize:13]; 74 | } 75 | } 76 | 77 | -(void)setTitle:(NSString *)title 78 | { 79 | [super setTitle:title]; 80 | [_titleButton setTitle:title forState:UIControlStateNormal]; 81 | } 82 | 83 | -(void)setSelectableTextColor:(UIColor*)selectableTextColor 84 | { 85 | _selectableTextColor = selectableTextColor; 86 | [_titleButton setTitleColor:_selectableTextColor forState:UIControlStateNormal]; 87 | } 88 | 89 | -(void)setTitleTarget:(nullable id)target action:(nullable SEL)action 90 | { 91 | NSInvocation *invocation = nil; 92 | 93 | if (target && action) 94 | { 95 | invocation = [NSInvocation invocationWithMethodSignature:[target methodSignatureForSelector:action]]; 96 | invocation.target = target; 97 | invocation.selector = action; 98 | } 99 | 100 | self.titleInvocation = invocation; 101 | } 102 | 103 | -(void)setTitleInvocation:(NSInvocation*)invocation 104 | { 105 | _titleInvocation = invocation; 106 | 107 | if (_titleInvocation.target == nil || _titleInvocation.selector == NULL) 108 | { 109 | self.enabled = NO; 110 | _titleButton.enabled = NO; 111 | [_titleButton removeTarget:nil action:NULL forControlEvents:UIControlEventTouchUpInside]; 112 | } 113 | else 114 | { 115 | self.enabled = YES; 116 | _titleButton.enabled = YES; 117 | [_titleButton addTarget:_titleInvocation.target action:_titleInvocation.selector forControlEvents:UIControlEventTouchUpInside]; 118 | } 119 | } 120 | 121 | @end 122 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/Categories/IQUIView+Hierarchy.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Hierarchy.h 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import 25 | #import "IQKeyboardManagerConstants.h" 26 | 27 | @class UICollectionView, UIScrollView, UITableView, NSArray; 28 | 29 | /** 30 | UIView hierarchy category. 31 | */ 32 | @interface UIView (IQ_UIView_Hierarchy) 33 | 34 | ///------------------------------ 35 | /// @name canBecomeFirstResponder 36 | ///------------------------------ 37 | 38 | /** 39 | Returns YES if IQKeyboardManager asking for `canBecomeFirstResponder. Useful when doing custom work in `textFieldShouldBeginEditing:` delegate. 40 | */ 41 | @property (nonatomic, readonly) BOOL isAskingCanBecomeFirstResponder; 42 | 43 | ///---------------------- 44 | /// @name viewControllers 45 | ///---------------------- 46 | 47 | /** 48 | Returns the UIViewController object that manages the receiver. 49 | */ 50 | @property (nullable, nonatomic, readonly, strong) UIViewController *viewController; 51 | 52 | /** 53 | Returns the topMost UIViewController object in hierarchy. 54 | */ 55 | @property (nullable, nonatomic, readonly, strong) UIViewController *topMostController; 56 | 57 | ///----------------------------------- 58 | /// @name Superviews/Subviews/Siglings 59 | ///----------------------------------- 60 | 61 | /** 62 | Returns the superView of provided class type. 63 | */ 64 | -(nullable UIView*)superviewOfClassType:(nonnull Class)classType; 65 | 66 | /** 67 | Returns all siblings of the receiver which canBecomeFirstResponder. 68 | */ 69 | @property (nonnull, nonatomic, readonly, copy) NSArray *responderSiblings; 70 | 71 | /** 72 | Returns all deep subViews of the receiver which canBecomeFirstResponder. 73 | */ 74 | @property (nonnull, nonatomic, readonly, copy) NSArray *deepResponderViews; 75 | 76 | ///------------------------- 77 | /// @name Special TextFields 78 | ///------------------------- 79 | 80 | /** 81 | Returns YES if the receiver object is UISearchBarTextField, otherwise return NO. 82 | */ 83 | @property (nonatomic, getter=isSearchBarTextField, readonly) BOOL searchBarTextField; 84 | 85 | /** 86 | Returns YES if the receiver object is UIAlertSheetTextField, otherwise return NO. 87 | */ 88 | @property (nonatomic, getter=isAlertViewTextField, readonly) BOOL alertViewTextField; 89 | 90 | ///---------------- 91 | /// @name Transform 92 | ///---------------- 93 | 94 | /** 95 | Returns current view transform with respect to the 'toView'. 96 | */ 97 | -(CGAffineTransform)convertTransformToView:(nullable UIView*)toView; 98 | 99 | ///----------------- 100 | /// @name Hierarchy 101 | ///----------------- 102 | 103 | /** 104 | Returns a string that represent the information about it's subview's hierarchy. You can use this method to debug the subview's positions. 105 | */ 106 | @property (nonnull, nonatomic, readonly, copy) NSString *subHierarchy; 107 | 108 | /** 109 | Returns an string that represent the information about it's upper hierarchy. You can use this method to debug the superview's positions. 110 | */ 111 | @property (nonnull, nonatomic, readonly, copy) NSString *superHierarchy; 112 | 113 | /** 114 | Returns an string that represent the information about it's frame positions. You can use this method to debug self positions. 115 | */ 116 | @property (nonnull, nonatomic, readonly, copy) NSString *debugHierarchy; 117 | 118 | @end 119 | 120 | 121 | /** 122 | NSObject category to used for logging purposes 123 | */ 124 | @interface NSObject (IQ_Logging) 125 | 126 | /** 127 | Short description for logging purpose. 128 | */ 129 | @property (nonnull, nonatomic, readonly, copy) NSString *_IQDescription; 130 | 131 | @end 132 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/IQToolbar/IQBarButtonItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // IQBarButtonItem.m 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "IQBarButtonItem.h" 25 | #import "IQKeyboardManagerConstantsInternal.h" 26 | 27 | @implementation IQBarButtonItem 28 | 29 | +(void)load 30 | { 31 | //Tint color 32 | [[self appearance] setTintColor:nil]; 33 | 34 | //Title 35 | [[self appearance] setTitlePositionAdjustment:UIOffsetZero forBarMetrics:UIBarMetricsDefault]; 36 | [[self appearance] setTitleTextAttributes:nil forState:UIControlStateNormal]; 37 | [[self appearance] setTitleTextAttributes:nil forState:UIControlStateHighlighted]; 38 | [[self appearance] setTitleTextAttributes:nil forState:UIControlStateDisabled]; 39 | [[self appearance] setTitleTextAttributes:nil forState:UIControlStateSelected]; 40 | [[self appearance] setTitleTextAttributes:nil forState:UIControlStateApplication]; 41 | [[self appearance] setTitleTextAttributes:nil forState:UIControlStateReserved]; 42 | 43 | //Background Image 44 | [[self appearance] setBackgroundImage:nil forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 45 | [[self appearance] setBackgroundImage:nil forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault]; 46 | [[self appearance] setBackgroundImage:nil forState:UIControlStateDisabled barMetrics:UIBarMetricsDefault]; 47 | [[self appearance] setBackgroundImage:nil forState:UIControlStateSelected barMetrics:UIBarMetricsDefault]; 48 | [[self appearance] setBackgroundImage:nil forState:UIControlStateApplication barMetrics:UIBarMetricsDefault]; 49 | [[self appearance] setBackgroundImage:nil forState:UIControlStateReserved barMetrics:UIBarMetricsDefault]; 50 | 51 | [[self appearance] setBackgroundImage:nil forState:UIControlStateNormal style:UIBarButtonItemStyleDone barMetrics:UIBarMetricsDefault]; 52 | [[self appearance] setBackgroundImage:nil forState:UIControlStateHighlighted style:UIBarButtonItemStyleDone barMetrics:UIBarMetricsDefault]; 53 | [[self appearance] setBackgroundImage:nil forState:UIControlStateDisabled style:UIBarButtonItemStyleDone barMetrics:UIBarMetricsDefault]; 54 | [[self appearance] setBackgroundImage:nil forState:UIControlStateSelected style:UIBarButtonItemStyleDone barMetrics:UIBarMetricsDefault]; 55 | [[self appearance] setBackgroundImage:nil forState:UIControlStateApplication style:UIBarButtonItemStyleDone barMetrics:UIBarMetricsDefault]; 56 | [[self appearance] setBackgroundImage:nil forState:UIControlStateReserved style:UIBarButtonItemStyleDone barMetrics:UIBarMetricsDefault]; 57 | 58 | [[self appearance] setBackgroundImage:nil forState:UIControlStateNormal style:UIBarButtonItemStylePlain barMetrics:UIBarMetricsDefault]; 59 | [[self appearance] setBackgroundImage:nil forState:UIControlStateHighlighted style:UIBarButtonItemStylePlain barMetrics:UIBarMetricsDefault]; 60 | [[self appearance] setBackgroundImage:nil forState:UIControlStateDisabled style:UIBarButtonItemStylePlain barMetrics:UIBarMetricsDefault]; 61 | [[self appearance] setBackgroundImage:nil forState:UIControlStateSelected style:UIBarButtonItemStylePlain barMetrics:UIBarMetricsDefault]; 62 | [[self appearance] setBackgroundImage:nil forState:UIControlStateApplication style:UIBarButtonItemStylePlain barMetrics:UIBarMetricsDefault]; 63 | [[self appearance] setBackgroundImage:nil forState:UIControlStateReserved style:UIBarButtonItemStylePlain barMetrics:UIBarMetricsDefault]; 64 | 65 | [[self appearance] setBackgroundVerticalPositionAdjustment:0 forBarMetrics:UIBarMetricsDefault]; 66 | 67 | //Back Button 68 | [[self appearance] setBackButtonBackgroundImage:nil forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 69 | [[self appearance] setBackButtonBackgroundImage:nil forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault]; 70 | [[self appearance] setBackButtonBackgroundImage:nil forState:UIControlStateDisabled barMetrics:UIBarMetricsDefault]; 71 | [[self appearance] setBackButtonBackgroundImage:nil forState:UIControlStateSelected barMetrics:UIBarMetricsDefault]; 72 | [[self appearance] setBackButtonBackgroundImage:nil forState:UIControlStateApplication barMetrics:UIBarMetricsDefault]; 73 | [[self appearance] setBackButtonBackgroundImage:nil forState:UIControlStateReserved barMetrics:UIBarMetricsDefault]; 74 | 75 | [[self appearance] setBackButtonTitlePositionAdjustment:UIOffsetZero forBarMetrics:UIBarMetricsDefault]; 76 | [[self appearance] setBackButtonBackgroundVerticalPositionAdjustment:0 forBarMetrics:UIBarMetricsDefault]; 77 | } 78 | 79 | @end 80 | -------------------------------------------------------------------------------- /LocaShopCar/GoodsCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // GoodsCell.m 3 | // LocaShopCar 4 | // 5 | // Created by xhl on 16/7/17. 6 | // Copyright © 2016年 xhl. All rights reserved. 7 | // 8 | 9 | #import "GoodsCell.h" 10 | #import "ShopCarModel.h" 11 | #import "LTDBShopCar.h" 12 | #import "ShopCarGruopModel.h" 13 | 14 | @interface GoodsCell () 15 | @property (weak, nonatomic) IBOutlet UILabel *title; 16 | @property (weak, nonatomic) IBOutlet UITextField *textField; 17 | @property (strong,nonatomic) ShopCarModel *carModel; 18 | @property (strong,nonatomic) ShopCarGruopModel *groupModel; 19 | @property (weak, nonatomic) IBOutlet UILabel *price; 20 | @property (weak, nonatomic) IBOutlet UIButton *addBt; 21 | @property (weak, nonatomic) IBOutlet UILabel *allPrice; 22 | @property (weak, nonatomic) IBOutlet UIButton *reduceBt; 23 | @property (weak, nonatomic) IBOutlet UIButton *buyBt; 24 | @property (weak, nonatomic) IBOutlet UIButton *selectButton; 25 | 26 | @end 27 | 28 | @implementation GoodsCell 29 | 30 | - (void)awakeFromNib { 31 | 32 | 33 | } 34 | 35 | //重写set方法 36 | - (void)setCarModel:(ShopCarModel *)carModel 37 | { 38 | //在每次设置观察者之前先提前移除,防止之前的没移除 39 | [_carModel removeObserver:self forKeyPath:@"goodsSelectCount"]; 40 | _carModel = carModel; 41 | [_carModel addObserver:self forKeyPath:@"goodsSelectCount" options:NSKeyValueObservingOptionNew context:NULL]; 42 | } 43 | 44 | - (void)dealloc 45 | { 46 | [self.carModel removeObserver:self forKeyPath:@"goodsSelectCount"]; 47 | } 48 | 49 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 50 | { 51 | 52 | int newCount = [change[@"new"] intValue]; 53 | 54 | _textField.text = [NSString stringWithFormat:@"%d",newCount]; 55 | 56 | [self setTing:newCount andIsAddOrReduce:YES]; 57 | 58 | if (self.callBlock) { 59 | self.callBlock(); 60 | } 61 | 62 | } 63 | 64 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 65 | [super setSelected:selected animated:animated]; 66 | 67 | // Configure the view for the selected state 68 | } 69 | 70 | - (void) cellDataWithModel:(NSIndexPath*)indexPath andGroupModel:(ShopCarGruopModel *)model 71 | { 72 | self.groupModel = model; 73 | self.carModel = self.groupModel.goods[indexPath.row]; 74 | self.price.text = [NSString stringWithFormat:@"单价:%.2f",self.carModel.price]; 75 | self.title.text = self.carModel.title; 76 | self.textField.text = [NSString stringWithFormat:@"%d",self.carModel.goodsSelectCount]; 77 | 78 | [self setTing:self.carModel.goodsSelectCount andIsAddOrReduce:NO]; 79 | 80 | UIImage * selectImg = self.carModel.isSelect ? [UIImage imageNamed:@"tm_mcart_checked"] : [UIImage imageNamed:@"tm_mcart_unchecked"]; 81 | [self.selectButton setImage:selectImg forState:UIControlStateNormal]; 82 | 83 | } 84 | 85 | - (void)setTing:(NSInteger)count andIsAddOrReduce:(BOOL)isAddOrReduce 86 | { 87 | //在商品列表中,如果没有商品数量是0那么取消减少与添加到购物车的交互。 88 | if (self.carModel.goodsSelectCount <=0) { 89 | self.reduceBt.enabled = NO; 90 | self.buyBt.enabled = NO; 91 | 92 | }else{ 93 | self.reduceBt.enabled = YES; 94 | self.buyBt.enabled = YES; 95 | 96 | if (isAddOrReduce) { 97 | //判断一下如果是在购物车中,需要更新数据库信息 98 | if (self.cellType == ShopCarCellType) { 99 | [[LTDBShopCar shareInstance] updateUser:self.carModel]; 100 | } 101 | } 102 | 103 | } 104 | 105 | //判断一下如果是在购物车中 106 | if (self.cellType == ShopCarCellType) { 107 | //小于等于1 静止减少 108 | if (self.carModel.goodsSelectCount <=1) { 109 | self.reduceBt.enabled = NO; 110 | }else{ 111 | self.reduceBt.enabled = YES; 112 | } 113 | 114 | } 115 | 116 | double allPrice = count * self.carModel.price; 117 | self.allPrice.text = [NSString stringWithFormat:@"总价:%.2f",allPrice]; 118 | 119 | } 120 | 121 | /** 122 | * 选中 123 | * 124 | * @param sender button 125 | */ 126 | - (IBAction)selectButton:(id)sender { 127 | 128 | self.carModel.select = !self.carModel.select; 129 | [self.groupModel.goods enumerateObjectsUsingBlock:^(ShopCarModel * obj, NSUInteger idx, BOOL * _Nonnull stop) { 130 | if (obj.select == NO) {//如果为当前有商品未被选中,跳出循环 131 | self.groupModel.select = NO; 132 | *stop = YES; 133 | }else if (idx == (self.groupModel.goods.count -1 )){ 134 | self.groupModel.select = YES; 135 | } 136 | }]; 137 | 138 | if (self.callBlock) { 139 | self.callBlock(); 140 | } 141 | } 142 | 143 | /** 144 | * 购买 145 | * 146 | * @param sender button 147 | */ 148 | - (IBAction)buyGood:(id)sender { 149 | if (self.btBlock) { 150 | self.btBlock(); 151 | } 152 | } 153 | 154 | /** 155 | * 增加 156 | * 157 | * @param sender button 158 | */ 159 | - (IBAction)add:(UIButton *)sender { 160 | 161 | self.carModel.goodsSelectCount ++; 162 | } 163 | 164 | /** 165 | * 减少 166 | * 167 | * @param sender button 168 | */ 169 | - (IBAction)reduce:(UIButton *)sender { 170 | 171 | if (self.carModel.goodsSelectCount>0) { 172 | self.carModel.goodsSelectCount --; 173 | } 174 | 175 | } 176 | 177 | /** 178 | * 删除 179 | * 180 | * @param sender button 181 | */ 182 | - (IBAction)deleteBt:(UIButton *)sender { 183 | if (self.deleteBlock) { 184 | self.deleteBlock(); 185 | } 186 | } 187 | 188 | - (void)textFieldDidEndEditing:(UITextField *)textField 189 | { 190 | NSLog(@"%@",textField.text); 191 | 192 | self.textField.text = [NSString stringWithFormat:@"%@",textField.text]; 193 | self.carModel.goodsSelectCount = [textField.text intValue]; 194 | NSLog(@"%@",textField.text); 195 | } 196 | 197 | @end 198 | -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/NSObject+MJClass.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+MJClass.m 3 | // MJExtensionExample 4 | // 5 | // Created by MJ Lee on 15/8/11. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "NSObject+MJClass.h" 10 | #import "NSObject+MJCoding.h" 11 | #import "NSObject+MJKeyValue.h" 12 | #import "MJFoundation.h" 13 | #import 14 | 15 | static const char MJAllowedPropertyNamesKey = '\0'; 16 | static const char MJIgnoredPropertyNamesKey = '\0'; 17 | static const char MJAllowedCodingPropertyNamesKey = '\0'; 18 | static const char MJIgnoredCodingPropertyNamesKey = '\0'; 19 | 20 | static NSMutableDictionary *allowedPropertyNamesDict_; 21 | static NSMutableDictionary *ignoredPropertyNamesDict_; 22 | static NSMutableDictionary *allowedCodingPropertyNamesDict_; 23 | static NSMutableDictionary *ignoredCodingPropertyNamesDict_; 24 | 25 | @implementation NSObject (MJClass) 26 | 27 | + (void)load 28 | { 29 | allowedPropertyNamesDict_ = [NSMutableDictionary dictionary]; 30 | ignoredPropertyNamesDict_ = [NSMutableDictionary dictionary]; 31 | allowedCodingPropertyNamesDict_ = [NSMutableDictionary dictionary]; 32 | ignoredCodingPropertyNamesDict_ = [NSMutableDictionary dictionary]; 33 | } 34 | 35 | + (NSMutableDictionary *)dictForKey:(const void *)key 36 | { 37 | if (key == &MJAllowedPropertyNamesKey) return allowedPropertyNamesDict_; 38 | if (key == &MJIgnoredPropertyNamesKey) return ignoredPropertyNamesDict_; 39 | if (key == &MJAllowedCodingPropertyNamesKey) return allowedCodingPropertyNamesDict_; 40 | if (key == &MJIgnoredCodingPropertyNamesKey) return ignoredCodingPropertyNamesDict_; 41 | return nil; 42 | } 43 | 44 | + (void)mj_enumerateClasses:(MJClassesEnumeration)enumeration 45 | { 46 | // 1.没有block就直接返回 47 | if (enumeration == nil) return; 48 | 49 | // 2.停止遍历的标记 50 | BOOL stop = NO; 51 | 52 | // 3.当前正在遍历的类 53 | Class c = self; 54 | 55 | // 4.开始遍历每一个类 56 | while (c && !stop) { 57 | // 4.1.执行操作 58 | enumeration(c, &stop); 59 | 60 | // 4.2.获得父类 61 | c = class_getSuperclass(c); 62 | 63 | if ([MJFoundation isClassFromFoundation:c]) break; 64 | } 65 | } 66 | 67 | + (void)mj_enumerateAllClasses:(MJClassesEnumeration)enumeration 68 | { 69 | // 1.没有block就直接返回 70 | if (enumeration == nil) return; 71 | 72 | // 2.停止遍历的标记 73 | BOOL stop = NO; 74 | 75 | // 3.当前正在遍历的类 76 | Class c = self; 77 | 78 | // 4.开始遍历每一个类 79 | while (c && !stop) { 80 | // 4.1.执行操作 81 | enumeration(c, &stop); 82 | 83 | // 4.2.获得父类 84 | c = class_getSuperclass(c); 85 | } 86 | } 87 | 88 | #pragma mark - 属性黑名单配置 89 | + (void)mj_setupIgnoredPropertyNames:(MJIgnoredPropertyNames)ignoredPropertyNames 90 | { 91 | [self mj_setupBlockReturnValue:ignoredPropertyNames key:&MJIgnoredPropertyNamesKey]; 92 | } 93 | 94 | + (NSMutableArray *)mj_totalIgnoredPropertyNames 95 | { 96 | return [self mj_totalObjectsWithSelector:@selector(mj_ignoredPropertyNames) key:&MJIgnoredPropertyNamesKey]; 97 | } 98 | 99 | #pragma mark - 归档属性黑名单配置 100 | + (void)mj_setupIgnoredCodingPropertyNames:(MJIgnoredCodingPropertyNames)ignoredCodingPropertyNames 101 | { 102 | [self mj_setupBlockReturnValue:ignoredCodingPropertyNames key:&MJIgnoredCodingPropertyNamesKey]; 103 | } 104 | 105 | + (NSMutableArray *)mj_totalIgnoredCodingPropertyNames 106 | { 107 | return [self mj_totalObjectsWithSelector:@selector(mj_ignoredCodingPropertyNames) key:&MJIgnoredCodingPropertyNamesKey]; 108 | } 109 | 110 | #pragma mark - 属性白名单配置 111 | + (void)mj_setupAllowedPropertyNames:(MJAllowedPropertyNames)allowedPropertyNames; 112 | { 113 | [self mj_setupBlockReturnValue:allowedPropertyNames key:&MJAllowedPropertyNamesKey]; 114 | } 115 | 116 | + (NSMutableArray *)mj_totalAllowedPropertyNames 117 | { 118 | return [self mj_totalObjectsWithSelector:@selector(mj_allowedPropertyNames) key:&MJAllowedPropertyNamesKey]; 119 | } 120 | 121 | #pragma mark - 归档属性白名单配置 122 | + (void)mj_setupAllowedCodingPropertyNames:(MJAllowedCodingPropertyNames)allowedCodingPropertyNames 123 | { 124 | [self mj_setupBlockReturnValue:allowedCodingPropertyNames key:&MJAllowedCodingPropertyNamesKey]; 125 | } 126 | 127 | + (NSMutableArray *)mj_totalAllowedCodingPropertyNames 128 | { 129 | return [self mj_totalObjectsWithSelector:@selector(mj_allowedCodingPropertyNames) key:&MJAllowedCodingPropertyNamesKey]; 130 | } 131 | #pragma mark - block和方法处理:存储block的返回值 132 | + (void)mj_setupBlockReturnValue:(id (^)())block key:(const char *)key 133 | { 134 | if (block) { 135 | objc_setAssociatedObject(self, key, block(), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 136 | } else { 137 | objc_setAssociatedObject(self, key, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 138 | } 139 | 140 | // 清空数据 141 | [[self dictForKey:key] removeAllObjects]; 142 | } 143 | 144 | + (NSMutableArray *)mj_totalObjectsWithSelector:(SEL)selector key:(const char *)key 145 | { 146 | NSMutableArray *array = [self dictForKey:key][NSStringFromClass(self)]; 147 | if (array) return array; 148 | 149 | // 创建、存储 150 | [self dictForKey:key][NSStringFromClass(self)] = array = [NSMutableArray array]; 151 | 152 | if ([self respondsToSelector:selector]) { 153 | #pragma clang diagnostic push 154 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 155 | NSArray *subArray = [self performSelector:selector]; 156 | #pragma clang diagnostic pop 157 | if (subArray) { 158 | [array addObjectsFromArray:subArray]; 159 | } 160 | } 161 | 162 | [self mj_enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) { 163 | NSArray *subArray = objc_getAssociatedObject(c, key); 164 | [array addObjectsFromArray:subArray]; 165 | }]; 166 | return array; 167 | } 168 | @end 169 | -------------------------------------------------------------------------------- /LocaShopCar/LTDBShopCar.m: -------------------------------------------------------------------------------- 1 | // 2 | // LTDBShopCar.m 3 | // LocaShopCar 4 | // 5 | // Created by xhl on 16/7/17. 6 | // Copyright © 2016年 xhl. All rights reserved. 7 | // 8 | 9 | #import "LTDBShopCar.h" 10 | #import "MJExtension.h" 11 | 12 | 13 | @implementation LTDBShopCar 14 | 15 | //创建单例 16 | +(LTDBShopCar*)shareInstance{ 17 | static dispatch_once_t onceToken; 18 | static LTDBShopCar *sharedInstance=nil; 19 | dispatch_once(&onceToken, ^{ 20 | sharedInstance=[[LTDBShopCar alloc]init]; 21 | }); 22 | [sharedInstance createUser]; 23 | return sharedInstance; 24 | } 25 | 26 | //创建shopCar && shopTab表 27 | -(void)createUser 28 | { 29 | self.db=[LTDBHelper shareDatabase].db; 30 | if(![self.db tableExists:@"shopCar"]) 31 | { 32 | [self.db executeUpdate:@"CREATE TABLE shopCar (goodsId TEXT PRIMARY KEY NOT NULL,title TEXT,price double,allPrice double,goodsSelectCount integer,isSelect integer,shopId TEXT)"]; 33 | NSLog(@"create shopCar1 success"); 34 | } 35 | 36 | if(![self.db tableExists:@"shopTab"]) 37 | { 38 | [self.db executeUpdate:@"CREATE TABLE shopTab (shopId TEXT PRIMARY KEY NOT NULL,shopName TEXT)"]; 39 | NSLog(@"create shopTab success"); 40 | [self settingShopTab]; 41 | 42 | } 43 | } 44 | 45 | /** 46 | * 设置商家表 47 | */ 48 | - (void)settingShopTab 49 | { 50 | 51 | NSString * path = [[NSBundle mainBundle] pathForResource:@"GuoupGood.plist" ofType:nil]; 52 | 53 | NSArray * datas = [ShopCarGruopModel mj_objectArrayWithFile:path]; 54 | 55 | for (ShopCarGruopModel * model in datas) { 56 | BOOL shopZero= [self.db executeUpdate:@"INSERT INTO shopTab (shopId,shopName) VALUES(?,?)",model.shopId,model.shopName]; 57 | if(shopZero==YES) 58 | NSLog(@"inser shopCar success"); 59 | } 60 | } 61 | 62 | //增 63 | -(void)insertUser:(ShopCarModel *)shopCarModel 64 | { 65 | 66 | FMResultSet *rs = [self.db executeQuery:@"select * from shopCar where goodsId = ?",shopCarModel.goodsId]; 67 | 68 | if ([rs next]) {//如果存在ID ,更新 69 | int count = [rs intForColumn:@"goodsSelectCount"]; 70 | ShopCarModel * model = [[ShopCarModel alloc] init]; 71 | model.goodsSelectCount = shopCarModel.goodsSelectCount + count; 72 | model.goodsId = shopCarModel.goodsId; 73 | [self updateUser:model]; 74 | }else{//根据ID创建一条新的数据 75 | [self insertShopCar:shopCarModel]; 76 | } 77 | 78 | } 79 | 80 | - (void)insertShopCar:(ShopCarModel *)shopCarModel 81 | { 82 | BOOL b= [self.db executeUpdate:@"INSERT INTO shopCar (shopId,title,price,allPrice,goodsSelectCount,isSelect,goodsId) VALUES(?,?,?,?,?,?,?)",shopCarModel.shopId,shopCarModel.title,[NSString stringWithFormat:@"%.2f",shopCarModel.price],[NSString stringWithFormat:@"%.2f",shopCarModel.allPrice],[NSString stringWithFormat:@"%d",shopCarModel.goodsSelectCount],[NSString stringWithFormat:@"%d",shopCarModel.select],shopCarModel.goodsId]; 83 | if(b==YES) 84 | NSLog(@"inser shopCar success"); 85 | 86 | } 87 | 88 | //查询(拼接数据) 89 | -(NSArray *)getShopCarModel 90 | { 91 | NSMutableArray *array = [[NSMutableArray alloc] init]; 92 | 93 | 94 | FMResultSet *rsShop = [self.db executeQuery:@"select * from shopTab"]; 95 | 96 | while ([rsShop next]) { 97 | NSString *shopId_shop = [rsShop stringForColumn:@"shopId"]; 98 | ShopCarGruopModel *shopCarGroup=[[ShopCarGruopModel alloc] init]; 99 | NSMutableArray * shopArr = [NSMutableArray array]; 100 | shopCarGroup.shopId = [rsShop stringForColumn:@"shopId"]; 101 | shopCarGroup.shopName = [rsShop stringForColumn:@"shopName"]; 102 | 103 | FMResultSet *rsGoods = [self.db executeQuery:@"select * from shopCar"]; 104 | while ([rsGoods next]) { 105 | NSString *shopId = [rsGoods stringForColumn:@"shopId"]; 106 | 107 | if ([shopId_shop isEqualToString:shopId]) { 108 | ShopCarModel * shopCar = [[ShopCarModel alloc] init]; 109 | shopCar.title=[rsGoods stringForColumn:@"title"]; 110 | shopCar.shopId=[rsGoods stringForColumn:@"shopId"]; 111 | shopCar.goodsId=[rsGoods stringForColumn:@"goodsId"]; 112 | shopCar.price=[rsGoods doubleForColumn:@"price"]; 113 | shopCar.allPrice=[rsGoods doubleForColumn:@"allPrice"]; 114 | shopCar.goodsSelectCount=[rsGoods intForColumn:@"goodsSelectCount"]; 115 | shopCar.select=[rsGoods boolForColumn:@"isSelect"]; 116 | [shopArr addObject:shopCar]; 117 | } 118 | } 119 | shopCarGroup.goods = shopArr; 120 | 121 | if (shopArr.count >0) { 122 | [array addObject:shopCarGroup]; 123 | } 124 | 125 | 126 | } 127 | 128 | return array; 129 | } 130 | 131 | //更新 132 | -(void)updateUser:(ShopCarModel *)shopCarModel 133 | { 134 | 135 | FMResultSet *rs = [self.db executeQuery:@"select * from shopCar where goodsId = ?",shopCarModel.goodsId]; 136 | 137 | if ([rs next]) { 138 | BOOL operaResult = [self.db executeUpdate:@"UPDATE shopCar SET goodsSelectCount=? WHERE goodsId=?",[NSString stringWithFormat:@"%d",shopCarModel.goodsSelectCount],[NSString stringWithFormat:@"%@",shopCarModel.goodsId]]; 139 | if(operaResult==YES){ 140 | NSLog(@"update shopCar success"); 141 | } 142 | }else{ 143 | NSLog(@"数据库不存在此条数据%@",shopCarModel); 144 | } 145 | 146 | 147 | 148 | } 149 | 150 | //删除 151 | -(void)deleteShopCarModel:(ShopCarModel *)shopCarModel 152 | { 153 | if (![self.db tableExists:@"shopCar"]) 154 | { 155 | return; 156 | } 157 | BOOL operaResult = [self.db executeUpdate:@"DELETE FROM shopCar WHERE goodsId=?",shopCarModel.goodsId]; 158 | 159 | if (operaResult == NO) { 160 | NSLog(@"数据库不存在此条数据%@",shopCarModel); 161 | } 162 | } 163 | 164 | 165 | @end 166 | -------------------------------------------------------------------------------- /LocaShopCar/MJExtension/MJProperty.m: -------------------------------------------------------------------------------- 1 | // 2 | // MJProperty.m 3 | // MJExtensionExample 4 | // 5 | // Created by MJ Lee on 15/4/17. 6 | // Copyright (c) 2015年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "MJProperty.h" 10 | #import "MJFoundation.h" 11 | #import "MJExtensionConst.h" 12 | #import 13 | 14 | @interface MJProperty() 15 | @property (strong, nonatomic) NSMutableDictionary *propertyKeysDict; 16 | @property (strong, nonatomic) NSMutableDictionary *objectClassInArrayDict; 17 | @end 18 | 19 | @implementation MJProperty 20 | 21 | #pragma mark - 懒加载 22 | - (NSMutableDictionary *)propertyKeysDict 23 | { 24 | if (!_propertyKeysDict) { 25 | _propertyKeysDict = [NSMutableDictionary dictionary]; 26 | } 27 | return _propertyKeysDict; 28 | } 29 | 30 | - (NSMutableDictionary *)objectClassInArrayDict 31 | { 32 | if (!_objectClassInArrayDict) { 33 | _objectClassInArrayDict = [NSMutableDictionary dictionary]; 34 | } 35 | return _objectClassInArrayDict; 36 | } 37 | 38 | #pragma mark - 缓存 39 | + (instancetype)cachedPropertyWithProperty:(objc_property_t)property 40 | { 41 | MJProperty *propertyObj = objc_getAssociatedObject(self, property); 42 | if (propertyObj == nil) { 43 | propertyObj = [[self alloc] init]; 44 | propertyObj.property = property; 45 | objc_setAssociatedObject(self, property, propertyObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 46 | } 47 | return propertyObj; 48 | } 49 | 50 | #pragma mark - 公共方法 51 | - (void)setProperty:(objc_property_t)property 52 | { 53 | _property = property; 54 | 55 | MJExtensionAssertParamNotNil(property); 56 | 57 | // 1.属性名 58 | _name = @(property_getName(property)); 59 | 60 | // 2.成员类型 61 | NSString *attrs = @(property_getAttributes(property)); 62 | NSUInteger dotLoc = [attrs rangeOfString:@","].location; 63 | NSString *code = nil; 64 | NSUInteger loc = 1; 65 | if (dotLoc == NSNotFound) { // 没有, 66 | code = [attrs substringFromIndex:loc]; 67 | } else { 68 | code = [attrs substringWithRange:NSMakeRange(loc, dotLoc - loc)]; 69 | } 70 | _type = [MJPropertyType cachedTypeWithCode:code]; 71 | } 72 | 73 | /** 74 | * 获得成员变量的值 75 | */ 76 | - (id)valueForObject:(id)object 77 | { 78 | if (self.type.KVCDisabled) return [NSNull null]; 79 | return [object valueForKey:self.name]; 80 | } 81 | 82 | /** 83 | * 设置成员变量的值 84 | */ 85 | - (void)setValue:(id)value forObject:(id)object 86 | { 87 | if (self.type.KVCDisabled || value == nil) return; 88 | [object setValue:value forKey:self.name]; 89 | } 90 | 91 | /** 92 | * 通过字符串key创建对应的keys 93 | */ 94 | - (NSArray *)propertyKeysWithStringKey:(NSString *)stringKey 95 | { 96 | if (stringKey.length == 0) return nil; 97 | 98 | NSMutableArray *propertyKeys = [NSMutableArray array]; 99 | // 如果有多级映射 100 | NSArray *oldKeys = [stringKey componentsSeparatedByString:@"."]; 101 | 102 | for (NSString *oldKey in oldKeys) { 103 | NSUInteger start = [oldKey rangeOfString:@"["].location; 104 | if (start != NSNotFound) { // 有索引的key 105 | NSString *prefixKey = [oldKey substringToIndex:start]; 106 | NSString *indexKey = prefixKey; 107 | if (prefixKey.length) { 108 | MJPropertyKey *propertyKey = [[MJPropertyKey alloc] init]; 109 | propertyKey.name = prefixKey; 110 | [propertyKeys addObject:propertyKey]; 111 | 112 | indexKey = [oldKey stringByReplacingOccurrencesOfString:prefixKey withString:@""]; 113 | } 114 | 115 | /** 解析索引 **/ 116 | // 元素 117 | NSArray *cmps = [[indexKey stringByReplacingOccurrencesOfString:@"[" withString:@""] componentsSeparatedByString:@"]"]; 118 | for (NSInteger i = 0; i 28 | 29 | ///----------------------------------- 30 | /// @name IQAutoToolbarManageBehaviour 31 | ///----------------------------------- 32 | 33 | /** 34 | `IQAutoToolbarBySubviews` 35 | Creates Toolbar according to subview's hirarchy of Textfield's in view. 36 | 37 | `IQAutoToolbarByTag` 38 | Creates Toolbar according to tag property of TextField's. 39 | 40 | `IQAutoToolbarByPosition` 41 | Creates Toolbar according to the y,x position of textField in it's superview coordinate. 42 | */ 43 | typedef NS_ENUM(NSInteger, IQAutoToolbarManageBehaviour) { 44 | IQAutoToolbarBySubviews, 45 | IQAutoToolbarByTag, 46 | IQAutoToolbarByPosition, 47 | }; 48 | 49 | ///------------------- 50 | /// @name Localization 51 | ///------------------- 52 | 53 | #define IQLocalizedString(key, comment) [[NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"IQKeyboardManager" ofType:@"bundle"]] localizedStringForKey:(key) value:@"" table:@"IQKeyboardManager"] 54 | 55 | #endif 56 | 57 | /* 58 | 59 | /---------------------------------------------------------------------------------------------------\ 60 | \---------------------------------------------------------------------------------------------------/ 61 | | iOS NSNotification Mechanism | 62 | /---------------------------------------------------------------------------------------------------\ 63 | \---------------------------------------------------------------------------------------------------/ 64 | 65 | 66 | ------------------------------------------------------------ 67 | When UITextField become first responder 68 | ------------------------------------------------------------ 69 | - UITextFieldTextDidBeginEditingNotification (UITextField) 70 | - UIKeyboardWillShowNotification 71 | - UIKeyboardDidShowNotification 72 | 73 | ------------------------------------------------------------ 74 | When UITextView become first responder 75 | ------------------------------------------------------------ 76 | - UIKeyboardWillShowNotification 77 | - UITextViewTextDidBeginEditingNotification (UITextView) 78 | - UIKeyboardDidShowNotification 79 | 80 | ------------------------------------------------------------ 81 | When switching focus from UITextField to another UITextField 82 | ------------------------------------------------------------ 83 | - UITextFieldTextDidEndEditingNotification (UITextField1) 84 | - UITextFieldTextDidBeginEditingNotification (UITextField2) 85 | - UIKeyboardWillShowNotification 86 | - UIKeyboardDidShowNotification 87 | 88 | ------------------------------------------------------------ 89 | When switching focus from UITextView to another UITextView 90 | ------------------------------------------------------------ 91 | - UITextViewTextDidEndEditingNotification : (UITextView1) 92 | - UIKeyboardWillShowNotification 93 | - UITextViewTextDidBeginEditingNotification : (UITextView2) 94 | - UIKeyboardDidShowNotification 95 | 96 | ------------------------------------------------------------ 97 | When switching focus from UITextField to UITextView 98 | ------------------------------------------------------------ 99 | - UITextFieldTextDidEndEditingNotification (UITextField) 100 | - UIKeyboardWillShowNotification 101 | - UITextViewTextDidBeginEditingNotification (UITextView) 102 | - UIKeyboardDidShowNotification 103 | 104 | ------------------------------------------------------------ 105 | When switching focus from UITextView to UITextField 106 | ------------------------------------------------------------ 107 | - UITextViewTextDidEndEditingNotification (UITextView) 108 | - UITextFieldTextDidBeginEditingNotification (UITextField) 109 | - UIKeyboardWillShowNotification 110 | - UIKeyboardDidShowNotification 111 | 112 | ------------------------------------------------------------ 113 | When opening/closing UIKeyboard Predictive bar 114 | ------------------------------------------------------------ 115 | - UIKeyboardWillShowNotification 116 | - UIKeyboardDidShowNotification 117 | 118 | ------------------------------------------------------------ 119 | On orientation change 120 | ------------------------------------------------------------ 121 | - UIApplicationWillChangeStatusBarOrientationNotification 122 | - UIKeyboardWillHideNotification 123 | - UIKeyboardDidHideNotification 124 | - UIApplicationDidChangeStatusBarOrientationNotification 125 | - UIKeyboardWillShowNotification 126 | - UIKeyboardDidShowNotification 127 | - UIKeyboardWillShowNotification 128 | - UIKeyboardDidShowNotification 129 | 130 | */ 131 | -------------------------------------------------------------------------------- /LocaShopCar/fmdb/FMDatabasePool.h: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabasePool.h 3 | // fmdb 4 | // 5 | // Created by August Mueller on 6/22/11. 6 | // Copyright 2011 Flying Meat Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class FMDatabase; 12 | 13 | /** Pool of `` objects. 14 | 15 | ### See also 16 | 17 | - `` 18 | - `` 19 | 20 | @warning Before using `FMDatabasePool`, please consider using `` instead. 21 | 22 | If you really really really know what you're doing and `FMDatabasePool` is what 23 | you really really need (ie, you're using a read only database), OK you can use 24 | it. But just be careful not to deadlock! 25 | 26 | For an example on deadlocking, search for: 27 | `ONLY_USE_THE_POOL_IF_YOU_ARE_DOING_READS_OTHERWISE_YOULL_DEADLOCK_USE_FMDATABASEQUEUE_INSTEAD` 28 | in the main.m file. 29 | */ 30 | 31 | @interface FMDatabasePool : NSObject { 32 | NSString *_path; 33 | 34 | dispatch_queue_t _lockQueue; 35 | 36 | NSMutableArray *_databaseInPool; 37 | NSMutableArray *_databaseOutPool; 38 | 39 | __unsafe_unretained id _delegate; 40 | 41 | NSUInteger _maximumNumberOfDatabasesToCreate; 42 | int _openFlags; 43 | NSString *_vfsName; 44 | } 45 | 46 | /** Database path */ 47 | 48 | @property (atomic, retain) NSString *path; 49 | 50 | /** Delegate object */ 51 | 52 | @property (atomic, assign) id delegate; 53 | 54 | /** Maximum number of databases to create */ 55 | 56 | @property (atomic, assign) NSUInteger maximumNumberOfDatabasesToCreate; 57 | 58 | /** Open flags */ 59 | 60 | @property (atomic, readonly) int openFlags; 61 | 62 | /** Custom virtual file system name */ 63 | 64 | @property (atomic, copy) NSString *vfsName; 65 | 66 | 67 | ///--------------------- 68 | /// @name Initialization 69 | ///--------------------- 70 | 71 | /** Create pool using path. 72 | 73 | @param aPath The file path of the database. 74 | 75 | @return The `FMDatabasePool` object. `nil` on error. 76 | */ 77 | 78 | + (instancetype)databasePoolWithPath:(NSString*)aPath; 79 | 80 | /** Create pool using path and specified flags 81 | 82 | @param aPath The file path of the database. 83 | @param openFlags Flags passed to the openWithFlags method of the database 84 | 85 | @return The `FMDatabasePool` object. `nil` on error. 86 | */ 87 | 88 | + (instancetype)databasePoolWithPath:(NSString*)aPath flags:(int)openFlags; 89 | 90 | /** Create pool using path. 91 | 92 | @param aPath The file path of the database. 93 | 94 | @return The `FMDatabasePool` object. `nil` on error. 95 | */ 96 | 97 | - (instancetype)initWithPath:(NSString*)aPath; 98 | 99 | /** Create pool using path and specified flags. 100 | 101 | @param aPath The file path of the database. 102 | @param openFlags Flags passed to the openWithFlags method of the database 103 | 104 | @return The `FMDatabasePool` object. `nil` on error. 105 | */ 106 | 107 | - (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags; 108 | 109 | /** Create pool using path and specified flags. 110 | 111 | @param aPath The file path of the database. 112 | @param openFlags Flags passed to the openWithFlags method of the database 113 | @param vfsName The name of a custom virtual file system 114 | 115 | @return The `FMDatabasePool` object. `nil` on error. 116 | */ 117 | 118 | - (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags vfs:(NSString *)vfsName; 119 | 120 | /** Returns the Class of 'FMDatabase' subclass, that will be used to instantiate database object. 121 | 122 | Subclasses can override this method to return specified Class of 'FMDatabase' subclass. 123 | 124 | @return The Class of 'FMDatabase' subclass, that will be used to instantiate database object. 125 | */ 126 | 127 | + (Class)databaseClass; 128 | 129 | ///------------------------------------------------ 130 | /// @name Keeping track of checked in/out databases 131 | ///------------------------------------------------ 132 | 133 | /** Number of checked-in databases in pool 134 | 135 | @returns Number of databases 136 | */ 137 | 138 | - (NSUInteger)countOfCheckedInDatabases; 139 | 140 | /** Number of checked-out databases in pool 141 | 142 | @returns Number of databases 143 | */ 144 | 145 | - (NSUInteger)countOfCheckedOutDatabases; 146 | 147 | /** Total number of databases in pool 148 | 149 | @returns Number of databases 150 | */ 151 | 152 | - (NSUInteger)countOfOpenDatabases; 153 | 154 | /** Release all databases in pool */ 155 | 156 | - (void)releaseAllDatabases; 157 | 158 | ///------------------------------------------ 159 | /// @name Perform database operations in pool 160 | ///------------------------------------------ 161 | 162 | /** Synchronously perform database operations in pool. 163 | 164 | @param block The code to be run on the `FMDatabasePool` pool. 165 | */ 166 | 167 | - (void)inDatabase:(void (^)(FMDatabase *db))block; 168 | 169 | /** Synchronously perform database operations in pool using transaction. 170 | 171 | @param block The code to be run on the `FMDatabasePool` pool. 172 | */ 173 | 174 | - (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block; 175 | 176 | /** Synchronously perform database operations in pool using deferred transaction. 177 | 178 | @param block The code to be run on the `FMDatabasePool` pool. 179 | */ 180 | 181 | - (void)inDeferredTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block; 182 | 183 | /** Synchronously perform database operations in pool using save point. 184 | 185 | @param block The code to be run on the `FMDatabasePool` pool. 186 | 187 | @return `NSError` object if error; `nil` if successful. 188 | 189 | @warning You can not nest these, since calling it will pull another database out of the pool and you'll get a deadlock. If you need to nest, use `<[FMDatabase startSavePointWithName:error:]>` instead. 190 | */ 191 | 192 | - (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block; 193 | 194 | @end 195 | 196 | 197 | /** FMDatabasePool delegate category 198 | 199 | This is a category that defines the protocol for the FMDatabasePool delegate 200 | */ 201 | 202 | @interface NSObject (FMDatabasePoolDelegate) 203 | 204 | /** Asks the delegate whether database should be added to the pool. 205 | 206 | @param pool The `FMDatabasePool` object. 207 | @param database The `FMDatabase` object. 208 | 209 | @return `YES` if it should add database to pool; `NO` if not. 210 | 211 | */ 212 | 213 | - (BOOL)databasePool:(FMDatabasePool*)pool shouldAddDatabaseToPool:(FMDatabase*)database; 214 | 215 | /** Tells the delegate that database was added to the pool. 216 | 217 | @param pool The `FMDatabasePool` object. 218 | @param database The `FMDatabase` object. 219 | 220 | */ 221 | 222 | - (void)databasePool:(FMDatabasePool*)pool didAddDatabase:(FMDatabase*)database; 223 | 224 | @end 225 | 226 | -------------------------------------------------------------------------------- /LocaShopCar/fmdb/FMDatabaseQueue.h: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabaseQueue.h 3 | // fmdb 4 | // 5 | // Created by August Mueller on 6/22/11. 6 | // Copyright 2011 Flying Meat Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class FMDatabase; 12 | 13 | /** To perform queries and updates on multiple threads, you'll want to use `FMDatabaseQueue`. 14 | 15 | Using a single instance of `` from multiple threads at once is a bad idea. It has always been OK to make a `` object *per thread*. Just don't share a single instance across threads, and definitely not across multiple threads at the same time. 16 | 17 | Instead, use `FMDatabaseQueue`. Here's how to use it: 18 | 19 | First, make your queue. 20 | 21 | FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath]; 22 | 23 | Then use it like so: 24 | 25 | [queue inDatabase:^(FMDatabase *db) { 26 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]]; 27 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]]; 28 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]]; 29 | 30 | FMResultSet *rs = [db executeQuery:@"select * from foo"]; 31 | while ([rs next]) { 32 | //… 33 | } 34 | }]; 35 | 36 | An easy way to wrap things up in a transaction can be done like this: 37 | 38 | [queue inTransaction:^(FMDatabase *db, BOOL *rollback) { 39 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]]; 40 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]]; 41 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]]; 42 | 43 | if (whoopsSomethingWrongHappened) { 44 | *rollback = YES; 45 | return; 46 | } 47 | // etc… 48 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]]; 49 | }]; 50 | 51 | `FMDatabaseQueue` will run the blocks on a serialized queue (hence the name of the class). So if you call `FMDatabaseQueue`'s methods from multiple threads at the same time, they will be executed in the order they are received. This way queries and updates won't step on each other's toes, and every one is happy. 52 | 53 | ### See also 54 | 55 | - `` 56 | 57 | @warning Do not instantiate a single `` object and use it across multiple threads. Use `FMDatabaseQueue` instead. 58 | 59 | @warning The calls to `FMDatabaseQueue`'s methods are blocking. So even though you are passing along blocks, they will **not** be run on another thread. 60 | 61 | */ 62 | 63 | @interface FMDatabaseQueue : NSObject { 64 | NSString *_path; 65 | dispatch_queue_t _queue; 66 | FMDatabase *_db; 67 | int _openFlags; 68 | NSString *_vfsName; 69 | } 70 | 71 | /** Path of database */ 72 | 73 | @property (atomic, retain) NSString *path; 74 | 75 | /** Open flags */ 76 | 77 | @property (atomic, readonly) int openFlags; 78 | 79 | /** Custom virtual file system name */ 80 | 81 | @property (atomic, copy) NSString *vfsName; 82 | 83 | ///---------------------------------------------------- 84 | /// @name Initialization, opening, and closing of queue 85 | ///---------------------------------------------------- 86 | 87 | /** Create queue using path. 88 | 89 | @param aPath The file path of the database. 90 | 91 | @return The `FMDatabaseQueue` object. `nil` on error. 92 | */ 93 | 94 | + (instancetype)databaseQueueWithPath:(NSString*)aPath; 95 | 96 | /** Create queue using path and specified flags. 97 | 98 | @param aPath The file path of the database. 99 | @param openFlags Flags passed to the openWithFlags method of the database 100 | 101 | @return The `FMDatabaseQueue` object. `nil` on error. 102 | */ 103 | + (instancetype)databaseQueueWithPath:(NSString*)aPath flags:(int)openFlags; 104 | 105 | /** Create queue using path. 106 | 107 | @param aPath The file path of the database. 108 | 109 | @return The `FMDatabaseQueue` object. `nil` on error. 110 | */ 111 | 112 | - (instancetype)initWithPath:(NSString*)aPath; 113 | 114 | /** Create queue using path and specified flags. 115 | 116 | @param aPath The file path of the database. 117 | @param openFlags Flags passed to the openWithFlags method of the database 118 | 119 | @return The `FMDatabaseQueue` object. `nil` on error. 120 | */ 121 | 122 | - (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags; 123 | 124 | /** Create queue using path and specified flags. 125 | 126 | @param aPath The file path of the database. 127 | @param openFlags Flags passed to the openWithFlags method of the database 128 | @param vfsName The name of a custom virtual file system 129 | 130 | @return The `FMDatabaseQueue` object. `nil` on error. 131 | */ 132 | 133 | - (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags vfs:(NSString *)vfsName; 134 | 135 | /** Returns the Class of 'FMDatabase' subclass, that will be used to instantiate database object. 136 | 137 | Subclasses can override this method to return specified Class of 'FMDatabase' subclass. 138 | 139 | @return The Class of 'FMDatabase' subclass, that will be used to instantiate database object. 140 | */ 141 | 142 | + (Class)databaseClass; 143 | 144 | /** Close database used by queue. */ 145 | 146 | - (void)close; 147 | 148 | /** Interupt pending database operation. */ 149 | 150 | - (void)interrupt; 151 | 152 | ///----------------------------------------------- 153 | /// @name Dispatching database operations to queue 154 | ///----------------------------------------------- 155 | 156 | /** Synchronously perform database operations on queue. 157 | 158 | @param block The code to be run on the queue of `FMDatabaseQueue` 159 | */ 160 | 161 | - (void)inDatabase:(void (^)(FMDatabase *db))block; 162 | 163 | /** Synchronously perform database operations on queue, using transactions. 164 | 165 | @param block The code to be run on the queue of `FMDatabaseQueue` 166 | */ 167 | 168 | - (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block; 169 | 170 | /** Synchronously perform database operations on queue, using deferred transactions. 171 | 172 | @param block The code to be run on the queue of `FMDatabaseQueue` 173 | */ 174 | 175 | - (void)inDeferredTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block; 176 | 177 | ///----------------------------------------------- 178 | /// @name Dispatching database operations to queue 179 | ///----------------------------------------------- 180 | 181 | /** Synchronously perform database operations using save point. 182 | 183 | @param block The code to be run on the queue of `FMDatabaseQueue` 184 | */ 185 | 186 | // NOTE: you can not nest these, since calling it will pull another database out of the pool and you'll get a deadlock. 187 | // If you need to nest, use FMDatabase's startSavePointWithName:error: instead. 188 | - (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block; 189 | 190 | @end 191 | 192 | -------------------------------------------------------------------------------- /LocaShopCar/GuoupGood.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | shopId 7 | shop0 8 | shopName 9 | 商家0 10 | goods 11 | 12 | 13 | shopId 14 | shop0 15 | goodsId 16 | goods_00 17 | title 18 | 商品0 19 | price 20 | 100.00 21 | select 22 | 23 | goodsSelectCount 24 | 0 25 | 26 | 27 | shopId 28 | shop0 29 | goodsId 30 | goods_01 31 | title 32 | 商品1 33 | price 34 | 100.00 35 | select 36 | 37 | goodsSelectCount 38 | 0 39 | 40 | 41 | 42 | 43 | shopId 44 | shop1 45 | shopName 46 | 商家1 47 | goods 48 | 49 | 50 | shopId 51 | shop1 52 | goodsId 53 | goods_10 54 | title 55 | 商品0 56 | price 57 | 100.00 58 | select 59 | 60 | goodsSelectCount 61 | 0 62 | 63 | 64 | shopId 65 | shop1 66 | goodsId 67 | goods_11 68 | title 69 | 商品1 70 | price 71 | 100.00 72 | select 73 | 74 | goodsSelectCount 75 | 0 76 | 77 | 78 | 79 | 80 | shopId 81 | shop2 82 | shopName 83 | 商家2 84 | goods 85 | 86 | 87 | shopId 88 | shop2 89 | goodsId 90 | goods_100 91 | title 92 | 商品0 93 | price 94 | 100.00 95 | select 96 | 97 | goodsSelectCount 98 | 0 99 | 100 | 101 | shopId 102 | shop2 103 | goodsId 104 | goods_101 105 | title 106 | 商品1 107 | price 108 | 100.00 109 | select 110 | 111 | goodsSelectCount 112 | 0 113 | 114 | 115 | shopId 116 | shop2 117 | goodsId 118 | goods_102 119 | title 120 | 商品2 121 | price 122 | 100.00 123 | select 124 | 125 | goodsSelectCount 126 | 0 127 | 128 | 129 | shopId 130 | shop2 131 | goodsId 132 | goods_103 133 | title 134 | 商品3 135 | price 136 | 100.00 137 | select 138 | 139 | goodsSelectCount 140 | 0 141 | 142 | 143 | 144 | 145 | shopId 146 | shop3 147 | shopName 148 | 商家3 149 | goods 150 | 151 | 152 | shopId 153 | shop3 154 | goodsId 155 | goods_1000 156 | title 157 | 商品0 158 | price 159 | 100.00 160 | select 161 | 162 | goodsSelectCount 163 | 0 164 | 165 | 166 | shopId 167 | shop3 168 | goodsId 169 | goods_1001 170 | title 171 | 商品1 172 | price 173 | 100.00 174 | select 175 | 176 | goodsSelectCount 177 | 0 178 | 179 | 180 | shopId 181 | shop3 182 | goodsId 183 | goods_1002 184 | title 185 | 商品1 186 | price 187 | 100.00 188 | select 189 | 190 | goodsSelectCount 191 | 0 192 | 193 | 194 | shopId 195 | shop3 196 | goodsId 197 | goods_1003 198 | title 199 | 商品1 200 | price 201 | 100.00 202 | select 203 | 204 | goodsSelectCount 205 | 0 206 | 207 | 208 | shopId 209 | shop3 210 | goodsId 211 | goods_1004 212 | title 213 | 商品1 214 | price 215 | 100.00 216 | select 217 | 218 | goodsSelectCount 219 | 0 220 | 221 | 222 | 223 | 224 | shopId 225 | shop4 226 | shopName 227 | 商家4 228 | goods 229 | 230 | 231 | shopId 232 | shop4 233 | goodsId 234 | goods_10000 235 | title 236 | 商品0 237 | price 238 | 100.00 239 | select 240 | 241 | goodsSelectCount 242 | 0 243 | 244 | 245 | shopId 246 | shop4 247 | goodsId 248 | goods_10001 249 | title 250 | 商品1 251 | price 252 | 100.00 253 | select 254 | 255 | goodsSelectCount 256 | 0 257 | 258 | 259 | shopId 260 | shop4 261 | goodsId 262 | goods_10002 263 | title 264 | 商品1 265 | price 266 | 100.00 267 | select 268 | 269 | goodsSelectCount 270 | 0 271 | 272 | 273 | shopId 274 | shop4 275 | goodsId 276 | goods_10003 277 | title 278 | 商品1 279 | price 280 | 100.00 281 | select 282 | 283 | goodsSelectCount 284 | 0 285 | 286 | 287 | 288 | 289 | 290 | -------------------------------------------------------------------------------- /LocaShopCar/fmdb/FMDatabaseQueue.m: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabaseQueue.m 3 | // fmdb 4 | // 5 | // Created by August Mueller on 6/22/11. 6 | // Copyright 2011 Flying Meat Inc. All rights reserved. 7 | // 8 | 9 | #import "FMDatabaseQueue.h" 10 | #import "FMDatabase.h" 11 | 12 | #if FMDB_SQLITE_STANDALONE 13 | #import 14 | #else 15 | #import 16 | #endif 17 | 18 | /* 19 | 20 | Note: we call [self retain]; before using dispatch_sync, just incase 21 | FMDatabaseQueue is released on another thread and we're in the middle of doing 22 | something in dispatch_sync 23 | 24 | */ 25 | 26 | /* 27 | * A key used to associate the FMDatabaseQueue object with the dispatch_queue_t it uses. 28 | * This in turn is used for deadlock detection by seeing if inDatabase: is called on 29 | * the queue's dispatch queue, which should not happen and causes a deadlock. 30 | */ 31 | static const void * const kDispatchQueueSpecificKey = &kDispatchQueueSpecificKey; 32 | 33 | @implementation FMDatabaseQueue 34 | 35 | @synthesize path = _path; 36 | @synthesize openFlags = _openFlags; 37 | @synthesize vfsName = _vfsName; 38 | 39 | + (instancetype)databaseQueueWithPath:(NSString*)aPath { 40 | 41 | FMDatabaseQueue *q = [[self alloc] initWithPath:aPath]; 42 | 43 | FMDBAutorelease(q); 44 | 45 | return q; 46 | } 47 | 48 | + (instancetype)databaseQueueWithPath:(NSString*)aPath flags:(int)openFlags { 49 | 50 | FMDatabaseQueue *q = [[self alloc] initWithPath:aPath flags:openFlags]; 51 | 52 | FMDBAutorelease(q); 53 | 54 | return q; 55 | } 56 | 57 | + (Class)databaseClass { 58 | return [FMDatabase class]; 59 | } 60 | 61 | - (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags vfs:(NSString *)vfsName { 62 | 63 | self = [super init]; 64 | 65 | if (self != nil) { 66 | 67 | _db = [[[self class] databaseClass] databaseWithPath:aPath]; 68 | FMDBRetain(_db); 69 | 70 | #if SQLITE_VERSION_NUMBER >= 3005000 71 | BOOL success = [_db openWithFlags:openFlags vfs:vfsName]; 72 | #else 73 | BOOL success = [_db open]; 74 | #endif 75 | if (!success) { 76 | NSLog(@"Could not create database queue for path %@", aPath); 77 | FMDBRelease(self); 78 | return 0x00; 79 | } 80 | 81 | _path = FMDBReturnRetained(aPath); 82 | 83 | _queue = dispatch_queue_create([[NSString stringWithFormat:@"fmdb.%@", self] UTF8String], NULL); 84 | dispatch_queue_set_specific(_queue, kDispatchQueueSpecificKey, (__bridge void *)self, NULL); 85 | _openFlags = openFlags; 86 | _vfsName = [vfsName copy]; 87 | } 88 | 89 | return self; 90 | } 91 | 92 | - (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags { 93 | return [self initWithPath:aPath flags:openFlags vfs:nil]; 94 | } 95 | 96 | - (instancetype)initWithPath:(NSString*)aPath { 97 | 98 | // default flags for sqlite3_open 99 | return [self initWithPath:aPath flags:SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE vfs:nil]; 100 | } 101 | 102 | - (instancetype)init { 103 | return [self initWithPath:nil]; 104 | } 105 | 106 | 107 | - (void)dealloc { 108 | 109 | FMDBRelease(_db); 110 | FMDBRelease(_path); 111 | 112 | if (_queue) { 113 | FMDBDispatchQueueRelease(_queue); 114 | _queue = 0x00; 115 | } 116 | #if ! __has_feature(objc_arc) 117 | [super dealloc]; 118 | #endif 119 | } 120 | 121 | - (void)close { 122 | FMDBRetain(self); 123 | dispatch_sync(_queue, ^() { 124 | [self->_db close]; 125 | FMDBRelease(_db); 126 | self->_db = 0x00; 127 | }); 128 | FMDBRelease(self); 129 | } 130 | 131 | - (void)interrupt 132 | { 133 | [[self database] interrupt]; 134 | } 135 | 136 | - (FMDatabase*)database { 137 | if (!_db) { 138 | _db = FMDBReturnRetained([[[self class] databaseClass] databaseWithPath:_path]); 139 | 140 | #if SQLITE_VERSION_NUMBER >= 3005000 141 | BOOL success = [_db openWithFlags:_openFlags vfs:_vfsName]; 142 | #else 143 | BOOL success = [_db open]; 144 | #endif 145 | if (!success) { 146 | NSLog(@"FMDatabaseQueue could not reopen database for path %@", _path); 147 | FMDBRelease(_db); 148 | _db = 0x00; 149 | return 0x00; 150 | } 151 | } 152 | 153 | return _db; 154 | } 155 | 156 | - (void)inDatabase:(void (^)(FMDatabase *db))block { 157 | /* Get the currently executing queue (which should probably be nil, but in theory could be another DB queue 158 | * and then check it against self to make sure we're not about to deadlock. */ 159 | FMDatabaseQueue *currentSyncQueue = (__bridge id)dispatch_get_specific(kDispatchQueueSpecificKey); 160 | assert(currentSyncQueue != self && "inDatabase: was called reentrantly on the same queue, which would lead to a deadlock"); 161 | 162 | FMDBRetain(self); 163 | 164 | dispatch_sync(_queue, ^() { 165 | 166 | FMDatabase *db = [self database]; 167 | block(db); 168 | 169 | if ([db hasOpenResultSets]) { 170 | NSLog(@"Warning: there is at least one open result set around after performing [FMDatabaseQueue inDatabase:]"); 171 | 172 | #if defined(DEBUG) && DEBUG 173 | NSSet *openSetCopy = FMDBReturnAutoreleased([[db valueForKey:@"_openResultSets"] copy]); 174 | for (NSValue *rsInWrappedInATastyValueMeal in openSetCopy) { 175 | FMResultSet *rs = (FMResultSet *)[rsInWrappedInATastyValueMeal pointerValue]; 176 | NSLog(@"query: '%@'", [rs query]); 177 | } 178 | #endif 179 | } 180 | }); 181 | 182 | FMDBRelease(self); 183 | } 184 | 185 | 186 | - (void)beginTransaction:(BOOL)useDeferred withBlock:(void (^)(FMDatabase *db, BOOL *rollback))block { 187 | FMDBRetain(self); 188 | dispatch_sync(_queue, ^() { 189 | 190 | BOOL shouldRollback = NO; 191 | 192 | if (useDeferred) { 193 | [[self database] beginDeferredTransaction]; 194 | } 195 | else { 196 | [[self database] beginTransaction]; 197 | } 198 | 199 | block([self database], &shouldRollback); 200 | 201 | if (shouldRollback) { 202 | [[self database] rollback]; 203 | } 204 | else { 205 | [[self database] commit]; 206 | } 207 | }); 208 | 209 | FMDBRelease(self); 210 | } 211 | 212 | - (void)inDeferredTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block { 213 | [self beginTransaction:YES withBlock:block]; 214 | } 215 | 216 | - (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block { 217 | [self beginTransaction:NO withBlock:block]; 218 | } 219 | 220 | - (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block { 221 | #if SQLITE_VERSION_NUMBER >= 3007000 222 | static unsigned long savePointIdx = 0; 223 | __block NSError *err = 0x00; 224 | FMDBRetain(self); 225 | dispatch_sync(_queue, ^() { 226 | 227 | NSString *name = [NSString stringWithFormat:@"savePoint%ld", savePointIdx++]; 228 | 229 | BOOL shouldRollback = NO; 230 | 231 | if ([[self database] startSavePointWithName:name error:&err]) { 232 | 233 | block([self database], &shouldRollback); 234 | 235 | if (shouldRollback) { 236 | // We need to rollback and release this savepoint to remove it 237 | [[self database] rollbackToSavePointWithName:name error:&err]; 238 | } 239 | [[self database] releaseSavePointWithName:name error:&err]; 240 | 241 | } 242 | }); 243 | FMDBRelease(self); 244 | return err; 245 | #else 246 | NSString *errorMessage = NSLocalizedString(@"Save point functions require SQLite 3.7", nil); 247 | if (self.logsErrors) NSLog(@"%@", errorMessage); 248 | return [NSError errorWithDomain:@"FMDatabase" code:0 userInfo:@{NSLocalizedDescriptionKey : errorMessage}]; 249 | #endif 250 | } 251 | 252 | @end 253 | -------------------------------------------------------------------------------- /LocaShopCar/fmdb/FMDatabaseAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabaseAdditions.m 3 | // fmdb 4 | // 5 | // Created by August Mueller on 10/30/05. 6 | // Copyright 2005 Flying Meat Inc.. All rights reserved. 7 | // 8 | 9 | #import "FMDatabase.h" 10 | #import "FMDatabaseAdditions.h" 11 | #import "TargetConditionals.h" 12 | 13 | #if FMDB_SQLITE_STANDALONE 14 | #import 15 | #else 16 | #import 17 | #endif 18 | 19 | @interface FMDatabase (PrivateStuff) 20 | - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arrayArgs orDictionary:(NSDictionary *)dictionaryArgs orVAList:(va_list)args; 21 | @end 22 | 23 | @implementation FMDatabase (FMDatabaseAdditions) 24 | 25 | #define RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(type, sel) \ 26 | va_list args; \ 27 | va_start(args, query); \ 28 | FMResultSet *resultSet = [self executeQuery:query withArgumentsInArray:0x00 orDictionary:0x00 orVAList:args]; \ 29 | va_end(args); \ 30 | if (![resultSet next]) { return (type)0; } \ 31 | type ret = [resultSet sel:0]; \ 32 | [resultSet close]; \ 33 | [resultSet setParentDB:nil]; \ 34 | return ret; 35 | 36 | 37 | - (NSString*)stringForQuery:(NSString*)query, ... { 38 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSString *, stringForColumnIndex); 39 | } 40 | 41 | - (int)intForQuery:(NSString*)query, ... { 42 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(int, intForColumnIndex); 43 | } 44 | 45 | - (long)longForQuery:(NSString*)query, ... { 46 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(long, longForColumnIndex); 47 | } 48 | 49 | - (BOOL)boolForQuery:(NSString*)query, ... { 50 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(BOOL, boolForColumnIndex); 51 | } 52 | 53 | - (double)doubleForQuery:(NSString*)query, ... { 54 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(double, doubleForColumnIndex); 55 | } 56 | 57 | - (NSData*)dataForQuery:(NSString*)query, ... { 58 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSData *, dataForColumnIndex); 59 | } 60 | 61 | - (NSDate*)dateForQuery:(NSString*)query, ... { 62 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSDate *, dateForColumnIndex); 63 | } 64 | 65 | 66 | - (BOOL)tableExists:(NSString*)tableName { 67 | 68 | tableName = [tableName lowercaseString]; 69 | 70 | FMResultSet *rs = [self executeQuery:@"select [sql] from sqlite_master where [type] = 'table' and lower(name) = ?", tableName]; 71 | 72 | //if at least one next exists, table exists 73 | BOOL returnBool = [rs next]; 74 | 75 | //close and free object 76 | [rs close]; 77 | 78 | return returnBool; 79 | } 80 | 81 | /* 82 | get table with list of tables: result colums: type[STRING], name[STRING],tbl_name[STRING],rootpage[INTEGER],sql[STRING] 83 | check if table exist in database (patch from OZLB) 84 | */ 85 | - (FMResultSet*)getSchema { 86 | 87 | //result colums: type[STRING], name[STRING],tbl_name[STRING],rootpage[INTEGER],sql[STRING] 88 | FMResultSet *rs = [self executeQuery:@"SELECT type, name, tbl_name, rootpage, sql FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) WHERE type != 'meta' AND name NOT LIKE 'sqlite_%' ORDER BY tbl_name, type DESC, name"]; 89 | 90 | return rs; 91 | } 92 | 93 | /* 94 | get table schema: result colums: cid[INTEGER], name,type [STRING], notnull[INTEGER], dflt_value[],pk[INTEGER] 95 | */ 96 | - (FMResultSet*)getTableSchema:(NSString*)tableName { 97 | 98 | //result colums: cid[INTEGER], name,type [STRING], notnull[INTEGER], dflt_value[],pk[INTEGER] 99 | FMResultSet *rs = [self executeQuery:[NSString stringWithFormat: @"pragma table_info('%@')", tableName]]; 100 | 101 | return rs; 102 | } 103 | 104 | - (BOOL)columnExists:(NSString*)columnName inTableWithName:(NSString*)tableName { 105 | 106 | BOOL returnBool = NO; 107 | 108 | tableName = [tableName lowercaseString]; 109 | columnName = [columnName lowercaseString]; 110 | 111 | FMResultSet *rs = [self getTableSchema:tableName]; 112 | 113 | //check if column is present in table schema 114 | while ([rs next]) { 115 | if ([[[rs stringForColumn:@"name"] lowercaseString] isEqualToString:columnName]) { 116 | returnBool = YES; 117 | break; 118 | } 119 | } 120 | 121 | //If this is not done FMDatabase instance stays out of pool 122 | [rs close]; 123 | 124 | return returnBool; 125 | } 126 | 127 | 128 | 129 | - (uint32_t)applicationID { 130 | #if SQLITE_VERSION_NUMBER >= 3007017 131 | uint32_t r = 0; 132 | 133 | FMResultSet *rs = [self executeQuery:@"pragma application_id"]; 134 | 135 | if ([rs next]) { 136 | r = (uint32_t)[rs longLongIntForColumnIndex:0]; 137 | } 138 | 139 | [rs close]; 140 | 141 | return r; 142 | #else 143 | NSString *errorMessage = NSLocalizedString(@"Application ID functions require SQLite 3.7.17", nil); 144 | if (self.logsErrors) NSLog(@"%@", errorMessage); 145 | return 0; 146 | #endif 147 | } 148 | 149 | - (void)setApplicationID:(uint32_t)appID { 150 | #if SQLITE_VERSION_NUMBER >= 3007017 151 | NSString *query = [NSString stringWithFormat:@"pragma application_id=%d", appID]; 152 | FMResultSet *rs = [self executeQuery:query]; 153 | [rs next]; 154 | [rs close]; 155 | #else 156 | NSString *errorMessage = NSLocalizedString(@"Application ID functions require SQLite 3.7.17", nil); 157 | if (self.logsErrors) NSLog(@"%@", errorMessage); 158 | #endif 159 | } 160 | 161 | 162 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE 163 | 164 | - (NSString*)applicationIDString { 165 | #if SQLITE_VERSION_NUMBER >= 3007017 166 | NSString *s = NSFileTypeForHFSTypeCode([self applicationID]); 167 | 168 | assert([s length] == 6); 169 | 170 | s = [s substringWithRange:NSMakeRange(1, 4)]; 171 | 172 | 173 | return s; 174 | #else 175 | NSString *errorMessage = NSLocalizedString(@"Application ID functions require SQLite 3.7.17", nil); 176 | if (self.logsErrors) NSLog(@"%@", errorMessage); 177 | return nil; 178 | #endif 179 | } 180 | 181 | - (void)setApplicationIDString:(NSString*)s { 182 | #if SQLITE_VERSION_NUMBER >= 3007017 183 | if ([s length] != 4) { 184 | NSLog(@"setApplicationIDString: string passed is not exactly 4 chars long. (was %ld)", [s length]); 185 | } 186 | 187 | [self setApplicationID:NSHFSTypeCodeFromFileType([NSString stringWithFormat:@"'%@'", s])]; 188 | #else 189 | NSString *errorMessage = NSLocalizedString(@"Application ID functions require SQLite 3.7.17", nil); 190 | if (self.logsErrors) NSLog(@"%@", errorMessage); 191 | #endif 192 | } 193 | 194 | #endif 195 | 196 | - (uint32_t)userVersion { 197 | uint32_t r = 0; 198 | 199 | FMResultSet *rs = [self executeQuery:@"pragma user_version"]; 200 | 201 | if ([rs next]) { 202 | r = (uint32_t)[rs longLongIntForColumnIndex:0]; 203 | } 204 | 205 | [rs close]; 206 | return r; 207 | } 208 | 209 | - (void)setUserVersion:(uint32_t)version { 210 | NSString *query = [NSString stringWithFormat:@"pragma user_version = %d", version]; 211 | FMResultSet *rs = [self executeQuery:query]; 212 | [rs next]; 213 | [rs close]; 214 | } 215 | 216 | #pragma clang diagnostic push 217 | #pragma clang diagnostic ignored "-Wdeprecated-implementations" 218 | 219 | - (BOOL)columnExists:(NSString*)tableName columnName:(NSString*)columnName __attribute__ ((deprecated)) { 220 | return [self columnExists:columnName inTableWithName:tableName]; 221 | } 222 | 223 | #pragma clang diagnostic pop 224 | 225 | 226 | - (BOOL)validateSQL:(NSString*)sql error:(NSError**)error { 227 | sqlite3_stmt *pStmt = NULL; 228 | BOOL validationSucceeded = YES; 229 | 230 | int rc = sqlite3_prepare_v2(_db, [sql UTF8String], -1, &pStmt, 0); 231 | if (rc != SQLITE_OK) { 232 | validationSucceeded = NO; 233 | if (error) { 234 | *error = [NSError errorWithDomain:NSCocoaErrorDomain 235 | code:[self lastErrorCode] 236 | userInfo:[NSDictionary dictionaryWithObject:[self lastErrorMessage] 237 | forKey:NSLocalizedDescriptionKey]]; 238 | } 239 | } 240 | 241 | sqlite3_finalize(pStmt); 242 | 243 | return validationSucceeded; 244 | } 245 | 246 | @end 247 | -------------------------------------------------------------------------------- /LocaShopCar/fmdb/FMDatabaseAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabaseAdditions.h 3 | // fmdb 4 | // 5 | // Created by August Mueller on 10/30/05. 6 | // Copyright 2005 Flying Meat Inc.. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FMDatabase.h" 11 | 12 | 13 | /** Category of additions for `` class. 14 | 15 | ### See also 16 | 17 | - `` 18 | */ 19 | 20 | @interface FMDatabase (FMDatabaseAdditions) 21 | 22 | ///---------------------------------------- 23 | /// @name Return results of SQL to variable 24 | ///---------------------------------------- 25 | 26 | /** Return `int` value for query 27 | 28 | @param query The SQL query to be performed. 29 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 30 | 31 | @return `int` value. 32 | 33 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project. 34 | */ 35 | 36 | - (int)intForQuery:(NSString*)query, ...; 37 | 38 | /** Return `long` value for query 39 | 40 | @param query The SQL query to be performed. 41 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 42 | 43 | @return `long` value. 44 | 45 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project. 46 | */ 47 | 48 | - (long)longForQuery:(NSString*)query, ...; 49 | 50 | /** Return `BOOL` value for query 51 | 52 | @param query The SQL query to be performed. 53 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 54 | 55 | @return `BOOL` value. 56 | 57 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project. 58 | */ 59 | 60 | - (BOOL)boolForQuery:(NSString*)query, ...; 61 | 62 | /** Return `double` value for query 63 | 64 | @param query The SQL query to be performed. 65 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 66 | 67 | @return `double` value. 68 | 69 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project. 70 | */ 71 | 72 | - (double)doubleForQuery:(NSString*)query, ...; 73 | 74 | /** Return `NSString` value for query 75 | 76 | @param query The SQL query to be performed. 77 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 78 | 79 | @return `NSString` value. 80 | 81 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project. 82 | */ 83 | 84 | - (NSString*)stringForQuery:(NSString*)query, ...; 85 | 86 | /** Return `NSData` value for query 87 | 88 | @param query The SQL query to be performed. 89 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 90 | 91 | @return `NSData` value. 92 | 93 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project. 94 | */ 95 | 96 | - (NSData*)dataForQuery:(NSString*)query, ...; 97 | 98 | /** Return `NSDate` value for query 99 | 100 | @param query The SQL query to be performed. 101 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 102 | 103 | @return `NSDate` value. 104 | 105 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project. 106 | */ 107 | 108 | - (NSDate*)dateForQuery:(NSString*)query, ...; 109 | 110 | 111 | // Notice that there's no dataNoCopyForQuery:. 112 | // That would be a bad idea, because we close out the result set, and then what 113 | // happens to the data that we just didn't copy? Who knows, not I. 114 | 115 | 116 | ///-------------------------------- 117 | /// @name Schema related operations 118 | ///-------------------------------- 119 | 120 | /** Does table exist in database? 121 | 122 | @param tableName The name of the table being looked for. 123 | 124 | @return `YES` if table found; `NO` if not found. 125 | */ 126 | 127 | - (BOOL)tableExists:(NSString*)tableName; 128 | 129 | /** The schema of the database. 130 | 131 | This will be the schema for the entire database. For each entity, each row of the result set will include the following fields: 132 | 133 | - `type` - The type of entity (e.g. table, index, view, or trigger) 134 | - `name` - The name of the object 135 | - `tbl_name` - The name of the table to which the object references 136 | - `rootpage` - The page number of the root b-tree page for tables and indices 137 | - `sql` - The SQL that created the entity 138 | 139 | @return `FMResultSet` of schema; `nil` on error. 140 | 141 | @see [SQLite File Format](http://www.sqlite.org/fileformat.html) 142 | */ 143 | 144 | - (FMResultSet*)getSchema; 145 | 146 | /** The schema of the database. 147 | 148 | This will be the schema for a particular table as report by SQLite `PRAGMA`, for example: 149 | 150 | PRAGMA table_info('employees') 151 | 152 | This will report: 153 | 154 | - `cid` - The column ID number 155 | - `name` - The name of the column 156 | - `type` - The data type specified for the column 157 | - `notnull` - whether the field is defined as NOT NULL (i.e. values required) 158 | - `dflt_value` - The default value for the column 159 | - `pk` - Whether the field is part of the primary key of the table 160 | 161 | @param tableName The name of the table for whom the schema will be returned. 162 | 163 | @return `FMResultSet` of schema; `nil` on error. 164 | 165 | @see [table_info](http://www.sqlite.org/pragma.html#pragma_table_info) 166 | */ 167 | 168 | - (FMResultSet*)getTableSchema:(NSString*)tableName; 169 | 170 | /** Test to see if particular column exists for particular table in database 171 | 172 | @param columnName The name of the column. 173 | 174 | @param tableName The name of the table. 175 | 176 | @return `YES` if column exists in table in question; `NO` otherwise. 177 | */ 178 | 179 | - (BOOL)columnExists:(NSString*)columnName inTableWithName:(NSString*)tableName; 180 | 181 | /** Test to see if particular column exists for particular table in database 182 | 183 | @param columnName The name of the column. 184 | 185 | @param tableName The name of the table. 186 | 187 | @return `YES` if column exists in table in question; `NO` otherwise. 188 | 189 | @see columnExists:inTableWithName: 190 | 191 | @warning Deprecated - use `` instead. 192 | */ 193 | 194 | - (BOOL)columnExists:(NSString*)tableName columnName:(NSString*)columnName __attribute__ ((deprecated)); 195 | 196 | 197 | /** Validate SQL statement 198 | 199 | This validates SQL statement by performing `sqlite3_prepare_v2`, but not returning the results, but instead immediately calling `sqlite3_finalize`. 200 | 201 | @param sql The SQL statement being validated. 202 | 203 | @param error This is a pointer to a `NSError` object that will receive the autoreleased `NSError` object if there was any error. If this is `nil`, no `NSError` result will be returned. 204 | 205 | @return `YES` if validation succeeded without incident; `NO` otherwise. 206 | 207 | */ 208 | 209 | - (BOOL)validateSQL:(NSString*)sql error:(NSError**)error; 210 | 211 | 212 | ///----------------------------------- 213 | /// @name Application identifier tasks 214 | ///----------------------------------- 215 | 216 | /** Retrieve application ID 217 | 218 | @return The `uint32_t` numeric value of the application ID. 219 | 220 | @see setApplicationID: 221 | */ 222 | 223 | - (uint32_t)applicationID; 224 | 225 | /** Set the application ID 226 | 227 | @param appID The `uint32_t` numeric value of the application ID. 228 | 229 | @see applicationID 230 | */ 231 | 232 | - (void)setApplicationID:(uint32_t)appID; 233 | 234 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE 235 | /** Retrieve application ID string 236 | 237 | @return The `NSString` value of the application ID. 238 | 239 | @see setApplicationIDString: 240 | */ 241 | 242 | 243 | - (NSString*)applicationIDString; 244 | 245 | /** Set the application ID string 246 | 247 | @param string The `NSString` value of the application ID. 248 | 249 | @see applicationIDString 250 | */ 251 | 252 | - (void)setApplicationIDString:(NSString*)string; 253 | 254 | #endif 255 | 256 | ///----------------------------------- 257 | /// @name user version identifier tasks 258 | ///----------------------------------- 259 | 260 | /** Retrieve user version 261 | 262 | @return The `uint32_t` numeric value of the user version. 263 | 264 | @see setUserVersion: 265 | */ 266 | 267 | - (uint32_t)userVersion; 268 | 269 | /** Set the user-version 270 | 271 | @param version The `uint32_t` numeric value of the user version. 272 | 273 | @see userVersion 274 | */ 275 | 276 | - (void)setUserVersion:(uint32_t)version; 277 | 278 | @end 279 | -------------------------------------------------------------------------------- /LocaShopCar/IQKeyboardManager/IQToolbar/IQToolbar.m: -------------------------------------------------------------------------------- 1 | // 2 | // IQToolbar.m 3 | // https://github.com/hackiftekhar/IQKeyboardManager 4 | // Copyright (c) 2013-16 Iftekhar Qurashi. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import "IQToolbar.h" 25 | #import "IQKeyboardManagerConstantsInternal.h" 26 | #import "IQTitleBarButtonItem.h" 27 | #import "IQUIView+Hierarchy.h" 28 | 29 | #import 30 | 31 | @implementation IQToolbar 32 | @synthesize titleFont = _titleFont; 33 | @synthesize title = _title; 34 | 35 | Class IQUIToolbarTextButtonClass; 36 | Class IQUIToolbarButtonClass; 37 | 38 | 39 | +(void)load 40 | { 41 | IQUIToolbarTextButtonClass = NSClassFromString(@"UIToolbarTextButton"); 42 | IQUIToolbarButtonClass = NSClassFromString(@"UIToolbarButton"); 43 | 44 | //Tint Color 45 | [[self appearance] setTintColor:nil]; 46 | 47 | [[self appearance] setBarTintColor:nil]; 48 | 49 | //Background image 50 | [[self appearance] setBackgroundImage:nil forToolbarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault]; 51 | [[self appearance] setBackgroundImage:nil forToolbarPosition:UIBarPositionBottom barMetrics:UIBarMetricsDefault]; 52 | [[self appearance] setBackgroundImage:nil forToolbarPosition:UIBarPositionTop barMetrics:UIBarMetricsDefault]; 53 | [[self appearance] setBackgroundImage:nil forToolbarPosition:UIBarPositionTopAttached barMetrics:UIBarMetricsDefault]; 54 | 55 | //Shadow image 56 | [[self appearance] setShadowImage:nil forToolbarPosition:UIBarPositionAny]; 57 | [[self appearance] setShadowImage:nil forToolbarPosition:UIBarPositionBottom]; 58 | [[self appearance] setShadowImage:nil forToolbarPosition:UIBarPositionTop]; 59 | [[self appearance] setShadowImage:nil forToolbarPosition:UIBarPositionTopAttached]; 60 | 61 | //Background color 62 | [[self appearance] setBackgroundColor:nil]; 63 | } 64 | 65 | -(void)initialize 66 | { 67 | [self sizeToFit]; 68 | self.autoresizingMask = UIViewAutoresizingFlexibleWidth;// | UIViewAutoresizingFlexibleHeight; 69 | self.translucent = YES; 70 | [self setTintColor:[UIColor blackColor]]; 71 | } 72 | 73 | - (instancetype)initWithFrame:(CGRect)frame 74 | { 75 | self = [super initWithFrame:frame]; 76 | if (self) 77 | { 78 | [self initialize]; 79 | } 80 | return self; 81 | } 82 | 83 | - (instancetype)initWithCoder:(NSCoder *)coder 84 | { 85 | self = [super initWithCoder:coder]; 86 | if (self) 87 | { 88 | [self initialize]; 89 | } 90 | return self; 91 | } 92 | 93 | -(CGSize)sizeThatFits:(CGSize)size 94 | { 95 | CGSize sizeThatFit = [super sizeThatFits:size]; 96 | 97 | sizeThatFit.height = 44; 98 | 99 | return sizeThatFit; 100 | } 101 | 102 | -(void)setBarStyle:(UIBarStyle)barStyle 103 | { 104 | [super setBarStyle:barStyle]; 105 | 106 | for (UIBarButtonItem *item in self.items) 107 | { 108 | if ([item isKindOfClass:[IQTitleBarButtonItem class]]) 109 | { 110 | if (barStyle == UIBarStyleDefault) 111 | { 112 | [(IQTitleBarButtonItem*)item setSelectableTextColor:[UIColor colorWithRed:0.0 green:0.5 blue:1.0 alpha:1.0]]; 113 | } 114 | else 115 | { 116 | [(IQTitleBarButtonItem*)item setSelectableTextColor:[UIColor yellowColor]]; 117 | } 118 | 119 | break; 120 | } 121 | } 122 | } 123 | 124 | -(void)setTintColor:(UIColor *)tintColor 125 | { 126 | [super setTintColor:tintColor]; 127 | 128 | for (UIBarButtonItem *item in self.items) 129 | { 130 | [item setTintColor:tintColor]; 131 | } 132 | } 133 | 134 | -(void)setTitleFont:(UIFont *)titleFont 135 | { 136 | _titleFont = titleFont; 137 | 138 | for (UIBarButtonItem *item in self.items) 139 | { 140 | if ([item isKindOfClass:[IQTitleBarButtonItem class]]) 141 | { 142 | [(IQTitleBarButtonItem*)item setFont:titleFont]; 143 | break; 144 | } 145 | } 146 | } 147 | 148 | -(void)setTitle:(NSString *)title 149 | { 150 | _title = title; 151 | 152 | for (UIBarButtonItem *item in self.items) 153 | { 154 | if ([item isKindOfClass:[IQTitleBarButtonItem class]]) 155 | { 156 | [(IQTitleBarButtonItem*)item setTitle:title]; 157 | break; 158 | } 159 | } 160 | } 161 | 162 | -(void)setTitleTarget:(nullable id)target action:(nullable SEL)action 163 | { 164 | NSInvocation *invocation = nil; 165 | 166 | if (target && action) 167 | { 168 | invocation = [NSInvocation invocationWithMethodSignature:[target methodSignatureForSelector:action]]; 169 | invocation.target = target; 170 | invocation.selector = action; 171 | } 172 | 173 | self.titleInvocation = invocation; 174 | } 175 | 176 | -(void)setTitleInvocation:(NSInvocation*)invocation 177 | { 178 | _titleInvocation = invocation; 179 | 180 | for (UIBarButtonItem *item in self.items) 181 | { 182 | if ([item isKindOfClass:[IQTitleBarButtonItem class]]) 183 | { 184 | [(IQTitleBarButtonItem*)item setTitleInvocation:_titleInvocation]; 185 | break; 186 | } 187 | } 188 | } 189 | 190 | -(void)layoutSubviews 191 | { 192 | [super layoutSubviews]; 193 | 194 | CGRect leftRect = CGRectNull; 195 | CGRect rightRect = CGRectNull; 196 | 197 | BOOL isTitleBarButtonFound = NO; 198 | 199 | NSArray *subviews = [self.subviews sortedArrayUsingComparator:^NSComparisonResult(UIView *view1, UIView *view2) { 200 | 201 | CGFloat x1 = CGRectGetMinX(view1.frame); 202 | CGFloat y1 = CGRectGetMinY(view1.frame); 203 | CGFloat x2 = CGRectGetMinX(view2.frame); 204 | CGFloat y2 = CGRectGetMinY(view2.frame); 205 | 206 | if (x1 < x2) return NSOrderedAscending; 207 | 208 | else if (x1 > x2) return NSOrderedDescending; 209 | 210 | //Else both y are same so checking for x positions 211 | else if (y1 < y2) return NSOrderedAscending; 212 | 213 | else if (y1 > y2) return NSOrderedDescending; 214 | 215 | else return NSOrderedSame; 216 | }]; 217 | 218 | for (UIView *barButtonItemView in subviews) 219 | { 220 | if (isTitleBarButtonFound == YES) 221 | { 222 | rightRect = barButtonItemView.frame; 223 | break; 224 | } 225 | else if ([barButtonItemView isMemberOfClass:[UIView class]]) 226 | { 227 | isTitleBarButtonFound = YES; 228 | } 229 | else if ([barButtonItemView isKindOfClass:IQUIToolbarTextButtonClass] || 230 | [barButtonItemView isKindOfClass:IQUIToolbarButtonClass]) 231 | { 232 | leftRect = barButtonItemView.frame; 233 | } 234 | } 235 | 236 | CGFloat x = 16; 237 | 238 | if (CGRectIsNull(leftRect) == false) 239 | { 240 | x = CGRectGetMaxX(leftRect) + 16; 241 | } 242 | 243 | CGFloat width = CGRectGetWidth(self.frame) - 32 - (CGRectIsNull(leftRect)?0:CGRectGetMaxX(leftRect)) - (CGRectIsNull(rightRect)?0:CGRectGetWidth(self.frame)-CGRectGetMinX(rightRect)); 244 | 245 | for (UIBarButtonItem *item in self.items) 246 | { 247 | if ([item isKindOfClass:[IQTitleBarButtonItem class]]) 248 | { 249 | CGRect titleRect = CGRectMake(x, 0, width, self.frame.size.height); 250 | item.customView.frame = titleRect; 251 | break; 252 | } 253 | } 254 | } 255 | 256 | #pragma mark - UIInputViewAudioFeedback delegate 257 | - (BOOL) enableInputClicksWhenVisible 258 | { 259 | return YES; 260 | } 261 | 262 | @end 263 | -------------------------------------------------------------------------------- /LocaShopCar/ShopCarController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ShopCarController.m 3 | // LocaShopCar 4 | // 5 | // Created by xhl on 16/7/17. 6 | // Copyright © 2016年 xhl. All rights reserved. 7 | // 8 | 9 | #import "ShopCarController.h" 10 | #import "MJExtension.h" 11 | #import "ShopCarModel.h" 12 | #import "GoodsCell.h" 13 | #import "LTDBShopCar.h" 14 | #import "ShopCarGruopModel.h" 15 | #import "ShopCarHeaderView.h" 16 | 17 | @interface ShopCarController () 18 | @property (weak, nonatomic) IBOutlet UITableView *tableView; 19 | @property (weak, nonatomic) IBOutlet UIButton *buttomChooseBt; 20 | @property (strong,nonatomic) NSMutableArray * cellDatas; 21 | @property (weak, nonatomic) IBOutlet UILabel *numberLbl; 22 | @property (weak, nonatomic) IBOutlet UILabel *totalPriceLbl; 23 | 24 | @end 25 | 26 | @implementation ShopCarController 27 | 28 | - (void)viewDidLoad { 29 | [super viewDidLoad]; 30 | // Do any additional setup after loading the view. 31 | } 32 | 33 | - (void)viewWillAppear:(BOOL)animated 34 | { 35 | [super viewWillAppear:animated]; 36 | 37 | [self allIsSelect]; 38 | [self.tableView reloadData]; 39 | [self settingTotalPrice]; 40 | } 41 | 42 | /** 43 | * 处理选中状态 44 | */ 45 | - (void)allIsSelect 46 | { 47 | //从数据库获取数据 48 | NSArray * arr = [[LTDBShopCar shareInstance] getShopCarModel]; 49 | 50 | 51 | [arr enumerateObjectsUsingBlock:^(ShopCarGruopModel * groupModel, NSUInteger idx, BOOL * _Nonnull stop) { 52 | 53 | // 54 | if (self.cellDatas.count > idx) { 55 | 56 | ShopCarGruopModel * localModel = self.cellDatas[idx]; 57 | 58 | groupModel.select = localModel.select; 59 | 60 | [groupModel.goods enumerateObjectsUsingBlock:^(ShopCarModel * carObj, NSUInteger idx, BOOL * _Nonnull stop) { 61 | 62 | if (localModel.goods.count > idx) { 63 | 64 | ShopCarModel * model = localModel.goods[idx]; 65 | carObj.select = model.select; 66 | } 67 | 68 | }]; 69 | } 70 | 71 | }]; 72 | 73 | //每次将要进入前清除数据,判断选中状态之后清除 74 | [self.cellDatas removeAllObjects]; 75 | //添加 76 | [self.cellDatas addObjectsFromArray:arr]; 77 | 78 | } 79 | 80 | //懒加载 81 | - (NSMutableArray *)cellDatas 82 | { 83 | if (!_cellDatas) { 84 | _cellDatas = [NSMutableArray array]; 85 | } 86 | 87 | return _cellDatas; 88 | } 89 | 90 | - (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 91 | { 92 | __weak typeof(self) weakSelf = self; 93 | ShopCarGruopModel *groupModel = self.cellDatas[section]; 94 | ShopCarHeaderView * headerView = [ShopCarHeaderView backHeaderViewWithTableView:tableView]; 95 | [headerView headerViewDataWtihModel:groupModel]; 96 | headerView.callBack = ^(){ 97 | [weakSelf reloadTableViewWithSection:section]; 98 | }; 99 | 100 | return headerView; 101 | } 102 | 103 | - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section 104 | { 105 | return 0.001; 106 | } 107 | 108 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 109 | { 110 | return 40; 111 | } 112 | 113 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 114 | { 115 | return self.cellDatas.count; 116 | } 117 | 118 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 119 | { 120 | return 90; 121 | } 122 | 123 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 124 | { 125 | ShopCarGruopModel *groupModel = self.cellDatas[section]; 126 | return groupModel.goods.count; 127 | } 128 | 129 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 130 | { 131 | ShopCarGruopModel *groupModel = self.cellDatas[indexPath.section]; 132 | GoodsCell * cell = [tableView dequeueReusableCellWithIdentifier:@"ShopCarCell"]; 133 | cell.cellType = ShopCarCellType; 134 | [cell cellDataWithModel:indexPath andGroupModel:groupModel]; 135 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 136 | __weak typeof(self) weakSelf = self; 137 | cell.deleteBlock = ^(){ 138 | [weakSelf dealDeleteResult:indexPath]; 139 | }; 140 | cell.callBlock = ^(){ 141 | [weakSelf reloadTableViewWithSection:indexPath.section]; 142 | }; 143 | 144 | return cell; 145 | } 146 | 147 | - (void)reloadTableViewWithSection:(NSInteger)section 148 | { 149 | [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationFade]; 150 | [self settingTotalPrice]; 151 | } 152 | 153 | - (IBAction)buttomTotalPrice:(id)sender { 154 | 155 | BOOL isSelect = ![[[self buttomInfo] valueForKey:@"isSelect"] boolValue]; 156 | [self.cellDatas enumerateObjectsUsingBlock:^(ShopCarGruopModel * obj, NSUInteger idx, BOOL * _Nonnull stop) { 157 | obj.select = isSelect; 158 | [obj.goods enumerateObjectsUsingBlock:^(ShopCarModel * carObj, NSUInteger idx, BOOL * _Nonnull stop) { 159 | carObj.select = isSelect; 160 | }]; 161 | }]; 162 | [self settingTotalPrice]; 163 | [self.tableView reloadData]; 164 | } 165 | 166 | //是否全选,选中商品的总价,选中商品的数量 167 | - (NSDictionary *)buttomInfo 168 | { 169 | __block BOOL isSelect = NO; 170 | __block double allPrice = 0.00; 171 | __block int selectCOunt = 0; 172 | [self.cellDatas enumerateObjectsUsingBlock:^(ShopCarGruopModel * obj, NSUInteger idx, BOOL * _Nonnull stop) { 173 | 174 | [obj.goods enumerateObjectsUsingBlock:^(ShopCarModel * carModel, NSUInteger idx, BOOL * _Nonnull stop) { 175 | if (carModel.isSelect == YES) { 176 | allPrice += carModel.price * carModel.goodsSelectCount; 177 | selectCOunt += carModel.goodsSelectCount; 178 | } 179 | }]; 180 | 181 | if (obj.select == NO) {//如果为当前有商品未被选中,跳出循环 182 | isSelect = NO; 183 | *stop = YES; 184 | }else if (idx == (self.cellDatas.count -1 )){ 185 | isSelect = YES; 186 | } 187 | 188 | 189 | }]; 190 | NSDictionary * buttomInfo = @{@"allPrice":@(allPrice), 191 | @"selectCOunt":@(selectCOunt), 192 | @"isSelect":@(isSelect)}; 193 | return buttomInfo; 194 | } 195 | 196 | /** 197 | * 设置底部总价信息 198 | */ 199 | - (void)settingTotalPrice 200 | { 201 | //设置图片 202 | UIImage * selectImg = [[[self buttomInfo] valueForKey:@"isSelect"] boolValue]? [UIImage imageNamed:@"tm_mcart_checked"] : [UIImage imageNamed:@"tm_mcart_unchecked"]; 203 | [self.buttomChooseBt setImage:selectImg forState:UIControlStateNormal]; 204 | 205 | //设置购买数量 206 | int count = [[[self buttomInfo] objectForKey:@"selectCOunt"] intValue]; 207 | self.numberLbl.text = [NSString stringWithFormat:@"数量: %d",count]; 208 | 209 | //设置总价 210 | double allPrice = [[[self buttomInfo] objectForKey:@"allPrice"] doubleValue]; 211 | self.totalPriceLbl.text = [NSString stringWithFormat:@"总价: %.2f",allPrice]; 212 | 213 | } 214 | 215 | //删除购物车数据 216 | - (void)dealDeleteResult:(NSIndexPath *)indexPath 217 | { 218 | UIAlertController * alertVc = [UIAlertController alertControllerWithTitle:@"提示" message:@"是否删除" preferredStyle:UIAlertControllerStyleAlert]; 219 | UIAlertAction * leftAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { 220 | 221 | }]; 222 | UIAlertAction * rightAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 223 | 224 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ 225 | ShopCarGruopModel *groupModel = self.cellDatas[indexPath.section]; 226 | [[LTDBShopCar shareInstance] deleteShopCarModel:groupModel.goods[indexPath.row]]; 227 | 228 | dispatch_async(dispatch_get_main_queue(), ^{ 229 | [groupModel.goods removeObjectAtIndex:indexPath.row]; 230 | 231 | if (groupModel.goods.count == 0) { 232 | [self.cellDatas removeObjectAtIndex:indexPath.section]; 233 | [self.tableView reloadData]; 234 | }else{ 235 | [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade]; 236 | } 237 | 238 | [self settingTotalPrice]; 239 | 240 | 241 | }); 242 | 243 | }); 244 | }]; 245 | [alertVc addAction:leftAction]; 246 | [alertVc addAction:rightAction]; 247 | [self presentViewController:alertVc animated:YES completion:nil]; 248 | 249 | } 250 | 251 | @end 252 | --------------------------------------------------------------------------------