├── .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 |
--------------------------------------------------------------------------------