├── .DS_Store
├── HBDrawViewDemo.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── wuhongbin.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ ├── dev.xcuserdatad
│ └── xcschemes
│ │ └── HBDrawViewDemo.xcscheme
│ └── wuhongbin.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ ├── HBDrawViewDemo.xcscheme
│ └── xcschememanagement.plist
├── HBDrawViewDemo
├── .DS_Store
├── AppDelegate.h
├── AppDelegate.m
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ ├── baocun.imageset
│ │ ├── Contents.json
│ │ ├── baocun@2x.png
│ │ └── baocun@3x.png
│ ├── bi.imageset
│ │ ├── Contents.json
│ │ ├── bi@2x.PNG
│ │ └── bi@3x.PNG
│ ├── chexiao.imageset
│ │ ├── Contents.json
│ │ ├── chexiao@2x.png
│ │ └── chexiao@3x.png
│ ├── gou.imageset
│ │ ├── Contents.json
│ │ ├── gou@2x.png
│ │ └── gou@3x.png
│ ├── huaban_1.imageset
│ │ ├── Contents.json
│ │ └── huaban_1.png
│ ├── huaban_2.imageset
│ │ ├── Contents.json
│ │ └── huaban_2.png
│ ├── huaban_3.imageset
│ │ ├── Contents.json
│ │ └── huaban_3.png
│ ├── jieting.imageset
│ │ ├── Contents.json
│ │ ├── jieting@2x.png
│ │ └── jieting@3x.png
│ ├── jieting_pre.imageset
│ │ ├── Contents.json
│ │ ├── jieting_pre@2x.png
│ │ └── jieting_pre@3x.png
│ ├── jingyin.imageset
│ │ ├── Contents.json
│ │ ├── jingyin@2x.PNG
│ │ └── jingyin@3x.PNG
│ ├── jujue.imageset
│ │ ├── Contents.json
│ │ ├── jujue@2x.png
│ │ └── jujue@3x.png
│ ├── jujue_pre.imageset
│ │ ├── Contents.json
│ │ ├── jujue_pre@2x.png
│ │ └── jujue_pre@3x.png
│ ├── mai_zhengchang.imageset
│ │ ├── Contents.json
│ │ ├── mai_zhengchang@2x.PNG
│ │ └── mai_zhengchang@3x.PNG
│ ├── paizhao.imageset
│ │ ├── Contents.json
│ │ ├── paizhao@2x.png
│ │ └── paizhao@3x.png
│ ├── qianjin.imageset
│ │ ├── Contents.json
│ │ ├── qianjin@2x.png
│ │ └── qianjin@3x.png
│ ├── shanchu.imageset
│ │ ├── Contents.json
│ │ ├── shanchu@2x.png
│ │ └── shanchu@3x.png
│ ├── shipin.imageset
│ │ ├── Contents.json
│ │ ├── shipin@2x.png
│ │ └── shipin@3x.png
│ ├── tingtong.imageset
│ │ ├── Contents.json
│ │ ├── tingtong@2x.png
│ │ └── tingtong@3x.png
│ ├── tupian.imageset
│ │ ├── Contents.json
│ │ ├── tupian@2x.png
│ │ └── tupian@3x.png
│ ├── tuya.imageset
│ │ ├── Contents.json
│ │ ├── tuya@2x.png
│ │ └── tuya@3x.png
│ ├── tuya_pre.imageset
│ │ ├── Contents.json
│ │ ├── tuya_pre@2x.png
│ │ └── tuya_pre@3x.png
│ ├── user_music_rect.imageset
│ │ ├── Contents.json
│ │ ├── user_music_rect@2x.png
│ │ └── user_music_rect@3x.png
│ ├── waifang.imageset
│ │ ├── Contents.json
│ │ ├── waifang@2x.PNG
│ │ └── waifang@3x.PNG
│ ├── xiangce.imageset
│ │ ├── Contents.json
│ │ ├── xiangce@2x.png
│ │ └── xiangce@3x.png
│ ├── xiangpica.imageset
│ │ ├── Contents.json
│ │ ├── xiangpica@2x.png
│ │ └── xiangpica@3x.png
│ └── yuyinmoshi.imageset
│ │ ├── Contents.json
│ │ ├── yuyinmoshi@2x.png
│ │ └── yuyinmoshi@3x.png
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── DrawingBoard
│ ├── .DS_Store
│ ├── Model
│ │ ├── HBBallColorModel.h
│ │ ├── HBBallColorModel.m
│ │ ├── HBDrawModel.h
│ │ ├── HBDrawModel.m
│ │ ├── HBDrawPoint.h
│ │ └── HBDrawPoint.m
│ ├── Tool
│ │ ├── HBDrawCommon.h
│ │ ├── HBDrawCommon.m
│ │ ├── NSFileManager+Helper.h
│ │ ├── NSFileManager+Helper.m
│ │ ├── UIColor+help.h
│ │ ├── UIColor+help.m
│ │ ├── UIView+WHB.h
│ │ ├── UIView+WHB.m
│ │ ├── ZXCustomWindow.h
│ │ └── ZXCustomWindow.m
│ ├── drawBoard
│ │ ├── HBDrawingBoard.h
│ │ └── HBDrawingBoard.m
│ └── drawSettingView
│ │ ├── .DS_Store
│ │ ├── BackImageBoardCollectionViewCell.h
│ │ ├── BackImageBoardCollectionViewCell.m
│ │ ├── BackImageBoardCollectionViewCell.xib
│ │ ├── HBBackImageBoard.h
│ │ ├── HBBackImageBoard.m
│ │ ├── HBDrawSettingBoard.h
│ │ ├── HBDrawSettingBoard.m
│ │ └── HBDrawSettingBoard.xib
├── Info.plist
├── MJExtension
│ ├── .svn
│ │ ├── all-wcprops
│ │ ├── entries
│ │ ├── prop-base
│ │ │ ├── MJExtension.h.svn-base
│ │ │ ├── MJExtensionConst.h.svn-base
│ │ │ ├── MJExtensionConst.m.svn-base
│ │ │ ├── MJFoundation.h.svn-base
│ │ │ ├── MJFoundation.m.svn-base
│ │ │ ├── MJProperty.h.svn-base
│ │ │ ├── MJProperty.m.svn-base
│ │ │ ├── MJPropertyKey.h.svn-base
│ │ │ ├── MJPropertyKey.m.svn-base
│ │ │ ├── MJPropertyType.h.svn-base
│ │ │ ├── MJPropertyType.m.svn-base
│ │ │ ├── NSObject+MJClass.h.svn-base
│ │ │ ├── NSObject+MJClass.m.svn-base
│ │ │ ├── NSObject+MJCoding.h.svn-base
│ │ │ ├── NSObject+MJCoding.m.svn-base
│ │ │ ├── NSObject+MJKeyValue.h.svn-base
│ │ │ ├── NSObject+MJKeyValue.m.svn-base
│ │ │ ├── NSObject+MJProperty.h.svn-base
│ │ │ ├── NSObject+MJProperty.m.svn-base
│ │ │ ├── NSString+MJExtension.h.svn-base
│ │ │ └── NSString+MJExtension.m.svn-base
│ │ └── text-base
│ │ │ ├── MJExtension.h.svn-base
│ │ │ ├── MJExtensionConst.h.svn-base
│ │ │ ├── MJExtensionConst.m.svn-base
│ │ │ ├── MJFoundation.h.svn-base
│ │ │ ├── MJFoundation.m.svn-base
│ │ │ ├── MJProperty.h.svn-base
│ │ │ ├── MJProperty.m.svn-base
│ │ │ ├── MJPropertyKey.h.svn-base
│ │ │ ├── MJPropertyKey.m.svn-base
│ │ │ ├── MJPropertyType.h.svn-base
│ │ │ ├── MJPropertyType.m.svn-base
│ │ │ ├── NSObject+MJClass.h.svn-base
│ │ │ ├── NSObject+MJClass.m.svn-base
│ │ │ ├── NSObject+MJCoding.h.svn-base
│ │ │ ├── NSObject+MJCoding.m.svn-base
│ │ │ ├── NSObject+MJKeyValue.h.svn-base
│ │ │ ├── NSObject+MJKeyValue.m.svn-base
│ │ │ ├── NSObject+MJProperty.h.svn-base
│ │ │ ├── NSObject+MJProperty.m.svn-base
│ │ │ ├── NSString+MJExtension.h.svn-base
│ │ │ └── NSString+MJExtension.m.svn-base
│ ├── MJExtension.h
│ ├── MJExtensionConst.h
│ ├── MJExtensionConst.m
│ ├── MJFoundation.h
│ ├── MJFoundation.m
│ ├── MJProperty.h
│ ├── MJProperty.m
│ ├── MJPropertyKey.h
│ ├── MJPropertyKey.m
│ ├── MJPropertyType.h
│ ├── MJPropertyType.m
│ ├── NSObject+MJClass.h
│ ├── NSObject+MJClass.m
│ ├── NSObject+MJCoding.h
│ ├── NSObject+MJCoding.m
│ ├── NSObject+MJKeyValue.h
│ ├── NSObject+MJKeyValue.m
│ ├── NSObject+MJProperty.h
│ ├── NSObject+MJProperty.m
│ ├── NSString+MJExtension.h
│ └── NSString+MJExtension.m
├── ViewController.h
├── ViewController.m
├── ZYQAssetPickerController.h
├── ZYQAssetPickerController.m
└── main.m
├── HBDrawViewDemoTests
├── HBDrawViewDemoTests.m
└── Info.plist
├── HBDrawViewDemoUITests
├── HBDrawViewDemoUITests.m
└── Info.plist
└── README.md
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/.DS_Store
--------------------------------------------------------------------------------
/HBDrawViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/HBDrawViewDemo.xcodeproj/project.xcworkspace/xcuserdata/wuhongbin.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo.xcodeproj/project.xcworkspace/xcuserdata/wuhongbin.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/HBDrawViewDemo.xcodeproj/xcuserdata/dev.xcuserdatad/xcschemes/HBDrawViewDemo.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
74 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
95 |
101 |
102 |
103 |
104 |
106 |
107 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/HBDrawViewDemo.xcodeproj/xcuserdata/wuhongbin.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/HBDrawViewDemo.xcodeproj/xcuserdata/wuhongbin.xcuserdatad/xcschemes/HBDrawViewDemo.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
74 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
95 |
101 |
102 |
103 |
104 |
106 |
107 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/HBDrawViewDemo.xcodeproj/xcuserdata/wuhongbin.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | HBDrawViewDemo.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 5E1F3FA81BF33C4B00ACE525
16 |
17 | primary
18 |
19 |
20 | 5E1F3FC11BF33C4B00ACE525
21 |
22 | primary
23 |
24 |
25 | 5E1F3FCC1BF33C4B00ACE525
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/.DS_Store
--------------------------------------------------------------------------------
/HBDrawViewDemo/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // HBDrawViewDemo
4 | //
5 | // Created by 伍宏彬 on 15/11/11.
6 | // Copyright © 2015年 伍宏彬. 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 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // HBDrawViewDemo
4 | //
5 | // Created by 伍宏彬 on 15/11/11.
6 | // Copyright © 2015年 伍宏彬. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // 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.
25 | // 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.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // 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.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // 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.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // 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.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | }
88 | ],
89 | "info" : {
90 | "version" : 1,
91 | "author" : "xcode"
92 | }
93 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/baocun.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "baocun@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "baocun@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/baocun.imageset/baocun@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/baocun.imageset/baocun@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/baocun.imageset/baocun@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/baocun.imageset/baocun@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/bi.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "bi@2x.PNG",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "bi@3x.PNG",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/bi.imageset/bi@2x.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/bi.imageset/bi@2x.PNG
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/bi.imageset/bi@3x.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/bi.imageset/bi@3x.PNG
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/chexiao.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "chexiao@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "chexiao@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/chexiao.imageset/chexiao@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/chexiao.imageset/chexiao@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/chexiao.imageset/chexiao@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/chexiao.imageset/chexiao@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/gou.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "gou@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "gou@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/gou.imageset/gou@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/gou.imageset/gou@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/gou.imageset/gou@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/gou.imageset/gou@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/huaban_1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "huaban_1.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/huaban_1.imageset/huaban_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/huaban_1.imageset/huaban_1.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/huaban_2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "huaban_2.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/huaban_2.imageset/huaban_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/huaban_2.imageset/huaban_2.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/huaban_3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "huaban_3.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/huaban_3.imageset/huaban_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/huaban_3.imageset/huaban_3.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/jieting.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "jieting@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "jieting@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/jieting.imageset/jieting@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/jieting.imageset/jieting@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/jieting.imageset/jieting@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/jieting.imageset/jieting@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/jieting_pre.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "jieting_pre@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "jieting_pre@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/jieting_pre.imageset/jieting_pre@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/jieting_pre.imageset/jieting_pre@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/jieting_pre.imageset/jieting_pre@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/jieting_pre.imageset/jieting_pre@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/jingyin.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "jingyin@2x.PNG",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "jingyin@3x.PNG",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/jingyin.imageset/jingyin@2x.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/jingyin.imageset/jingyin@2x.PNG
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/jingyin.imageset/jingyin@3x.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/jingyin.imageset/jingyin@3x.PNG
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/jujue.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "jujue@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "jujue@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/jujue.imageset/jujue@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/jujue.imageset/jujue@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/jujue.imageset/jujue@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/jujue.imageset/jujue@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/jujue_pre.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "jujue_pre@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "jujue_pre@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/jujue_pre.imageset/jujue_pre@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/jujue_pre.imageset/jujue_pre@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/jujue_pre.imageset/jujue_pre@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/jujue_pre.imageset/jujue_pre@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/mai_zhengchang.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "mai_zhengchang@2x.PNG",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "mai_zhengchang@3x.PNG",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/mai_zhengchang.imageset/mai_zhengchang@2x.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/mai_zhengchang.imageset/mai_zhengchang@2x.PNG
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/mai_zhengchang.imageset/mai_zhengchang@3x.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/mai_zhengchang.imageset/mai_zhengchang@3x.PNG
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/paizhao.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "paizhao@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "paizhao@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/paizhao.imageset/paizhao@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/paizhao.imageset/paizhao@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/paizhao.imageset/paizhao@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/paizhao.imageset/paizhao@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/qianjin.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "qianjin@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "qianjin@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/qianjin.imageset/qianjin@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/qianjin.imageset/qianjin@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/qianjin.imageset/qianjin@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/qianjin.imageset/qianjin@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/shanchu.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "shanchu@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "shanchu@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/shanchu.imageset/shanchu@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/shanchu.imageset/shanchu@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/shanchu.imageset/shanchu@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/shanchu.imageset/shanchu@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/shipin.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "shipin@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "shipin@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/shipin.imageset/shipin@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/shipin.imageset/shipin@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/shipin.imageset/shipin@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/shipin.imageset/shipin@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/tingtong.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tingtong@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "tingtong@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/tingtong.imageset/tingtong@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/tingtong.imageset/tingtong@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/tingtong.imageset/tingtong@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/tingtong.imageset/tingtong@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/tupian.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tupian@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "tupian@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/tupian.imageset/tupian@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/tupian.imageset/tupian@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/tupian.imageset/tupian@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/tupian.imageset/tupian@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/tuya.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tuya@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "tuya@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/tuya.imageset/tuya@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/tuya.imageset/tuya@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/tuya.imageset/tuya@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/tuya.imageset/tuya@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/tuya_pre.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "tuya_pre@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "tuya_pre@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/tuya_pre.imageset/tuya_pre@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/tuya_pre.imageset/tuya_pre@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/tuya_pre.imageset/tuya_pre@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/tuya_pre.imageset/tuya_pre@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/user_music_rect.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "user_music_rect@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "user_music_rect@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/user_music_rect.imageset/user_music_rect@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/user_music_rect.imageset/user_music_rect@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/user_music_rect.imageset/user_music_rect@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/user_music_rect.imageset/user_music_rect@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/waifang.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "waifang@2x.PNG",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "waifang@3x.PNG",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/waifang.imageset/waifang@2x.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/waifang.imageset/waifang@2x.PNG
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/waifang.imageset/waifang@3x.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/waifang.imageset/waifang@3x.PNG
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/xiangce.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "xiangce@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "xiangce@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/xiangce.imageset/xiangce@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/xiangce.imageset/xiangce@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/xiangce.imageset/xiangce@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/xiangce.imageset/xiangce@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/xiangpica.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "xiangpica@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "xiangpica@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/xiangpica.imageset/xiangpica@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/xiangpica.imageset/xiangpica@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/xiangpica.imageset/xiangpica@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/xiangpica.imageset/xiangpica@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/yuyinmoshi.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "yuyinmoshi@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "yuyinmoshi@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/yuyinmoshi.imageset/yuyinmoshi@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/yuyinmoshi.imageset/yuyinmoshi@2x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/Assets.xcassets/yuyinmoshi.imageset/yuyinmoshi@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/Assets.xcassets/yuyinmoshi.imageset/yuyinmoshi@3x.png
--------------------------------------------------------------------------------
/HBDrawViewDemo/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 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/Base.lproj/Main.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 |
34 |
44 |
57 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/DrawingBoard/.DS_Store
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/Model/HBBallColorModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // HBBallColorModel.h
3 | // DemoAntiAliasing
4 | //
5 | // Created by 伍宏彬 on 15/11/4.
6 | // Copyright © 2015年 HB. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface HBBallColorModel : NSObject
13 |
14 | @property (nonatomic, assign) BOOL isBallColor;
15 |
16 | @property (nonatomic, strong) NSNumber * ballColor;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/Model/HBBallColorModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // HBBallColorModel.m
3 | // DemoAntiAliasing
4 | //
5 | // Created by 伍宏彬 on 15/11/4.
6 | // Copyright © 2015年 HB. All rights reserved.
7 | //
8 |
9 | #import "HBBallColorModel.h"
10 |
11 | @implementation HBBallColorModel
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/Model/HBDrawModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // HBDrawModel.h
3 | // DemoAntiAliasing
4 | //
5 | // Created by 伍宏彬 on 15/11/9.
6 | // Copyright © 2015年 HB. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | @interface HBDrawModel : NSObject
13 | /*
14 | pointList;
15 | private String paintColor;
16 | private String background;
17 | private int paintSize;
18 | private String action; com.changebackground.doodle com.playing.doodle
19 | public float width;
20 | public float hight;
21 | private String from;
22 | private boolean isEraser=false;
23 | */
24 | @property (nonatomic, strong) NSArray * pointList;
25 | @property (nonatomic, copy) NSString * paintColor;
26 | @property (nonatomic, copy) NSString * background;
27 | @property (nonatomic, copy) NSString * action;
28 | @property (nonatomic, strong) NSNumber * paintSize;
29 | @property (nonatomic, strong) NSNumber * width;
30 | @property (nonatomic, strong) NSNumber * height;
31 | @property (nonatomic, strong) NSNumber * isEraser;
32 | @property (nonatomic, strong) NSNumber * shapType;
33 | @end
34 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/Model/HBDrawModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // HBDrawModel.m
3 | // DemoAntiAliasing
4 | //
5 | // Created by 伍宏彬 on 15/11/9.
6 | // Copyright © 2015年 HB. All rights reserved.
7 | //
8 |
9 | #import "HBDrawModel.h"
10 | #import "HBDrawPoint.h"
11 | #import "MJExtension.h"
12 | #import "HBDrawCommon.h"
13 |
14 |
15 | @implementation HBDrawModel
16 |
17 | - (instancetype)init
18 | {
19 | self = [super init];
20 | if (self) {
21 | self.action = Action_playing;
22 | self.width = @([UIScreen mainScreen].bounds.size.width);
23 | self.height = @([UIScreen mainScreen].bounds.size.height);
24 |
25 | }
26 | return self;
27 | }
28 | + (NSDictionary *)objectClassInArray
29 | {
30 | return @{@"pointList": [HBDrawPoint class]};
31 | }
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/Model/HBDrawPoint.h:
--------------------------------------------------------------------------------
1 | //
2 | // HBDrawPoint.h
3 | // DemoAntiAliasing
4 | //
5 | // Created by 伍宏彬 on 15/11/9.
6 | // Copyright © 2015年 HB. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface HBDrawPoint : NSObject
13 |
14 | + (instancetype)drawPoint:(CGPoint)point;
15 |
16 | @property (nonatomic, strong) NSNumber * x;
17 |
18 | @property (nonatomic, strong) NSNumber * y;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/Model/HBDrawPoint.m:
--------------------------------------------------------------------------------
1 | //
2 | // HBDrawPoint.m
3 | // DemoAntiAliasing
4 | //
5 | // Created by 伍宏彬 on 15/11/9.
6 | // Copyright © 2015年 HB. All rights reserved.
7 | //
8 |
9 | #import "HBDrawPoint.h"
10 |
11 |
12 | @implementation HBDrawPoint
13 | + (instancetype)drawPoint:(CGPoint)point
14 | {
15 | HBDrawPoint *drawPoint = [[HBDrawPoint alloc] init];
16 | drawPoint.x = @(point.x);
17 | drawPoint.y = @(point.y);
18 | return drawPoint;
19 | }
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/Tool/HBDrawCommon.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef __HBDrawCommon__H__
3 | #define __HBDrawCommon__H__
4 |
5 | #import
6 |
7 | UIKIT_EXTERN NSString * const CollectionImageBoardViewID;
8 | UIKIT_EXTERN NSString * const ImageBoardNotification;
9 | UIKIT_EXTERN NSString * const SendColorAndWidthNotification;
10 |
11 | /**改变背景**/
12 | UIKIT_EXTERN NSString * const Action_changebackground;
13 | /**画**/
14 | UIKIT_EXTERN NSString * const Action_playing;
15 | /**回退**/
16 | UIKIT_EXTERN NSString * const Action_return;
17 | /**向前**/
18 | UIKIT_EXTERN NSString * const Action_goforward;
19 | /**清屏**/
20 | UIKIT_EXTERN NSString * const Action_clearAll;
21 |
22 | #endif
23 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/Tool/HBDrawCommon.m:
--------------------------------------------------------------------------------
1 |
2 | #ifndef __HBDrawCommon__M__
3 | #define __HBDrawCommon__M__
4 |
5 | #import
6 |
7 | NSString * const CollectionImageBoardViewID = @"CollectionImageBoardViewID";
8 | NSString * const ImageBoardNotification = @"ImageBoardNotification";
9 | NSString * const Action_changebackground = @"com.changebackground.doodle";
10 | NSString * const Action_playing = @"com.playing.doodle";
11 | NSString * const SendColorAndWidthNotification = @"SendColorAndWidthNotification";
12 | NSString * const Action_return = @"com.return.doodle";
13 | NSString * const Action_goforward = @"com.goforward.doodle";
14 | NSString * const Action_clearAll = @"com.clearAll.doodle";
15 |
16 | #endif
17 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/Tool/NSFileManager+Helper.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSFileManager_Helper.h
3 | // FirstVideo
4 | //
5 | // Created by doorxp1 on 14-7-9.
6 | // Copyright (c) 2014年 doorxp1. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface NSFileManager(Helper)
13 |
14 | /**
15 | * 检测指定全路径的文件是否存在
16 | *
17 | * @param path 文件的全路径
18 | * @return BOOL 存在还回YES,否则返回NO
19 | */
20 | + (BOOL)fileExist:(NSString *)path;
21 |
22 | /**
23 | * 检测指定全路径的目录是否存在
24 | *
25 | * @param path 目录的全路径
26 | * @return BOOL 存在还回YES,否则返回NO
27 | */
28 | + (BOOL)dirExist:(NSString *)path;
29 |
30 | /**
31 | * 创建目录
32 | *
33 | * @param path 指定目录路径
34 | * @return BOOL 成功返回YES
35 | */
36 | + (BOOL)mkDir:(NSString *)path;
37 |
38 | /**
39 | * 移动指定路径的文件到另一个路径
40 | *
41 | * @param from 移动源路径
42 | * @param to 移动目标路径
43 | * @return BOOl 成功返回YES
44 | */
45 | + (BOOL)move:(NSString *)from to:(NSString *)to;
46 |
47 | /**
48 | * 复制指定路径的文件到另一个路径
49 | *
50 | * @param from 复制源路径
51 | * @param to 复制目标路径
52 | * @return BOOl 成功返回YES
53 | */
54 | + (BOOL)copy:(NSString *)from to:(NSString *)to;
55 |
56 | /**
57 | * 删除指定文件
58 | *
59 | * @param path 指定待删除文件路径
60 | * @return BOOL 成功返回YES
61 | */
62 | + (BOOL)deleteFile:(NSString*)path;
63 |
64 | /**
65 | 保存文件到制定目录
66 |
67 | @param data 文件二进制
68 | @param filePath 文件路径
69 | @return 是否保存成功
70 | */
71 | + (BOOL)hb_saveData:(NSData *)data filePath:(NSString *)filePath;
72 |
73 | /**
74 | 获取文件二进制
75 |
76 | @param filePath 文件路径
77 | @return 二进制
78 | */
79 | + (UIImage *)hb_getImageFileName:(NSString *)filePath;
80 | @end
81 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/Tool/NSFileManager+Helper.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSFileManager_Helper.m
3 | // FirstVideo
4 | //
5 | // Created by doorxp1 on 14-7-9.
6 | // Copyright (c) 2014年 doorxp1. All rights reserved.
7 | //
8 |
9 | #import "NSFileManager+Helper.h"
10 |
11 | @implementation NSFileManager(Helper)
12 | + (BOOL)fileExist:(NSString *)path
13 | {
14 | if(path == nil)
15 | {
16 | return NO;
17 | }
18 |
19 | return [[NSFileManager defaultManager] fileExistsAtPath:path];
20 | }
21 |
22 | + (BOOL)dirExist:(NSString *)path
23 | {
24 | BOOL isDirecotry = NO;
25 | if (![[NSFileManager defaultManager] fileExistsAtPath:path
26 | isDirectory:&isDirecotry]
27 | || !isDirecotry)
28 | {
29 | isDirecotry = NO;
30 | }
31 |
32 | return isDirecotry;
33 | }
34 |
35 | + (BOOL)mkDir:(NSString *)path
36 | {
37 | BOOL isSecc = YES;
38 | NSError *erro = nil;
39 | if (![NSFileManager dirExist:path])
40 | {
41 | if(![[NSFileManager defaultManager] createDirectoryAtPath:path
42 | withIntermediateDirectories:YES
43 | attributes:nil
44 | error:&erro]
45 | || erro != nil)
46 | {
47 | NSAssert(0, @"文件夹创建失败!");
48 | isSecc = NO;
49 | }
50 | }
51 |
52 | return isSecc;
53 | }
54 |
55 |
56 | + (BOOL)copy:(NSString *)from to:(NSString *)to
57 | {
58 | NSError *error = nil;
59 | BOOL bRet = [[NSFileManager defaultManager] copyItemAtPath:from toPath:to error:&error];
60 | if (error)
61 | NSLog(@"%@",error);
62 | return bRet;
63 | }
64 |
65 | + (BOOL)move:(NSString *)from to:(NSString *)to
66 | {
67 | NSError *error = nil;
68 | BOOL bRet = [[NSFileManager defaultManager] moveItemAtPath:from toPath:to error:&error];
69 | if (error)
70 | NSLog(@"%@",error);
71 | return bRet;
72 | }
73 |
74 | + (BOOL)deleteFile:(NSString*)path
75 | {
76 | NSError *error = nil;
77 | BOOL bRet = [[NSFileManager defaultManager] removeItemAtPath:path error:&error];
78 | if (error) {
79 | NSLog(@"%@",error);
80 | }
81 | return bRet;
82 | }
83 | + (BOOL)hb_saveData:(NSData *)data filePath:(NSString *)filePath{
84 |
85 | if (![NSFileManager mkDir:[filePath stringByDeletingLastPathComponent]]) {
86 |
87 | NSAssert(0, @"路径不存在");
88 | return NO;
89 | }
90 |
91 | return [data writeToFile:filePath atomically:YES];
92 | }
93 |
94 | + (UIImage *)hb_getImageFileName:(NSString *)filePath{
95 |
96 | if (![NSFileManager fileExist:filePath]) {
97 |
98 | NSAssert(0, @"路径不存在");
99 | return nil;
100 | }
101 | return [UIImage imageWithContentsOfFile:filePath];
102 | }
103 | @end
104 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/Tool/UIColor+help.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+help.h
3 | // DemoAntiAliasing
4 | //
5 | // Created by 伍宏彬 on 15/11/9.
6 | // Copyright © 2015年 HB. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIColor (help)
12 |
13 | + (UIColor *)colorWithHexString:(NSString *)color;
14 |
15 | //从十六进制字符串获取颜色,
16 | //color:支持@“#123456”、 @“0X123456”、 @“123456”三种格式
17 | + (UIColor *)colorWithHexString:(NSString *)color alpha:(CGFloat)alpha;
18 |
19 | - (NSString *)toColorString;
20 |
21 | @end
22 |
23 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/Tool/UIColor+help.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+help.m
3 | // DemoAntiAliasing
4 | //
5 | // Created by 伍宏彬 on 15/11/9.
6 | // Copyright © 2015年 HB. All rights reserved.
7 | //
8 |
9 | #import "UIColor+help.h"
10 |
11 | @implementation UIColor (help)
12 |
13 | + (UIColor *)colorWithHexString:(NSString *)color alpha:(CGFloat)alpha
14 | {
15 | //删除字符串中的空格
16 | NSString *cString = [[color stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
17 | // String should be 6 or 8 characters
18 | if ([cString length] < 6)
19 | {
20 | return [UIColor clearColor];
21 | }
22 | // strip 0X if it appears
23 | //如果是0x开头的,那么截取字符串,字符串从索引为2的位置开始,一直到末尾
24 | if ([cString hasPrefix:@"0X"])
25 | {
26 | cString = [cString substringFromIndex:2];
27 | }
28 | //如果是#开头的,那么截取字符串,字符串从索引为1的位置开始,一直到末尾
29 | if ([cString hasPrefix:@"#"])
30 | {
31 | cString = [cString substringFromIndex:1];
32 | }
33 | if ([cString length] != 6)
34 | {
35 | return [UIColor clearColor];
36 | }
37 |
38 | // Separate into r, g, b substrings
39 | NSRange range;
40 | range.location = 0;
41 | range.length = 2;
42 | //r
43 | NSString *rString = [cString substringWithRange:range];
44 | //g
45 | range.location = 2;
46 | NSString *gString = [cString substringWithRange:range];
47 | //b
48 | range.location = 4;
49 | NSString *bString = [cString substringWithRange:range];
50 |
51 | // Scan values
52 | unsigned int r, g, b;
53 | [[NSScanner scannerWithString:rString] scanHexInt:&r];
54 | [[NSScanner scannerWithString:gString] scanHexInt:&g];
55 | [[NSScanner scannerWithString:bString] scanHexInt:&b];
56 | return [UIColor colorWithRed:((float)r / 255.0f) green:((float)g / 255.0f) blue:((float)b / 255.0f) alpha:alpha];
57 | }
58 |
59 | //默认alpha值为1
60 | + (UIColor *)colorWithHexString:(NSString *)color
61 | {
62 | return [self colorWithHexString:color alpha:1.0f];
63 | }
64 |
65 | - (NSString *)toColorString
66 | {
67 | const CGFloat *cs=CGColorGetComponents(self.CGColor);
68 | NSString *r = [NSString stringWithFormat:@"%@",[self ToHex:cs[0]*255]];
69 | NSString *g = [NSString stringWithFormat:@"%@",[self ToHex:cs[1]*255]];
70 | NSString *b = [NSString stringWithFormat:@"%@",[self ToHex:cs[2]*255]];
71 | return [NSString stringWithFormat:@"#%@%@%@",r,g,b];
72 | }
73 | //十进制转十六进制
74 | -(NSString *)ToHex:(int)tmpid
75 | {
76 | NSString *endtmp=@"";
77 | NSString *nLetterValue;
78 | NSString *nStrat;
79 | int ttmpig=tmpid%16;
80 | int tmp=tmpid/16;
81 | switch (ttmpig)
82 | {
83 | case 10:
84 | nLetterValue =@"A";break;
85 | case 11:
86 | nLetterValue =@"B";break;
87 | case 12:
88 | nLetterValue =@"C";break;
89 | case 13:
90 | nLetterValue =@"D";break;
91 | case 14:
92 | nLetterValue =@"E";break;
93 | case 15:
94 | nLetterValue =@"F";break;
95 | default:nLetterValue=[[NSString alloc]initWithFormat:@"%i",ttmpig];
96 |
97 | }
98 | switch (tmp)
99 | {
100 | case 10:
101 | nStrat =@"A";break;
102 | case 11:
103 | nStrat =@"B";break;
104 | case 12:
105 | nStrat =@"C";break;
106 | case 13:
107 | nStrat =@"D";break;
108 | case 14:
109 | nStrat =@"E";break;
110 | case 15:
111 | nStrat =@"F";break;
112 | default:nStrat=[[NSString alloc]initWithFormat:@"%i",tmp];
113 |
114 | }
115 | endtmp=[[NSString alloc]initWithFormat:@"%@%@",nStrat,nLetterValue];
116 | return endtmp;
117 | }
118 | @end
119 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/Tool/UIView+WHB.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+WHB.h
3 | // zhaopianbaocunfree
4 | //
5 | // Created by WHB on 14-11-12.
6 | // Copyright (c) 2014年 WHB. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIView (WHB)
12 | // 只会生成方法的声明, 不会生成方法的实现和成员变量
13 | @property(nonatomic,assign) CGFloat x;
14 | @property(nonatomic,assign) CGFloat y;
15 |
16 |
17 | @property(nonatomic,assign) CGFloat width;
18 | @property(nonatomic,assign) CGFloat height;
19 |
20 | @property(nonatomic,assign) CGFloat centerX;
21 | @property(nonatomic,assign) CGFloat centerY;
22 |
23 | @property(nonatomic,assign) CGSize size;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/Tool/UIView+WHB.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+WHB.m
3 | // zhaopianbaocunfree
4 | //
5 | // Created by WHB on 14-11-12.
6 | // Copyright (c) 2014年 WHB. All rights reserved.
7 | //
8 |
9 | #import "UIView+WHB.h"
10 |
11 | @implementation UIView (WHB)
12 |
13 |
14 | - (void)setSize:(CGSize)size
15 | {
16 | CGRect frame = self.frame;
17 | frame.size = size;
18 | self.frame = frame;
19 | }
20 |
21 | - (CGSize)size
22 | {
23 | return self.frame.size;
24 | }
25 |
26 | - (void)setX:(CGFloat)x
27 | {
28 | CGRect frame = self.frame;
29 | frame.origin.x = x;
30 | self.frame = frame;
31 | }
32 |
33 | - (CGFloat)x
34 | {
35 | return self.frame.origin.x;
36 | }
37 |
38 | - (void)setY:(CGFloat)y
39 | {
40 | CGRect frame = self.frame;
41 | frame.origin.y = y;
42 | self.frame = frame;
43 | }
44 |
45 | - (CGFloat)y
46 | {
47 | return self.frame.origin.y;
48 | }
49 |
50 | - (void)setWidth:(CGFloat)width
51 | {
52 | CGRect frame = self.frame;
53 | frame.size.width = width;
54 | self.frame = frame;
55 | }
56 |
57 | - (CGFloat)width
58 | {
59 | return self.frame.size.width;
60 | }
61 |
62 | - (void)setHeight:(CGFloat)height
63 | {
64 | CGRect frame = self.frame;
65 | frame.size.height = height;
66 | self.frame = frame;
67 | }
68 |
69 | - (CGFloat)height
70 | {
71 | return self.frame.size.height;
72 | }
73 |
74 | - (void)setCenterX:(CGFloat)centerX
75 | {
76 | CGPoint center = self.center;
77 | center.x = centerX;
78 | self.center = center;
79 | }
80 |
81 | - (CGFloat)centerX
82 | {
83 | return self.center.x;
84 | }
85 |
86 | - (void)setCenterY:(CGFloat)centerY
87 | {
88 | CGPoint center = self.center;
89 | center.y = centerY;
90 | self.center = center;
91 | }
92 |
93 | - (CGFloat)centerY
94 | {
95 | return self.center.y;
96 | }
97 |
98 | @end
99 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/Tool/ZXCustomWindow.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZXCustomWindow.h
3 | // MosterColock
4 | //
5 | // Created by wuhongbin on 15/6/25.
6 | // Copyright (c) 2015年 wuhongbin. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ZXCustomWindow : UIWindow
12 |
13 | - (instancetype)initWithAnimationView:(UIView *)animationView;
14 |
15 | @property (nonatomic, assign) NSTimeInterval animationTime;
16 |
17 | - (void)showWithAnimationTime:(NSTimeInterval)second;
18 |
19 | - (void)hideWithAnimationTime:(NSTimeInterval)second;
20 |
21 |
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/Tool/ZXCustomWindow.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZXCustomWindow.m
3 | // MosterColock
4 | //
5 | // Created by wuhongbin on 15/6/25.
6 | // Copyright (c) 2015年 wuhongbin. All rights reserved.
7 | //
8 |
9 | #import "ZXCustomWindow.h"
10 |
11 |
12 | @interface ZXCustomWindow()
13 |
14 | @property (nonatomic, weak) UIView *animationView;
15 |
16 | @end
17 |
18 | @implementation ZXCustomWindow
19 |
20 | - (instancetype)initWithAnimationView:(UIView *)animationView
21 | {
22 | if (self = [super initWithFrame:[[UIScreen mainScreen] bounds]]) {
23 |
24 | self.windowLevel = UIWindowLevelAlert;
25 |
26 | self.animationView = animationView;
27 |
28 | [self addSubview:self.animationView];
29 |
30 | [[NSNotificationCenter defaultCenter] addObserverForName:@"hideTopWindow" object:nil queue:nil usingBlock:^(NSNotification *note) {
31 |
32 | [self hideWithAnimationTime:self.animationTime];
33 |
34 | }];
35 |
36 | }
37 | return self;
38 |
39 | }
40 |
41 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
42 | {
43 | CGPoint touchPoint = [[touches anyObject] locationInView:self];
44 |
45 | if (!CGRectContainsPoint(self.animationView.frame, touchPoint))
46 | [self hideWithAnimationTime:self.animationTime];
47 |
48 | // for (UIView *view in self.subviews) {
49 | //// if ([view isKindOfClass:[giftInfoView class]] || [view isKindOfClass:[putView class]]) {
50 | // [self hideWithAnimationTime:self.animationTime];
51 | //// }
52 | // }
53 | }
54 |
55 | - (void)showWithAnimationTime:(NSTimeInterval)second
56 | {
57 | self.animationTime = second;
58 | [self makeKeyAndVisible];
59 |
60 | // if (!self.hidden) return;
61 | [UIView animateWithDuration:self.animationTime delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
62 |
63 |
64 | [UIView animateWithDuration:0.1 animations:^{
65 |
66 | self.animationView.transform = CGAffineTransformMakeTranslation(0, -self.animationView.bounds.size.height);
67 |
68 | }];
69 |
70 |
71 | } completion:^(BOOL finished) {
72 |
73 |
74 | self.hidden = NO;
75 |
76 | }];
77 |
78 | }
79 |
80 | - (void)hideWithAnimationTime:(NSTimeInterval)second
81 | {
82 | self.animationTime = second;
83 | // if (self.hidden) return;
84 |
85 | [UIView animateWithDuration:self.animationTime delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
86 |
87 | [UIView animateWithDuration:0.1 animations:^{
88 |
89 | self.animationView.transform = CGAffineTransformIdentity;
90 |
91 | } completion:^(BOOL finished) {
92 |
93 | self.hidden = YES;
94 | // whblog(@"隐藏");
95 |
96 | }];
97 |
98 | } completion:^(BOOL finished) {
99 |
100 |
101 | // self.hidden = YES;
102 | //// whblog(@"隐藏");
103 |
104 | }];
105 |
106 | }
107 | #pragma mark - delloc
108 | - (void)dealloc
109 | {
110 | [[NSNotificationCenter defaultCenter] removeObserver:self name:@"hideTopWindow" object:nil];
111 | }
112 |
113 | @end
114 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/drawBoard/HBDrawingBoard.h:
--------------------------------------------------------------------------------
1 | //
2 | // HBDrawingBoard.h
3 | // DemoAntiAliasing
4 | //
5 | // Created by 伍宏彬 on 15/11/2.
6 | // Copyright (c) 2015年 HB. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "HBDrawModel.h"
11 |
12 | typedef NS_ENUM(NSInteger, HBDrawingStatus)
13 | {
14 | HBDrawingStatusBegin,//准备绘制
15 | HBDrawingStatusMove,//正在绘制
16 | HBDrawingStatusEnd//结束绘制
17 |
18 | };
19 |
20 | typedef NS_ENUM(NSInteger, HBDrawingShapeType)
21 | {
22 | HBDrawingShapeCurve = 0,//曲线
23 | HBDrawingShapeLine,//直线
24 | HBDrawingShapeEllipse,//椭圆
25 | HBDrawingShapeRect,//矩形
26 |
27 | };
28 | typedef NS_ENUM(NSInteger, actionOpen) {
29 | actionOpenAlbum,
30 | actionOpenCamera
31 | };
32 |
33 |
34 |
35 |
36 | @class HBDrawingBoard;
37 |
38 | @protocol HBDrawingBoardDelegate
39 |
40 | - (void)drawBoard:(HBDrawingBoard *)drawView action:(actionOpen)action;
41 | - (void)drawBoard:(HBDrawingBoard *)drawView drawingStatus:(HBDrawingStatus)drawingStatus model:(HBDrawModel *)model;
42 |
43 | @end
44 |
45 | @interface HBDrawingBoard : UIView
46 |
47 | @property (nonatomic, assign) BOOL ise;
48 |
49 | @property (nonatomic, assign) HBDrawingShapeType shapType;
50 |
51 | @property (nonatomic, strong) UIImageView *backImage;
52 |
53 | @property (nonatomic, weak) id delegate;
54 | /**
55 | * 根据点的集合绘制
56 | *
57 | * @param points ["{x,y}"...]
58 | * @param lineColor 颜色
59 | * @param lineWidth 线宽
60 | *
61 | * @return YES -> 绘制完成 反之
62 | */
63 | - (BOOL)drawWithPoints:(HBDrawModel *)model;
64 | - (void)showSettingBoard;
65 | - (void)hideSettingBoard;
66 |
67 | + (HBDrawModel *)objectWith:(NSDictionary *)dic;
68 | @end
69 |
70 | #pragma mark - HBPath
71 | @interface HBPath : NSObject
72 |
73 | @property (nonatomic, strong) UIColor *pathColor;//画笔颜色
74 | @property (nonatomic, assign) CGFloat lineWidth;//线宽
75 | @property (nonatomic, assign) BOOL isEraser;//橡皮擦
76 | @property (nonatomic, assign) HBDrawingShapeType shapType;//绘制样式
77 | @property (nonatomic, copy) NSString *imagePath;//图片路径
78 | @property (nonatomic, strong) UIBezierPath *bezierPath;
79 |
80 |
81 | + (instancetype)pathToPoint:(CGPoint)beginPoint pathWidth:(CGFloat)pathWidth isEraser:(BOOL)isEraser;//初始化对象
82 | - (void)pathLineToPoint:(CGPoint)movePoint WithType:(HBDrawingShapeType)shapeType;//画
83 |
84 | @end
85 |
86 | @interface HBDrawView : UIView
87 |
88 | - (void)setBrush:(HBPath *)path;
89 |
90 | @end
91 |
92 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/drawSettingView/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WillieWu/HBDrawingBoardDemo/d7a07e733f3f0912eb1ed7ead95dca749085e4a5/HBDrawViewDemo/DrawingBoard/drawSettingView/.DS_Store
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/drawSettingView/BackImageBoardCollectionViewCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // BackImageBoardCollectionViewCell.h
3 | // DemoAntiAliasing
4 | //
5 | // Created by 伍宏彬 on 15/11/6.
6 | // Copyright © 2015年 HB. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface BackImageBoardCollectionViewCell : UICollectionViewCell
12 |
13 | @property (weak, nonatomic) IBOutlet UIImageView *selectImage;
14 | @property (nonatomic, copy) NSString * imageName;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/drawSettingView/BackImageBoardCollectionViewCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // BackImageBoardCollectionViewCell.m
3 | // DemoAntiAliasing
4 | //
5 | // Created by 伍宏彬 on 15/11/6.
6 | // Copyright © 2015年 HB. All rights reserved.
7 | //
8 |
9 | #import "BackImageBoardCollectionViewCell.h"
10 |
11 | @interface BackImageBoardCollectionViewCell()
12 | @property (weak, nonatomic) IBOutlet UIImageView *backImage;
13 |
14 | @end
15 |
16 | @implementation BackImageBoardCollectionViewCell
17 |
18 | - (void)awakeFromNib {
19 | [super awakeFromNib];
20 | self.layer.cornerRadius = 3;
21 | self.layer.borderWidth = 2;
22 | self.layer.borderColor = [UIColor whiteColor].CGColor;
23 | self.layer.masksToBounds = YES;
24 | self.selectImage.hidden = YES;
25 | }
26 |
27 | - (void)setImageName:(NSString *)imageName
28 | {
29 | _imageName = imageName;
30 | self.backImage.image = [UIImage imageNamed:imageName];
31 |
32 | }
33 | @end
34 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/drawSettingView/BackImageBoardCollectionViewCell.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/drawSettingView/HBBackImageBoard.h:
--------------------------------------------------------------------------------
1 | //
2 | // HBBackImageBoard.h
3 | // DemoAntiAliasing
4 | //
5 | // Created by 伍宏彬 on 15/11/6.
6 | // Copyright © 2015年 HB. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "HBDrawCommon.h"
11 |
12 |
13 | @interface HBBackImageBoard : UIView
14 |
15 | @property (nonatomic, strong) UICollectionView *collectionView;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/drawSettingView/HBBackImageBoard.m:
--------------------------------------------------------------------------------
1 | //
2 | // HBBackImageBoard.m
3 | // DemoAntiAliasing
4 | //
5 | // Created by 伍宏彬 on 15/11/6.
6 | // Copyright © 2015年 HB. All rights reserved.
7 | //
8 |
9 | #import "HBBackImageBoard.h"
10 | #import "BackImageBoardCollectionViewCell.h"
11 |
12 |
13 | @interface HBBackImageBoard()
14 | {
15 | NSIndexPath *_lastIndexPath;
16 | }
17 | @property (nonatomic, strong) UIImageView *imageView;
18 | @property (nonatomic, strong) NSArray *array;
19 | @end
20 |
21 | @implementation HBBackImageBoard
22 |
23 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
24 | {
25 | return self.array.count;
26 | }
27 |
28 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
29 | {
30 | BackImageBoardCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CollectionImageBoardViewID forIndexPath:indexPath];
31 |
32 | cell.imageName = self.array[indexPath.item];
33 |
34 | if (indexPath.item == 0 && !_lastIndexPath) {
35 |
36 | _lastIndexPath = indexPath;
37 | cell.selectImage.hidden = NO;
38 | cell.layer.borderColor = [UIColor purpleColor].CGColor;
39 |
40 | [[NSNotificationCenter defaultCenter] postNotificationName:ImageBoardNotification object:nil userInfo:[NSDictionary dictionaryWithObject:cell.imageName forKey:@"imageBoardName"]];
41 |
42 | }
43 |
44 | return cell;
45 | }
46 |
47 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
48 | {
49 |
50 | if (_lastIndexPath) {
51 |
52 | BackImageBoardCollectionViewCell *cell = (BackImageBoardCollectionViewCell *)[collectionView cellForItemAtIndexPath:_lastIndexPath];
53 | cell.selectImage.hidden = YES;
54 | cell.layer.borderColor = [UIColor whiteColor].CGColor;
55 | }
56 |
57 | _lastIndexPath = indexPath;
58 |
59 | BackImageBoardCollectionViewCell *cell = (BackImageBoardCollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath];
60 | cell.selectImage.hidden = NO;
61 | cell.layer.borderColor = [UIColor purpleColor].CGColor;
62 |
63 | [[NSNotificationCenter defaultCenter] postNotificationName:ImageBoardNotification object:nil userInfo:[NSDictionary dictionaryWithObject:cell.imageName forKey:@"imageBoardName"]];
64 | }
65 |
66 | - (UIImageView *)imageView
67 | {
68 | if (!_imageView) {
69 | _imageView = [[UIImageView alloc] init];
70 | }
71 | return _imageView;
72 | }
73 | - (NSArray *)array
74 | {
75 | if (!_array) {
76 | _array = [NSArray arrayWithObjects:@"huaban_1",@"huaban_2",@"huaban_3", nil];
77 | }
78 | return _array;
79 | }
80 | @end
81 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/DrawingBoard/drawSettingView/HBDrawSettingBoard.h:
--------------------------------------------------------------------------------
1 | //
2 | // HBDrawSettingBoard.h
3 | // DemoAntiAliasing
4 | //
5 | // Created by 伍宏彬 on 15/11/4.
6 | // Copyright © 2015年 HB. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "HBDrawCommon.h"
11 |
12 | typedef NS_ENUM(NSInteger,setType) {
13 | setTypePen,
14 | setTypeCamera,
15 | setTypeAlbum,
16 | setTypeSave,
17 | setTypeEraser,
18 | setTypeBack,
19 | setTyperegeneration,
20 | setTypeClearAll
21 | };
22 |
23 | typedef void(^boardSettingBlock)(setType type);
24 |
25 | @interface HBDrawSettingBoard : UIView
26 | - (void)getSettingType:(boardSettingBlock)type;
27 | - (CGFloat)getLineWidth;
28 | - (UIColor *)getLineColor;
29 | @end
30 |
31 | //画笔展示的球
32 | @interface HBColorBall : UIView
33 | @property (nonatomic, strong) UIColor *ballColor;
34 |
35 | @property (nonatomic, assign) CGFloat ballSize;
36 |
37 | @property (nonatomic, assign) CGFloat lineWidth;
38 | @end
--------------------------------------------------------------------------------
/HBDrawViewDemo/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 | UIFileSharingEnabled
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationLandscapeLeft
39 | UIInterfaceOrientationLandscapeRight
40 |
41 | UISupportedInterfaceOrientations~ipad
42 |
43 | UIInterfaceOrientationPortrait
44 | UIInterfaceOrientationPortraitUpsideDown
45 | UIInterfaceOrientationLandscapeLeft
46 | UIInterfaceOrientationLandscapeRight
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/all-wcprops:
--------------------------------------------------------------------------------
1 | K 25
2 | svn:wc:ra_dav:version-url
3 | V 66
4 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension
5 | END
6 | MJPropertyKey.m
7 | K 25
8 | svn:wc:ra_dav:version-url
9 | V 82
10 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/MJPropertyKey.m
11 | END
12 | NSObject+MJCoding.h
13 | K 25
14 | svn:wc:ra_dav:version-url
15 | V 86
16 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/NSObject+MJCoding.h
17 | END
18 | MJFoundation.h
19 | K 25
20 | svn:wc:ra_dav:version-url
21 | V 81
22 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/MJFoundation.h
23 | END
24 | NSObject+MJClass.h
25 | K 25
26 | svn:wc:ra_dav:version-url
27 | V 85
28 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/NSObject+MJClass.h
29 | END
30 | NSObject+MJCoding.m
31 | K 25
32 | svn:wc:ra_dav:version-url
33 | V 86
34 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/NSObject+MJCoding.m
35 | END
36 | MJFoundation.m
37 | K 25
38 | svn:wc:ra_dav:version-url
39 | V 81
40 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/MJFoundation.m
41 | END
42 | MJExtension.h
43 | K 25
44 | svn:wc:ra_dav:version-url
45 | V 80
46 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/MJExtension.h
47 | END
48 | NSObject+MJClass.m
49 | K 25
50 | svn:wc:ra_dav:version-url
51 | V 85
52 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/NSObject+MJClass.m
53 | END
54 | NSString+MJExtension.h
55 | K 25
56 | svn:wc:ra_dav:version-url
57 | V 89
58 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/NSString+MJExtension.h
59 | END
60 | MJExtensionConst.h
61 | K 25
62 | svn:wc:ra_dav:version-url
63 | V 85
64 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/MJExtensionConst.h
65 | END
66 | MJProperty.h
67 | K 25
68 | svn:wc:ra_dav:version-url
69 | V 79
70 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/MJProperty.h
71 | END
72 | NSString+MJExtension.m
73 | K 25
74 | svn:wc:ra_dav:version-url
75 | V 89
76 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/NSString+MJExtension.m
77 | END
78 | MJPropertyType.h
79 | K 25
80 | svn:wc:ra_dav:version-url
81 | V 83
82 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/MJPropertyType.h
83 | END
84 | NSObject+MJProperty.h
85 | K 25
86 | svn:wc:ra_dav:version-url
87 | V 88
88 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/NSObject+MJProperty.h
89 | END
90 | NSObject+MJKeyValue.h
91 | K 25
92 | svn:wc:ra_dav:version-url
93 | V 88
94 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/NSObject+MJKeyValue.h
95 | END
96 | MJExtensionConst.m
97 | K 25
98 | svn:wc:ra_dav:version-url
99 | V 85
100 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/MJExtensionConst.m
101 | END
102 | MJProperty.m
103 | K 25
104 | svn:wc:ra_dav:version-url
105 | V 79
106 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/MJProperty.m
107 | END
108 | MJPropertyType.m
109 | K 25
110 | svn:wc:ra_dav:version-url
111 | V 83
112 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/MJPropertyType.m
113 | END
114 | NSObject+MJProperty.m
115 | K 25
116 | svn:wc:ra_dav:version-url
117 | V 88
118 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/NSObject+MJProperty.m
119 | END
120 | MJPropertyKey.h
121 | K 25
122 | svn:wc:ra_dav:version-url
123 | V 82
124 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/MJPropertyKey.h
125 | END
126 | NSObject+MJKeyValue.m
127 | K 25
128 | svn:wc:ra_dav:version-url
129 | V 88
130 | /svn/ps/!svn/ver/23390/yudao/ios/YuDao/YuDao/ExternKit/MJExtension/NSObject+MJKeyValue.m
131 | END
132 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/MJExtension.h.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/MJExtensionConst.h.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/MJExtensionConst.m.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/MJFoundation.h.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/MJFoundation.m.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/MJProperty.h.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/MJProperty.m.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/MJPropertyKey.h.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/MJPropertyKey.m.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/MJPropertyType.h.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/MJPropertyType.m.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/NSObject+MJClass.h.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/NSObject+MJClass.m.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/NSObject+MJCoding.h.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/NSObject+MJCoding.m.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/NSObject+MJKeyValue.h.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/NSObject+MJKeyValue.m.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/NSObject+MJProperty.h.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/NSObject+MJProperty.m.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/NSString+MJExtension.h.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/prop-base/NSString+MJExtension.m.svn-base:
--------------------------------------------------------------------------------
1 | K 14
2 | svn:executable
3 | V 1
4 | *
5 | END
6 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/MJExtension.h.svn-base:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/MJExtensionConst.h.svn-base:
--------------------------------------------------------------------------------
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(error, msg) \
12 | if (error) *error = [NSError errorWithDomain:msg code:250 userInfo:nil];
13 |
14 | /**
15 | * 断言
16 | * @param condition 条件
17 | * @param returnValue 返回值
18 | */
19 | #define MJExtensionAssertError(condition, returnValue, error, msg) \
20 | if ((condition) == NO) { \
21 | MJExtensionBuildError(error, msg); \
22 | return returnValue;\
23 | }
24 |
25 | #define MJExtensionAssert2(condition, returnValue) \
26 | if ((condition) == NO) return returnValue;
27 |
28 | /**
29 | * 断言
30 | * @param condition 条件
31 | */
32 | #define MJExtensionAssert(condition) MJExtensionAssert2(condition, )
33 |
34 | /**
35 | * 断言
36 | * @param param 参数
37 | * @param returnValue 返回值
38 | */
39 | #define MJExtensionAssertParamNotNil2(param, returnValue) \
40 | MJExtensionAssert2((param) != nil, returnValue)
41 |
42 | /**
43 | * 断言
44 | * @param param 参数
45 | */
46 | #define MJExtensionAssertParamNotNil(param) MJExtensionAssertParamNotNil2(param, )
47 |
48 | /**
49 | * 打印所有的属性
50 | */
51 | #define MJLogAllIvars \
52 | -(NSString *)description \
53 | { \
54 | return [self keyValues].description; \
55 | }
56 | #define MJExtensionLogAllProperties MJLogAllIvars
57 |
58 | /**
59 | * 类型(属性类型)
60 | */
61 | extern NSString *const MJPropertyTypeInt;
62 | extern NSString *const MJPropertyTypeShort;
63 | extern NSString *const MJPropertyTypeFloat;
64 | extern NSString *const MJPropertyTypeDouble;
65 | extern NSString *const MJPropertyTypeLong;
66 | extern NSString *const MJPropertyTypeLongLong;
67 | extern NSString *const MJPropertyTypeChar;
68 | extern NSString *const MJPropertyTypeBOOL1;
69 | extern NSString *const MJPropertyTypeBOOL2;
70 | extern NSString *const MJPropertyTypePointer;
71 |
72 | extern NSString *const MJPropertyTypeIvar;
73 | extern NSString *const MJPropertyTypeMethod;
74 | extern NSString *const MJPropertyTypeBlock;
75 | extern NSString *const MJPropertyTypeClass;
76 | extern NSString *const MJPropertyTypeSEL;
77 | extern NSString *const MJPropertyTypeId;
78 |
79 | #endif
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/MJExtensionConst.m.svn-base:
--------------------------------------------------------------------------------
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 = @"q";
14 | NSString *const MJPropertyTypeChar = @"c";
15 | NSString *const MJPropertyTypeBOOL1 = @"c";
16 | NSString *const MJPropertyTypeBOOL2 = @"b";
17 | NSString *const MJPropertyTypePointer = @"*";
18 |
19 | NSString *const MJPropertyTypeIvar = @"^{objc_ivar=}";
20 | NSString *const MJPropertyTypeMethod = @"^{objc_method=}";
21 | NSString *const MJPropertyTypeBlock = @"@?";
22 | NSString *const MJPropertyTypeClass = @"#";
23 | NSString *const MJPropertyTypeSEL = @":";
24 | NSString *const MJPropertyTypeId = @"@";
25 |
26 | #endif
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/MJFoundation.h.svn-base:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/MJFoundation.m.svn-base:
--------------------------------------------------------------------------------
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 | [NSArray class],
27 | [NSDictionary class],
28 | [NSString class],
29 | [NSAttributedString class], nil];
30 | }
31 | return foundationClasses_;
32 | }
33 |
34 | + (BOOL)isClassFromFoundation:(Class)c
35 | {
36 | if (c == [NSObject class] || c == [NSManagedObject class]) return YES;
37 |
38 | __block BOOL result = NO;
39 | [[self foundationClasses] enumerateObjectsUsingBlock:^(Class foundationClass, BOOL *stop) {
40 | if (c == foundationClass || [c isSubclassOfClass:foundationClass]) {
41 | result = YES;
42 | *stop = YES;
43 | }
44 | }];
45 | return result;
46 | }
47 | @end
48 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/MJProperty.h.svn-base:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/MJProperty.m.svn-base:
--------------------------------------------------------------------------------
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 |
13 | @interface MJProperty()
14 | @property (strong, nonatomic) NSMutableDictionary *propertyKeysDict;
15 | @property (strong, nonatomic) NSMutableDictionary *objectClassInArrayDict;
16 | @end
17 |
18 | @implementation MJProperty
19 |
20 | /** originKey作为key,propertyKeys作为value */
21 | static NSMutableDictionary *originKeyPropertyKey_;
22 | + (void)load
23 | {
24 | originKeyPropertyKey_ = [NSMutableDictionary dictionary];
25 | }
26 |
27 | #pragma mark - 懒加载
28 | - (NSMutableDictionary *)propertyKeysDict
29 | {
30 | if (!_propertyKeysDict) {
31 | _propertyKeysDict = [NSMutableDictionary dictionary];
32 | }
33 | return _propertyKeysDict;
34 | }
35 |
36 | - (NSMutableDictionary *)objectClassInArrayDict
37 | {
38 | if (!_objectClassInArrayDict) {
39 | _objectClassInArrayDict = [NSMutableDictionary dictionary];
40 | }
41 | return _objectClassInArrayDict;
42 | }
43 |
44 | #pragma mark - 缓存
45 | + (instancetype)cachedPropertyWithProperty:(objc_property_t)property
46 | {
47 | MJProperty *propertyObj = objc_getAssociatedObject(self, property);
48 | if (propertyObj == nil) {
49 | propertyObj = [[self alloc] init];
50 | propertyObj.property = property;
51 | objc_setAssociatedObject(self, property, propertyObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
52 | }
53 | return propertyObj;
54 | }
55 |
56 | #pragma mark - 公共方法
57 | - (void)setProperty:(objc_property_t)property
58 | {
59 | _property = property;
60 |
61 | MJExtensionAssertParamNotNil(property);
62 |
63 | // 1.属性名
64 | _name = @(property_getName(property));
65 |
66 | // 2.成员类型
67 | NSString *attrs = @(property_getAttributes(property));
68 | NSUInteger loc = 1;
69 | NSUInteger len = [attrs rangeOfString:@","].location - loc;
70 | _type = [MJPropertyType cachedTypeWithCode:[attrs substringWithRange:NSMakeRange(loc, len)]];
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
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 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/MJPropertyKey.m.svn-base:
--------------------------------------------------------------------------------
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 | return [object count] ? object[self.name.intValue] : nil;
19 | }
20 | return nil;
21 | }
22 | @end
23 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/MJPropertyType.h.svn-base:
--------------------------------------------------------------------------------
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
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/MJPropertyType.m.svn-base:
--------------------------------------------------------------------------------
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 | #pragma mark - 缓存
17 | static NSMutableDictionary *cachedTypes_;
18 | + (void)load
19 | {
20 | cachedTypes_ = [NSMutableDictionary dictionary];
21 | }
22 |
23 | + (instancetype)cachedTypeWithCode:(NSString *)code
24 | {
25 | MJExtensionAssertParamNotNil2(code, nil);
26 |
27 | MJPropertyType *type = cachedTypes_[code];
28 | if (type == nil) {
29 | type = [[self alloc] init];
30 | type.code = code;
31 | cachedTypes_[code] = type;
32 | }
33 | return type;
34 | }
35 |
36 | #pragma mark - 公共方法
37 | - (void)setCode:(NSString *)code
38 | {
39 | _code = code;
40 |
41 | MJExtensionAssertParamNotNil(code);
42 |
43 | if ([code isEqualToString:MJPropertyTypeId]) {
44 | _idType = YES;
45 | } else if (code.length == 0) {
46 | _KVCDisabled = YES;
47 | } else if (code.length > 3 && [code hasPrefix:@"@\""]) {
48 | // 去掉@"和",截取中间的类型名称
49 | _code = [code substringWithRange:NSMakeRange(2, code.length - 3)];
50 | _typeClass = NSClassFromString(_code);
51 | _fromFoundation = [MJFoundation isClassFromFoundation:_typeClass];
52 | _numberType = (_typeClass == [NSNumber class] || [_typeClass isSubclassOfClass:[NSNumber class]]);
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, 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 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/NSObject+MJClass.h.svn-base:
--------------------------------------------------------------------------------
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)enumerateClasses:(MJClassesEnumeration)enumeration;
34 | + (void)enumerateAllClasses:(MJClassesEnumeration)enumeration;
35 |
36 | #pragma mark - 属性白名单配置
37 | /**
38 | * 这个数组中的属性名才会进行字典和模型的转换
39 | *
40 | * @param allowedPropertyNames 这个数组中的属性名才会进行字典和模型的转换
41 | */
42 | + (void)setupAllowedPropertyNames:(MJAllowedPropertyNames)allowedPropertyNames;
43 |
44 | /**
45 | * 这个数组中的属性名才会进行字典和模型的转换
46 | */
47 | + (NSMutableArray *)totalAllowedPropertyNames;
48 |
49 | #pragma mark - 属性黑名单配置
50 | /**
51 | * 这个数组中的属性名将会被忽略:不进行字典和模型的转换
52 | *
53 | * @param ignoredPropertyNames 这个数组中的属性名将会被忽略:不进行字典和模型的转换
54 | */
55 | + (void)setupIgnoredPropertyNames:(MJIgnoredPropertyNames)ignoredPropertyNames;
56 |
57 | /**
58 | * 这个数组中的属性名将会被忽略:不进行字典和模型的转换
59 | */
60 | + (NSMutableArray *)totalIgnoredPropertyNames;
61 |
62 | #pragma mark - 归档属性白名单配置
63 | /**
64 | * 这个数组中的属性名才会进行归档
65 | *
66 | * @param allowedCodingPropertyNames 这个数组中的属性名才会进行归档
67 | */
68 | + (void)setupAllowedCodingPropertyNames:(MJAllowedCodingPropertyNames)allowedCodingPropertyNames;
69 |
70 | /**
71 | * 这个数组中的属性名才会进行字典和模型的转换
72 | */
73 | + (NSMutableArray *)totalAllowedCodingPropertyNames;
74 |
75 | #pragma mark - 归档属性黑名单配置
76 | /**
77 | * 这个数组中的属性名将会被忽略:不进行归档
78 | *
79 | * @param ignoredCodingPropertyNames 这个数组中的属性名将会被忽略:不进行归档
80 | */
81 | + (void)setupIgnoredCodingPropertyNames:(MJIgnoredCodingPropertyNames)ignoredCodingPropertyNames;
82 |
83 | /**
84 | * 这个数组中的属性名将会被忽略:不进行归档
85 | */
86 | + (NSMutableArray *)totalIgnoredCodingPropertyNames;
87 |
88 | #pragma mark - 内部使用
89 | + (void)setupBlockReturnValue:(id (^)())block key:(const char *)key dict:(NSMutableDictionary *)dict;
90 | @end
91 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/NSObject+MJClass.m.svn-base:
--------------------------------------------------------------------------------
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 | @implementation NSObject (MJClass)
21 |
22 | static NSMutableDictionary *allowedPropertyNames_;
23 | static NSMutableDictionary *ignoredPropertyNames_;
24 | static NSMutableDictionary *allowedCodingPropertyNames_;
25 | static NSMutableDictionary *ignoredCodingPropertyNames_;
26 | + (void)load
27 | {
28 | allowedPropertyNames_ = [NSMutableDictionary dictionary];
29 | ignoredPropertyNames_ = [NSMutableDictionary dictionary];
30 | allowedCodingPropertyNames_ = [NSMutableDictionary dictionary];
31 | ignoredCodingPropertyNames_ = [NSMutableDictionary dictionary];
32 | }
33 |
34 | + (void)enumerateClasses:(MJClassesEnumeration)enumeration
35 | {
36 | // 1.没有block就直接返回
37 | if (enumeration == nil) return;
38 |
39 | // 2.停止遍历的标记
40 | BOOL stop = NO;
41 |
42 | // 3.当前正在遍历的类
43 | Class c = self;
44 |
45 | // 4.开始遍历每一个类
46 | while (c && !stop) {
47 | // 4.1.执行操作
48 | enumeration(c, &stop);
49 |
50 | // 4.2.获得父类
51 | c = class_getSuperclass(c);
52 |
53 | if ([MJFoundation isClassFromFoundation:c]) break;
54 | }
55 | }
56 |
57 | + (void)enumerateAllClasses:(MJClassesEnumeration)enumeration
58 | {
59 | // 1.没有block就直接返回
60 | if (enumeration == nil) return;
61 |
62 | // 2.停止遍历的标记
63 | BOOL stop = NO;
64 |
65 | // 3.当前正在遍历的类
66 | Class c = self;
67 |
68 | // 4.开始遍历每一个类
69 | while (c && !stop) {
70 | // 4.1.执行操作
71 | enumeration(c, &stop);
72 |
73 | // 4.2.获得父类
74 | c = class_getSuperclass(c);
75 | }
76 | }
77 |
78 | #pragma mark - 属性黑名单配置
79 | + (void)setupIgnoredPropertyNames:(MJIgnoredPropertyNames)ignoredPropertyNames
80 | {
81 | [self setupBlockReturnValue:ignoredPropertyNames key:&MJIgnoredPropertyNamesKey dict:ignoredPropertyNames_];
82 | }
83 |
84 | + (NSMutableArray *)totalIgnoredPropertyNames
85 | {
86 | return [self totalObjectsWithSelector:@selector(ignoredPropertyNames) key:&MJIgnoredPropertyNamesKey dict:ignoredPropertyNames_];
87 | }
88 |
89 | #pragma mark - 归档属性黑名单配置
90 | + (void)setupIgnoredCodingPropertyNames:(MJIgnoredCodingPropertyNames)ignoredCodingPropertyNames
91 | {
92 | [self setupBlockReturnValue:ignoredCodingPropertyNames key:&MJIgnoredCodingPropertyNamesKey dict:ignoredCodingPropertyNames_];
93 | }
94 |
95 | + (NSMutableArray *)totalIgnoredCodingPropertyNames
96 | {
97 | return [self totalObjectsWithSelector:@selector(ignoredCodingPropertyNames) key:&MJIgnoredCodingPropertyNamesKey dict:ignoredCodingPropertyNames_];
98 | }
99 |
100 | #pragma mark - 属性白名单配置
101 | + (void)setupAllowedPropertyNames:(MJAllowedPropertyNames)allowedPropertyNames;
102 | {
103 | [self setupBlockReturnValue:allowedPropertyNames key:&MJAllowedPropertyNamesKey dict:allowedPropertyNames_];
104 | }
105 |
106 | + (NSMutableArray *)totalAllowedPropertyNames
107 | {
108 | return [self totalObjectsWithSelector:@selector(allowedPropertyNames) key:&MJAllowedPropertyNamesKey dict:allowedPropertyNames_];
109 | }
110 |
111 | #pragma mark - 归档属性白名单配置
112 | + (void)setupAllowedCodingPropertyNames:(MJAllowedCodingPropertyNames)allowedCodingPropertyNames
113 | {
114 | [self setupBlockReturnValue:allowedCodingPropertyNames key:&MJAllowedCodingPropertyNamesKey dict:allowedCodingPropertyNames_];
115 | }
116 |
117 | + (NSMutableArray *)totalAllowedCodingPropertyNames
118 | {
119 | return [self totalObjectsWithSelector:@selector(allowedCodingPropertyNames) key:&MJAllowedCodingPropertyNamesKey dict:allowedCodingPropertyNames_];
120 | }
121 | #pragma mark - block和方法处理:存储block的返回值
122 | + (void)setupBlockReturnValue:(id (^)())block key:(const char *)key dict:(NSMutableDictionary *)dict
123 | {
124 | if (block) {
125 | objc_setAssociatedObject(self, key, block(), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
126 | } else {
127 | objc_setAssociatedObject(self, key, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
128 | }
129 |
130 | // 清空数据
131 | [dict removeAllObjects];
132 | }
133 |
134 | + (NSMutableArray *)totalObjectsWithSelector:(SEL)selector key:(const char *)key dict:(NSMutableDictionary *)dict
135 | {
136 | NSMutableArray *array = dict[NSStringFromClass(self)];
137 | if (array) return array;
138 |
139 | // 创建、存储
140 | dict[NSStringFromClass(self)] = array = [NSMutableArray array];
141 |
142 | if ([self respondsToSelector:selector]) {
143 | #pragma clang diagnostic push
144 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
145 | NSArray *subArray = [self performSelector:selector];
146 | #pragma clang diagnostic pop
147 | if (subArray) {
148 | [array addObjectsFromArray:subArray];
149 | }
150 | }
151 |
152 | [self enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
153 | NSArray *subArray = objc_getAssociatedObject(c, key);
154 | [array addObjectsFromArray:subArray];
155 | }];
156 | return array;
157 | }
158 | @end
159 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/NSObject+MJCoding.h.svn-base:
--------------------------------------------------------------------------------
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 | /**
11 | * Codeing协议
12 | */
13 | @protocol MJCoding
14 | @optional
15 | /**
16 | * 这个数组中的属性名才会进行归档
17 | */
18 | + (NSArray *)allowedCodingPropertyNames;
19 | /**
20 | * 这个数组中的属性名将会被忽略:不进行归档
21 | */
22 | + (NSArray *)ignoredCodingPropertyNames;
23 | @end
24 |
25 | @interface NSObject (MJCoding)
26 | /**
27 | * 解码(从文件中解析对象)
28 | */
29 | - (void)decode:(NSCoder *)decoder;
30 | /**
31 | * 编码(将对象写入文件中)
32 | */
33 | - (void)encode:(NSCoder *)encoder;
34 | @end
35 |
36 | /**
37 | 归档的实现
38 | */
39 | #define MJCodingImplementation \
40 | - (id)initWithCoder:(NSCoder *)decoder \
41 | { \
42 | if (self = [super init]) { \
43 | [self decode:decoder]; \
44 | } \
45 | return self; \
46 | } \
47 | \
48 | - (void)encodeWithCoder:(NSCoder *)encoder \
49 | { \
50 | [self encode:encoder]; \
51 | }
52 |
53 | #define MJExtensionCodingImplementation MJCodingImplementation
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/NSObject+MJCoding.m.svn-base:
--------------------------------------------------------------------------------
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)encode:(NSCoder *)encoder
17 | {
18 | Class aClass = [self class];
19 |
20 | NSArray *allowedCodingPropertyNames = [aClass totalAllowedCodingPropertyNames];
21 | NSArray *ignoredCodingPropertyNames = [aClass totalIgnoredCodingPropertyNames];
22 |
23 | [aClass 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)decode:(NSCoder *)decoder
35 | {
36 | Class aClass = [self class];
37 |
38 | NSArray *allowedCodingPropertyNames = [aClass totalAllowedCodingPropertyNames];
39 | NSArray *ignoredCodingPropertyNames = [aClass totalIgnoredCodingPropertyNames];
40 |
41 | [aClass 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 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/NSObject+MJKeyValue.h.svn-base:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+MJKeyValue.h
3 | // MJExtension
4 | //
5 | // Created by mj on 13-8-24.
6 | // Copyright (c) 2013年 小码哥. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "MJExtensionConst.h"
11 | #import
12 | #import "MJProperty.h"
13 |
14 | /**
15 | * KeyValue协议
16 | */
17 | @protocol MJKeyValue
18 | @optional
19 | /**
20 | * 只有这个数组中的属性名才允许进行字典和模型的转换
21 | */
22 | + (NSArray *)allowedPropertyNames;
23 |
24 | /**
25 | * 这个数组中的属性名将会被忽略:不进行字典和模型的转换
26 | */
27 | + (NSArray *)ignoredPropertyNames;
28 |
29 | /**
30 | * 将属性名换为其他key去字典中取值
31 | *
32 | * @return 字典中的key是属性名,value是从字典中取值用的key
33 | */
34 | + (NSDictionary *)replacedKeyFromPropertyName;
35 |
36 | /**
37 | * 将属性名换为其他key去字典中取值
38 | *
39 | * @return 从字典中取值用的key
40 | */
41 | + (NSString *)replacedKeyFromPropertyName121:(NSString *)propertyName;
42 |
43 | /**
44 | * 数组中需要转换的模型类
45 | *
46 | * @return 字典中的key是数组属性名,value是数组中存放模型的Class(Class类型或者NSString类型)
47 | */
48 | + (NSDictionary *)objectClassInArray;
49 |
50 | /**
51 | * 旧值换新值,用于过滤字典中的值
52 | *
53 | * @param oldValue 旧值
54 | *
55 | * @return 新值
56 | */
57 | - (id)newValueFromOldValue:(id)oldValue property:(MJProperty *)property;
58 |
59 | /**
60 | * 当字典转模型完毕时调用
61 | */
62 | - (void)keyValuesDidFinishConvertingToObject;
63 |
64 | /**
65 | * 当模型转字典完毕时调用
66 | */
67 | - (void)objectDidFinishConvertingToKeyValues;
68 | @end
69 |
70 | @interface NSObject (MJKeyValue)
71 | /**
72 | * 将字典的键值对转成模型属性
73 | * @param keyValues 字典(可以是NSDictionary、NSData、NSString)
74 | */
75 | - (instancetype)setKeyValues:(id)keyValues;
76 | - (instancetype)setKeyValues:(id)keyValues error:(NSError **)error;
77 |
78 | /**
79 | * 将字典的键值对转成模型属性
80 | * @param keyValues 字典(可以是NSDictionary、NSData、NSString)
81 | * @param context CoreData上下文
82 | */
83 | - (instancetype)setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context;
84 | - (instancetype)setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context error:(NSError **)error;
85 |
86 | /**
87 | * 模型转字典时,字典的key是否参考replacedKeyFromPropertyName等方法(父类设置了,子类也会继承下来)
88 | */
89 | + (void)referenceReplacedKeyWhenCreatingKeyValues:(BOOL)reference;
90 |
91 | /**
92 | * 将模型转成字典
93 | * @return 字典
94 | */
95 | - (NSMutableDictionary *)keyValues;
96 | - (NSMutableDictionary *)keyValuesWithError:(NSError **)error;
97 | - (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys;
98 | - (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys error:(NSError **)error;
99 | - (NSMutableDictionary *)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys;
100 | - (NSMutableDictionary *)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys error:(NSError **)error;
101 |
102 | /**
103 | * 通过模型数组来创建一个字典数组
104 | * @param objectArray 模型数组
105 | * @return 字典数组
106 | */
107 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray;
108 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray error:(NSError **)error;
109 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys;
110 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys error:(NSError **)error;
111 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray ignoredKeys:(NSArray *)ignoredKeys;
112 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray ignoredKeys:(NSArray *)ignoredKeys error:(NSError **)error;
113 |
114 | #pragma mark - 字典转模型
115 | /**
116 | * 通过字典来创建一个模型
117 | * @param keyValues 字典(可以是NSDictionary、NSData、NSString)
118 | * @return 新建的对象
119 | */
120 | + (instancetype)objectWithKeyValues:(id)keyValues;
121 | + (instancetype)objectWithKeyValues:(id)keyValues error:(NSError **)error;
122 |
123 | /**
124 | * 通过字典来创建一个CoreData模型
125 | * @param keyValues 字典(可以是NSDictionary、NSData、NSString)
126 | * @param context CoreData上下文
127 | * @return 新建的对象
128 | */
129 | + (instancetype)objectWithKeyValues:(id)keyValues context:(NSManagedObjectContext *)context;
130 | + (instancetype)objectWithKeyValues:(id)keyValues context:(NSManagedObjectContext *)context error:(NSError **)error;
131 |
132 | /**
133 | * 通过plist来创建一个模型
134 | * @param filename 文件名(仅限于mainBundle中的文件)
135 | * @return 新建的对象
136 | */
137 | + (instancetype)objectWithFilename:(NSString *)filename;
138 | + (instancetype)objectWithFilename:(NSString *)filename error:(NSError **)error;
139 |
140 | /**
141 | * 通过plist来创建一个模型
142 | * @param file 文件全路径
143 | * @return 新建的对象
144 | */
145 | + (instancetype)objectWithFile:(NSString *)file;
146 | + (instancetype)objectWithFile:(NSString *)file error:(NSError **)error;
147 |
148 | #pragma mark - 字典数组转模型数组
149 | /**
150 | * 通过字典数组来创建一个模型数组
151 | * @param keyValuesArray 字典数组(可以是NSDictionary、NSData、NSString)
152 | * @return 模型数组
153 | */
154 | + (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray;
155 | + (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray error:(NSError **)error;
156 |
157 | /**
158 | * 通过字典数组来创建一个模型数组
159 | * @param keyValuesArray 字典数组(可以是NSDictionary、NSData、NSString)
160 | * @param context CoreData上下文
161 | * @return 模型数组
162 | */
163 | + (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context;
164 | + (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context error:(NSError **)error;
165 |
166 | /**
167 | * 通过plist来创建一个模型数组
168 | * @param filename 文件名(仅限于mainBundle中的文件)
169 | * @return 模型数组
170 | */
171 | + (NSMutableArray *)objectArrayWithFilename:(NSString *)filename;
172 | + (NSMutableArray *)objectArrayWithFilename:(NSString *)filename error:(NSError **)error;
173 |
174 | /**
175 | * 通过plist来创建一个模型数组
176 | * @param file 文件全路径
177 | * @return 模型数组
178 | */
179 | + (NSMutableArray *)objectArrayWithFile:(NSString *)file;
180 | + (NSMutableArray *)objectArrayWithFile:(NSString *)file error:(NSError **)error;
181 |
182 | #pragma mark - 转换为JSON
183 | /**
184 | * 转换为JSON Data
185 | */
186 | - (NSData *)JSONData;
187 | /**
188 | * 转换为字典或者数组
189 | */
190 | - (id)JSONObject;
191 | /**
192 | * 转换为JSON 字符串
193 | */
194 | - (NSString *)JSONString;
195 | @end
196 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/NSObject+MJProperty.h.svn-base:
--------------------------------------------------------------------------------
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 |
11 | @class MJProperty;
12 |
13 | /**
14 | * 遍历成员变量用的block
15 | *
16 | * @param property 成员的包装对象
17 | * @param stop YES代表停止遍历,NO代表继续遍历
18 | */
19 | typedef void (^MJPropertiesEnumeration)(MJProperty *property, BOOL *stop);
20 |
21 | /** 将属性名换为其他key去字典中取值 */
22 | typedef NSDictionary * (^MJReplacedKeyFromPropertyName)();
23 | typedef NSString * (^MJReplacedKeyFromPropertyName121)(NSString *propertyName);
24 | /** 数组中需要转换的模型类 */
25 | typedef NSDictionary * (^MJObjectClassInArray)();
26 | /** 用于过滤字典中的值 */
27 | typedef id (^MJNewValueFromOldValue)(id object, id oldValue, MJProperty *property);
28 |
29 | /**
30 | * 成员属性相关的扩展
31 | */
32 | @interface NSObject (MJProperty)
33 | #pragma mark - 遍历
34 | /**
35 | * 遍历所有的成员
36 | */
37 | + (void)enumerateProperties:(MJPropertiesEnumeration)enumeration;
38 |
39 | #pragma mark - 新值配置
40 | /**
41 | * 用于过滤字典中的值
42 | *
43 | * @param newValueFormOldValue 用于过滤字典中的值
44 | */
45 | + (void)setupNewValueFromOldValue:(MJNewValueFromOldValue)newValueFormOldValue;
46 | + (id)getNewValueFromObject:(__weak id)object oldValue:(__weak id)oldValue property:(__weak MJProperty *)property;
47 |
48 | #pragma mark - key配置
49 | /**
50 | * 将属性名换为其他key去字典中取值
51 | *
52 | * @param replacedKeyFromPropertyName 将属性名换为其他key去字典中取值
53 | */
54 | + (void)setupReplacedKeyFromPropertyName:(MJReplacedKeyFromPropertyName)replacedKeyFromPropertyName;
55 | /**
56 | * 将属性名换为其他key去字典中取值
57 | *
58 | * @param replacedKeyFromPropertyName121 将属性名换为其他key去字典中取值
59 | */
60 | + (void)setupReplacedKeyFromPropertyName121:(MJReplacedKeyFromPropertyName121)replacedKeyFromPropertyName121;
61 |
62 | #pragma mark - array model class配置
63 | /**
64 | * 数组中需要转换的模型类
65 | *
66 | * @param objectClassInArray 数组中需要转换的模型类
67 | */
68 | + (void)setupObjectClassInArray:(MJObjectClassInArray)objectClassInArray;
69 | @end
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/NSObject+MJProperty.m.svn-base:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+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 "NSObject+MJProperty.h"
10 | #import "NSObject+MJKeyValue.h"
11 | #import "NSObject+MJCoding.h"
12 | #import "NSObject+MJClass.h"
13 | #import "MJProperty.h"
14 | #import "MJFoundation.h"
15 | #import
16 |
17 | @implementation NSObject (Property)
18 |
19 | static const char MJReplacedKeyFromPropertyNameKey = '\0';
20 | static const char MJReplacedKeyFromPropertyName121Key = '\0';
21 | static const char MJNewValueFromOldValueKey = '\0';
22 | static const char MJObjectClassInArrayKey = '\0';
23 |
24 | static NSMutableDictionary *cachedProperties_;
25 | + (void)load
26 | {
27 | cachedProperties_ = [NSMutableDictionary dictionary];
28 | }
29 |
30 | #pragma mark - --私有方法--
31 | + (NSString *)propertyKey:(NSString *)propertyName
32 | {
33 | MJExtensionAssertParamNotNil2(propertyName, nil);
34 |
35 | __block NSString *key = nil;
36 | // 查看有没有需要替换的key
37 | if ([self respondsToSelector:@selector(replacedKeyFromPropertyName121:)]) {
38 | key = [self replacedKeyFromPropertyName121:propertyName];
39 | }
40 |
41 | // 调用block
42 | if (!key) {
43 | [self enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
44 | MJReplacedKeyFromPropertyName121 block = objc_getAssociatedObject(c, &MJReplacedKeyFromPropertyName121Key);
45 | if (block) {
46 | key = block(propertyName);
47 | }
48 | if (key) *stop = YES;
49 | }];
50 | }
51 |
52 | // 查看有没有需要替换的key
53 | if (!key && [self respondsToSelector:@selector(replacedKeyFromPropertyName)]) {
54 | key = [self replacedKeyFromPropertyName][propertyName];
55 | }
56 |
57 | if (!key) {
58 | [self enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
59 | NSDictionary *dict = objc_getAssociatedObject(c, &MJReplacedKeyFromPropertyNameKey);
60 | if (dict) {
61 | key = dict[propertyName];
62 | }
63 | if (key) *stop = YES;
64 | }];
65 | }
66 |
67 | // 2.用属性名作为key
68 | if (!key) key = propertyName;
69 |
70 | return key;
71 | }
72 |
73 | + (Class)propertyObjectClassInArray:(NSString *)propertyName
74 | {
75 | __block id aClass = nil;
76 | if ([self respondsToSelector:@selector(objectClassInArray)]) {
77 | aClass = [self objectClassInArray][propertyName];
78 | }
79 |
80 | if (!aClass) {
81 | [self enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
82 | NSDictionary *dict = objc_getAssociatedObject(c, &MJObjectClassInArrayKey);
83 | if (dict) {
84 | aClass = dict[propertyName];
85 | }
86 | if (aClass) *stop = YES;
87 | }];
88 | }
89 |
90 | // 如果是NSString类型
91 | if ([aClass isKindOfClass:[NSString class]]) {
92 | aClass = NSClassFromString(aClass);
93 | }
94 | return aClass;
95 | }
96 |
97 | #pragma mark - --公共方法--
98 | + (void)enumerateProperties:(MJPropertiesEnumeration)enumeration
99 | {
100 | // 获得成员变量
101 | NSArray *cachedProperties = [self properties];
102 |
103 | // 遍历成员变量
104 | BOOL stop = NO;
105 | for (MJProperty *property in cachedProperties) {
106 | enumeration(property, &stop);
107 | if (stop) break;
108 | }
109 | }
110 |
111 | #pragma mark - 公共方法
112 | + (NSMutableArray *)properties
113 | {
114 | // 获得成员变量
115 | // 通过关联对象,以及提前定义好的MJCachedPropertiesKey来进行运行时,对所有属性的获取。
116 |
117 | //***objc_getAssociatedObject 方法用于判断当前是否已经获取过MJCachedPropertiesKey对应的关联对象
118 | // 1> 关联到的对象
119 | // 2> 关联的属性 key
120 | NSMutableArray *cachedProperties = cachedProperties_[NSStringFromClass(self)];
121 |
122 | //***
123 | if (cachedProperties == nil) {
124 | cachedProperties = [NSMutableArray array];
125 |
126 | /** 遍历这个类的所有类()不包括NSObject这些基础类 */
127 | [self enumerateClasses:^(__unsafe_unretained Class c, BOOL *stop) {
128 | // 1.获得所有的成员变量
129 | unsigned int outCount = 0;
130 | /**
131 | class_copyIvarList 成员变量,提示有很多第三方框架会使用 Ivar,能够获得更多的信息
132 | 但是:在 swift 中,由于语法结构的变化,使用 Ivar 非常不稳定,经常会崩溃!
133 | class_copyPropertyList 属性
134 | class_copyMethodList 方法
135 | class_copyProtocolList 协议
136 | */
137 | objc_property_t *properties = class_copyPropertyList(c, &outCount);
138 |
139 | // 2.遍历每一个成员变量
140 | for (unsigned int i = 0; i
10 |
11 | @interface NSString (MJExtension)
12 | /**
13 | * 驼峰转下划线(loveYou -> love_you)
14 | */
15 | - (NSString *)underlineFromCamel;
16 | /**
17 | * 下划线转驼峰(love_you -> loveYou)
18 | */
19 | - (NSString *)camelFromUnderline;
20 | /**
21 | * 首字母变大写
22 | */
23 | - (NSString *)firstCharUpper;
24 | /**
25 | * 首字母变小写
26 | */
27 | - (NSString *)firstCharLower;
28 |
29 | - (BOOL)isPureInt;
30 |
31 | - (NSURL *)url;
32 | @end
33 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/.svn/text-base/NSString+MJExtension.m.svn-base:
--------------------------------------------------------------------------------
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 *)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 *)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 *)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)isPureInt
66 | {
67 | NSScanner *scan = [NSScanner scannerWithString:self];
68 | int val;
69 | return [scan scanInt:&val] && [scan isAtEnd];
70 | }
71 |
72 | - (NSURL *)url
73 | {
74 | return [NSURL URLWithString:(NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)self,(CFStringRef)@"!$&'()*+,-./:;=?@_~%#[]", NULL,kCFStringEncodingUTF8))];
75 | }
76 | @end
77 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/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 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/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(error, msg) \
12 | if (error) *error = [NSError errorWithDomain:msg code:250 userInfo:nil];
13 |
14 | /**
15 | * 断言
16 | * @param condition 条件
17 | * @param returnValue 返回值
18 | */
19 | #define MJExtensionAssertError(condition, returnValue, error, msg) \
20 | if ((condition) == NO) { \
21 | MJExtensionBuildError(error, msg); \
22 | return returnValue;\
23 | }
24 |
25 | #define MJExtensionAssert2(condition, returnValue) \
26 | if ((condition) == NO) return returnValue;
27 |
28 | /**
29 | * 断言
30 | * @param condition 条件
31 | */
32 | #define MJExtensionAssert(condition) MJExtensionAssert2(condition, )
33 |
34 | /**
35 | * 断言
36 | * @param param 参数
37 | * @param returnValue 返回值
38 | */
39 | #define MJExtensionAssertParamNotNil2(param, returnValue) \
40 | MJExtensionAssert2((param) != nil, returnValue)
41 |
42 | /**
43 | * 断言
44 | * @param param 参数
45 | */
46 | #define MJExtensionAssertParamNotNil(param) MJExtensionAssertParamNotNil2(param, )
47 |
48 | /**
49 | * 打印所有的属性
50 | */
51 | #define MJLogAllIvars \
52 | -(NSString *)description \
53 | { \
54 | return [self keyValues].description; \
55 | }
56 | #define MJExtensionLogAllProperties MJLogAllIvars
57 |
58 | /**
59 | * 类型(属性类型)
60 | */
61 | extern NSString *const MJPropertyTypeInt;
62 | extern NSString *const MJPropertyTypeShort;
63 | extern NSString *const MJPropertyTypeFloat;
64 | extern NSString *const MJPropertyTypeDouble;
65 | extern NSString *const MJPropertyTypeLong;
66 | extern NSString *const MJPropertyTypeLongLong;
67 | extern NSString *const MJPropertyTypeChar;
68 | extern NSString *const MJPropertyTypeBOOL1;
69 | extern NSString *const MJPropertyTypeBOOL2;
70 | extern NSString *const MJPropertyTypePointer;
71 |
72 | extern NSString *const MJPropertyTypeIvar;
73 | extern NSString *const MJPropertyTypeMethod;
74 | extern NSString *const MJPropertyTypeBlock;
75 | extern NSString *const MJPropertyTypeClass;
76 | extern NSString *const MJPropertyTypeSEL;
77 | extern NSString *const MJPropertyTypeId;
78 |
79 | #endif
--------------------------------------------------------------------------------
/HBDrawViewDemo/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 = @"q";
14 | NSString *const MJPropertyTypeChar = @"c";
15 | NSString *const MJPropertyTypeBOOL1 = @"c";
16 | NSString *const MJPropertyTypeBOOL2 = @"b";
17 | NSString *const MJPropertyTypePointer = @"*";
18 |
19 | NSString *const MJPropertyTypeIvar = @"^{objc_ivar=}";
20 | NSString *const MJPropertyTypeMethod = @"^{objc_method=}";
21 | NSString *const MJPropertyTypeBlock = @"@?";
22 | NSString *const MJPropertyTypeClass = @"#";
23 | NSString *const MJPropertyTypeSEL = @":";
24 | NSString *const MJPropertyTypeId = @"@";
25 |
26 | #endif
--------------------------------------------------------------------------------
/HBDrawViewDemo/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 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/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 | [NSArray class],
27 | [NSDictionary class],
28 | [NSString class],
29 | [NSAttributedString class], nil];
30 | }
31 | return foundationClasses_;
32 | }
33 |
34 | + (BOOL)isClassFromFoundation:(Class)c
35 | {
36 | if (c == [NSObject class] || c == [NSManagedObject class]) return YES;
37 |
38 | __block BOOL result = NO;
39 | [[self foundationClasses] enumerateObjectsUsingBlock:^(Class foundationClass, BOOL *stop) {
40 | if (c == foundationClass || [c isSubclassOfClass:foundationClass]) {
41 | result = YES;
42 | *stop = YES;
43 | }
44 | }];
45 | return result;
46 | }
47 | @end
48 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/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 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/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 |
13 | @interface MJProperty()
14 | @property (strong, nonatomic) NSMutableDictionary *propertyKeysDict;
15 | @property (strong, nonatomic) NSMutableDictionary *objectClassInArrayDict;
16 | @end
17 |
18 | @implementation MJProperty
19 |
20 | /** originKey作为key,propertyKeys作为value */
21 | static NSMutableDictionary *originKeyPropertyKey_;
22 | + (void)load
23 | {
24 | originKeyPropertyKey_ = [NSMutableDictionary dictionary];
25 | }
26 |
27 | #pragma mark - 懒加载
28 | - (NSMutableDictionary *)propertyKeysDict
29 | {
30 | if (!_propertyKeysDict) {
31 | _propertyKeysDict = [NSMutableDictionary dictionary];
32 | }
33 | return _propertyKeysDict;
34 | }
35 |
36 | - (NSMutableDictionary *)objectClassInArrayDict
37 | {
38 | if (!_objectClassInArrayDict) {
39 | _objectClassInArrayDict = [NSMutableDictionary dictionary];
40 | }
41 | return _objectClassInArrayDict;
42 | }
43 |
44 | #pragma mark - 缓存
45 | + (instancetype)cachedPropertyWithProperty:(objc_property_t)property
46 | {
47 | MJProperty *propertyObj = objc_getAssociatedObject(self, property);
48 | if (propertyObj == nil) {
49 | propertyObj = [[self alloc] init];
50 | propertyObj.property = property;
51 | objc_setAssociatedObject(self, property, propertyObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
52 | }
53 | return propertyObj;
54 | }
55 |
56 | #pragma mark - 公共方法
57 | - (void)setProperty:(objc_property_t)property
58 | {
59 | _property = property;
60 |
61 | MJExtensionAssertParamNotNil(property);
62 |
63 | // 1.属性名
64 | _name = @(property_getName(property));
65 |
66 | // 2.成员类型
67 | NSString *attrs = @(property_getAttributes(property));
68 | NSUInteger loc = 1;
69 | NSUInteger len = [attrs rangeOfString:@","].location - loc;
70 | _type = [MJPropertyType cachedTypeWithCode:[attrs substringWithRange:NSMakeRange(loc, len)]];
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
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 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/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 | return [object count] ? object[self.name.intValue] : nil;
19 | }
20 | return nil;
21 | }
22 | @end
23 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/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
--------------------------------------------------------------------------------
/HBDrawViewDemo/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 | #pragma mark - 缓存
17 | static NSMutableDictionary *cachedTypes_;
18 | + (void)load
19 | {
20 | cachedTypes_ = [NSMutableDictionary dictionary];
21 | }
22 |
23 | + (instancetype)cachedTypeWithCode:(NSString *)code
24 | {
25 | MJExtensionAssertParamNotNil2(code, nil);
26 |
27 | MJPropertyType *type = cachedTypes_[code];
28 | if (type == nil) {
29 | type = [[self alloc] init];
30 | type.code = code;
31 | cachedTypes_[code] = type;
32 | }
33 | return type;
34 | }
35 |
36 | #pragma mark - 公共方法
37 | - (void)setCode:(NSString *)code
38 | {
39 | _code = code;
40 |
41 | MJExtensionAssertParamNotNil(code);
42 |
43 | if ([code isEqualToString:MJPropertyTypeId]) {
44 | _idType = YES;
45 | } else if (code.length == 0) {
46 | _KVCDisabled = YES;
47 | } else if (code.length > 3 && [code hasPrefix:@"@\""]) {
48 | // 去掉@"和",截取中间的类型名称
49 | _code = [code substringWithRange:NSMakeRange(2, code.length - 3)];
50 | _typeClass = NSClassFromString(_code);
51 | _fromFoundation = [MJFoundation isClassFromFoundation:_typeClass];
52 | _numberType = (_typeClass == [NSNumber class] || [_typeClass isSubclassOfClass:[NSNumber class]]);
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, 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 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/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)enumerateClasses:(MJClassesEnumeration)enumeration;
34 | + (void)enumerateAllClasses:(MJClassesEnumeration)enumeration;
35 |
36 | #pragma mark - 属性白名单配置
37 | /**
38 | * 这个数组中的属性名才会进行字典和模型的转换
39 | *
40 | * @param allowedPropertyNames 这个数组中的属性名才会进行字典和模型的转换
41 | */
42 | + (void)setupAllowedPropertyNames:(MJAllowedPropertyNames)allowedPropertyNames;
43 |
44 | /**
45 | * 这个数组中的属性名才会进行字典和模型的转换
46 | */
47 | + (NSMutableArray *)totalAllowedPropertyNames;
48 |
49 | #pragma mark - 属性黑名单配置
50 | /**
51 | * 这个数组中的属性名将会被忽略:不进行字典和模型的转换
52 | *
53 | * @param ignoredPropertyNames 这个数组中的属性名将会被忽略:不进行字典和模型的转换
54 | */
55 | + (void)setupIgnoredPropertyNames:(MJIgnoredPropertyNames)ignoredPropertyNames;
56 |
57 | /**
58 | * 这个数组中的属性名将会被忽略:不进行字典和模型的转换
59 | */
60 | + (NSMutableArray *)totalIgnoredPropertyNames;
61 |
62 | #pragma mark - 归档属性白名单配置
63 | /**
64 | * 这个数组中的属性名才会进行归档
65 | *
66 | * @param allowedCodingPropertyNames 这个数组中的属性名才会进行归档
67 | */
68 | + (void)setupAllowedCodingPropertyNames:(MJAllowedCodingPropertyNames)allowedCodingPropertyNames;
69 |
70 | /**
71 | * 这个数组中的属性名才会进行字典和模型的转换
72 | */
73 | + (NSMutableArray *)totalAllowedCodingPropertyNames;
74 |
75 | #pragma mark - 归档属性黑名单配置
76 | /**
77 | * 这个数组中的属性名将会被忽略:不进行归档
78 | *
79 | * @param ignoredCodingPropertyNames 这个数组中的属性名将会被忽略:不进行归档
80 | */
81 | + (void)setupIgnoredCodingPropertyNames:(MJIgnoredCodingPropertyNames)ignoredCodingPropertyNames;
82 |
83 | /**
84 | * 这个数组中的属性名将会被忽略:不进行归档
85 | */
86 | + (NSMutableArray *)totalIgnoredCodingPropertyNames;
87 |
88 | #pragma mark - 内部使用
89 | + (void)setupBlockReturnValue:(id (^)())block key:(const char *)key dict:(NSMutableDictionary *)dict;
90 | @end
91 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/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 | @implementation NSObject (MJClass)
21 |
22 | static NSMutableDictionary *allowedPropertyNames_;
23 | static NSMutableDictionary *ignoredPropertyNames_;
24 | static NSMutableDictionary *allowedCodingPropertyNames_;
25 | static NSMutableDictionary *ignoredCodingPropertyNames_;
26 | + (void)load
27 | {
28 | allowedPropertyNames_ = [NSMutableDictionary dictionary];
29 | ignoredPropertyNames_ = [NSMutableDictionary dictionary];
30 | allowedCodingPropertyNames_ = [NSMutableDictionary dictionary];
31 | ignoredCodingPropertyNames_ = [NSMutableDictionary dictionary];
32 | }
33 |
34 | + (void)enumerateClasses:(MJClassesEnumeration)enumeration
35 | {
36 | // 1.没有block就直接返回
37 | if (enumeration == nil) return;
38 |
39 | // 2.停止遍历的标记
40 | BOOL stop = NO;
41 |
42 | // 3.当前正在遍历的类
43 | Class c = self;
44 |
45 | // 4.开始遍历每一个类
46 | while (c && !stop) {
47 | // 4.1.执行操作
48 | enumeration(c, &stop);
49 |
50 | // 4.2.获得父类
51 | c = class_getSuperclass(c);
52 |
53 | if ([MJFoundation isClassFromFoundation:c]) break;
54 | }
55 | }
56 |
57 | + (void)enumerateAllClasses:(MJClassesEnumeration)enumeration
58 | {
59 | // 1.没有block就直接返回
60 | if (enumeration == nil) return;
61 |
62 | // 2.停止遍历的标记
63 | BOOL stop = NO;
64 |
65 | // 3.当前正在遍历的类
66 | Class c = self;
67 |
68 | // 4.开始遍历每一个类
69 | while (c && !stop) {
70 | // 4.1.执行操作
71 | enumeration(c, &stop);
72 |
73 | // 4.2.获得父类
74 | c = class_getSuperclass(c);
75 | }
76 | }
77 |
78 | #pragma mark - 属性黑名单配置
79 | + (void)setupIgnoredPropertyNames:(MJIgnoredPropertyNames)ignoredPropertyNames
80 | {
81 | [self setupBlockReturnValue:ignoredPropertyNames key:&MJIgnoredPropertyNamesKey dict:ignoredPropertyNames_];
82 | }
83 |
84 | + (NSMutableArray *)totalIgnoredPropertyNames
85 | {
86 | return [self totalObjectsWithSelector:@selector(ignoredPropertyNames) key:&MJIgnoredPropertyNamesKey dict:ignoredPropertyNames_];
87 | }
88 |
89 | #pragma mark - 归档属性黑名单配置
90 | + (void)setupIgnoredCodingPropertyNames:(MJIgnoredCodingPropertyNames)ignoredCodingPropertyNames
91 | {
92 | [self setupBlockReturnValue:ignoredCodingPropertyNames key:&MJIgnoredCodingPropertyNamesKey dict:ignoredCodingPropertyNames_];
93 | }
94 |
95 | + (NSMutableArray *)totalIgnoredCodingPropertyNames
96 | {
97 | return [self totalObjectsWithSelector:@selector(ignoredCodingPropertyNames) key:&MJIgnoredCodingPropertyNamesKey dict:ignoredCodingPropertyNames_];
98 | }
99 |
100 | #pragma mark - 属性白名单配置
101 | + (void)setupAllowedPropertyNames:(MJAllowedPropertyNames)allowedPropertyNames;
102 | {
103 | [self setupBlockReturnValue:allowedPropertyNames key:&MJAllowedPropertyNamesKey dict:allowedPropertyNames_];
104 | }
105 |
106 | + (NSMutableArray *)totalAllowedPropertyNames
107 | {
108 | return [self totalObjectsWithSelector:@selector(allowedPropertyNames) key:&MJAllowedPropertyNamesKey dict:allowedPropertyNames_];
109 | }
110 |
111 | #pragma mark - 归档属性白名单配置
112 | + (void)setupAllowedCodingPropertyNames:(MJAllowedCodingPropertyNames)allowedCodingPropertyNames
113 | {
114 | [self setupBlockReturnValue:allowedCodingPropertyNames key:&MJAllowedCodingPropertyNamesKey dict:allowedCodingPropertyNames_];
115 | }
116 |
117 | + (NSMutableArray *)totalAllowedCodingPropertyNames
118 | {
119 | return [self totalObjectsWithSelector:@selector(allowedCodingPropertyNames) key:&MJAllowedCodingPropertyNamesKey dict:allowedCodingPropertyNames_];
120 | }
121 | #pragma mark - block和方法处理:存储block的返回值
122 | + (void)setupBlockReturnValue:(id (^)())block key:(const char *)key dict:(NSMutableDictionary *)dict
123 | {
124 | if (block) {
125 | objc_setAssociatedObject(self, key, block(), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
126 | } else {
127 | objc_setAssociatedObject(self, key, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
128 | }
129 |
130 | // 清空数据
131 | [dict removeAllObjects];
132 | }
133 |
134 | + (NSMutableArray *)totalObjectsWithSelector:(SEL)selector key:(const char *)key dict:(NSMutableDictionary *)dict
135 | {
136 | NSMutableArray *array = dict[NSStringFromClass(self)];
137 | if (array) return array;
138 |
139 | // 创建、存储
140 | dict[NSStringFromClass(self)] = array = [NSMutableArray array];
141 |
142 | if ([self respondsToSelector:selector]) {
143 | #pragma clang diagnostic push
144 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
145 | NSArray *subArray = [self performSelector:selector];
146 | #pragma clang diagnostic pop
147 | if (subArray) {
148 | [array addObjectsFromArray:subArray];
149 | }
150 | }
151 |
152 | [self enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
153 | NSArray *subArray = objc_getAssociatedObject(c, key);
154 | [array addObjectsFromArray:subArray];
155 | }];
156 | return array;
157 | }
158 | @end
159 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/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 | /**
11 | * Codeing协议
12 | */
13 | @protocol MJCoding
14 | @optional
15 | /**
16 | * 这个数组中的属性名才会进行归档
17 | */
18 | + (NSArray *)allowedCodingPropertyNames;
19 | /**
20 | * 这个数组中的属性名将会被忽略:不进行归档
21 | */
22 | + (NSArray *)ignoredCodingPropertyNames;
23 | @end
24 |
25 | @interface NSObject (MJCoding)
26 | /**
27 | * 解码(从文件中解析对象)
28 | */
29 | - (void)decode:(NSCoder *)decoder;
30 | /**
31 | * 编码(将对象写入文件中)
32 | */
33 | - (void)encode:(NSCoder *)encoder;
34 | @end
35 |
36 | /**
37 | 归档的实现
38 | */
39 | #define MJCodingImplementation \
40 | - (id)initWithCoder:(NSCoder *)decoder \
41 | { \
42 | if (self = [super init]) { \
43 | [self decode:decoder]; \
44 | } \
45 | return self; \
46 | } \
47 | \
48 | - (void)encodeWithCoder:(NSCoder *)encoder \
49 | { \
50 | [self encode:encoder]; \
51 | }
52 |
53 | #define MJExtensionCodingImplementation MJCodingImplementation
--------------------------------------------------------------------------------
/HBDrawViewDemo/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)encode:(NSCoder *)encoder
17 | {
18 | Class aClass = [self class];
19 |
20 | NSArray *allowedCodingPropertyNames = [aClass totalAllowedCodingPropertyNames];
21 | NSArray *ignoredCodingPropertyNames = [aClass totalIgnoredCodingPropertyNames];
22 |
23 | [aClass 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)decode:(NSCoder *)decoder
35 | {
36 | Class aClass = [self class];
37 |
38 | NSArray *allowedCodingPropertyNames = [aClass totalAllowedCodingPropertyNames];
39 | NSArray *ignoredCodingPropertyNames = [aClass totalIgnoredCodingPropertyNames];
40 |
41 | [aClass 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 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/NSObject+MJKeyValue.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+MJKeyValue.h
3 | // MJExtension
4 | //
5 | // Created by mj on 13-8-24.
6 | // Copyright (c) 2013年 小码哥. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "MJExtensionConst.h"
11 | #import
12 | #import "MJProperty.h"
13 |
14 | /**
15 | * KeyValue协议
16 | */
17 | @protocol MJKeyValue
18 | @optional
19 | /**
20 | * 只有这个数组中的属性名才允许进行字典和模型的转换
21 | */
22 | + (NSArray *)allowedPropertyNames;
23 |
24 | /**
25 | * 这个数组中的属性名将会被忽略:不进行字典和模型的转换
26 | */
27 | + (NSArray *)ignoredPropertyNames;
28 |
29 | /**
30 | * 将属性名换为其他key去字典中取值
31 | *
32 | * @return 字典中的key是属性名,value是从字典中取值用的key
33 | */
34 | + (NSDictionary *)replacedKeyFromPropertyName;
35 |
36 | /**
37 | * 将属性名换为其他key去字典中取值
38 | *
39 | * @return 从字典中取值用的key
40 | */
41 | + (NSString *)replacedKeyFromPropertyName121:(NSString *)propertyName;
42 |
43 | /**
44 | * 数组中需要转换的模型类
45 | *
46 | * @return 字典中的key是数组属性名,value是数组中存放模型的Class(Class类型或者NSString类型)
47 | */
48 | + (NSDictionary *)objectClassInArray;
49 |
50 | /**
51 | * 旧值换新值,用于过滤字典中的值
52 | *
53 | * @param oldValue 旧值
54 | *
55 | * @return 新值
56 | */
57 | - (id)newValueFromOldValue:(id)oldValue property:(MJProperty *)property;
58 |
59 | /**
60 | * 当字典转模型完毕时调用
61 | */
62 | - (void)keyValuesDidFinishConvertingToObject;
63 |
64 | /**
65 | * 当模型转字典完毕时调用
66 | */
67 | - (void)objectDidFinishConvertingToKeyValues;
68 | @end
69 |
70 | @interface NSObject (MJKeyValue)
71 | /**
72 | * 将字典的键值对转成模型属性
73 | * @param keyValues 字典(可以是NSDictionary、NSData、NSString)
74 | */
75 | - (instancetype)setKeyValues:(id)keyValues;
76 | - (instancetype)setKeyValues:(id)keyValues error:(NSError **)error;
77 |
78 | /**
79 | * 将字典的键值对转成模型属性
80 | * @param keyValues 字典(可以是NSDictionary、NSData、NSString)
81 | * @param context CoreData上下文
82 | */
83 | - (instancetype)setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context;
84 | - (instancetype)setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context error:(NSError **)error;
85 |
86 | /**
87 | * 模型转字典时,字典的key是否参考replacedKeyFromPropertyName等方法(父类设置了,子类也会继承下来)
88 | */
89 | + (void)referenceReplacedKeyWhenCreatingKeyValues:(BOOL)reference;
90 |
91 | /**
92 | * 将模型转成字典
93 | * @return 字典
94 | */
95 | - (NSMutableDictionary *)keyValues;
96 | - (NSMutableDictionary *)keyValuesWithError:(NSError **)error;
97 | - (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys;
98 | - (NSMutableDictionary *)keyValuesWithKeys:(NSArray *)keys error:(NSError **)error;
99 | - (NSMutableDictionary *)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys;
100 | - (NSMutableDictionary *)keyValuesWithIgnoredKeys:(NSArray *)ignoredKeys error:(NSError **)error;
101 |
102 | /**
103 | * 通过模型数组来创建一个字典数组
104 | * @param objectArray 模型数组
105 | * @return 字典数组
106 | */
107 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray;
108 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray error:(NSError **)error;
109 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys;
110 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray keys:(NSArray *)keys error:(NSError **)error;
111 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray ignoredKeys:(NSArray *)ignoredKeys;
112 | + (NSMutableArray *)keyValuesArrayWithObjectArray:(NSArray *)objectArray ignoredKeys:(NSArray *)ignoredKeys error:(NSError **)error;
113 |
114 | #pragma mark - 字典转模型
115 | /**
116 | * 通过字典来创建一个模型
117 | * @param keyValues 字典(可以是NSDictionary、NSData、NSString)
118 | * @return 新建的对象
119 | */
120 | + (instancetype)objectWithKeyValues:(id)keyValues;
121 | + (instancetype)objectWithKeyValues:(id)keyValues error:(NSError **)error;
122 |
123 | /**
124 | * 通过字典来创建一个CoreData模型
125 | * @param keyValues 字典(可以是NSDictionary、NSData、NSString)
126 | * @param context CoreData上下文
127 | * @return 新建的对象
128 | */
129 | + (instancetype)objectWithKeyValues:(id)keyValues context:(NSManagedObjectContext *)context;
130 | + (instancetype)objectWithKeyValues:(id)keyValues context:(NSManagedObjectContext *)context error:(NSError **)error;
131 |
132 | /**
133 | * 通过plist来创建一个模型
134 | * @param filename 文件名(仅限于mainBundle中的文件)
135 | * @return 新建的对象
136 | */
137 | + (instancetype)objectWithFilename:(NSString *)filename;
138 | + (instancetype)objectWithFilename:(NSString *)filename error:(NSError **)error;
139 |
140 | /**
141 | * 通过plist来创建一个模型
142 | * @param file 文件全路径
143 | * @return 新建的对象
144 | */
145 | + (instancetype)objectWithFile:(NSString *)file;
146 | + (instancetype)objectWithFile:(NSString *)file error:(NSError **)error;
147 |
148 | #pragma mark - 字典数组转模型数组
149 | /**
150 | * 通过字典数组来创建一个模型数组
151 | * @param keyValuesArray 字典数组(可以是NSDictionary、NSData、NSString)
152 | * @return 模型数组
153 | */
154 | + (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray;
155 | + (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray error:(NSError **)error;
156 |
157 | /**
158 | * 通过字典数组来创建一个模型数组
159 | * @param keyValuesArray 字典数组(可以是NSDictionary、NSData、NSString)
160 | * @param context CoreData上下文
161 | * @return 模型数组
162 | */
163 | + (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context;
164 | + (NSMutableArray *)objectArrayWithKeyValuesArray:(id)keyValuesArray context:(NSManagedObjectContext *)context error:(NSError **)error;
165 |
166 | /**
167 | * 通过plist来创建一个模型数组
168 | * @param filename 文件名(仅限于mainBundle中的文件)
169 | * @return 模型数组
170 | */
171 | + (NSMutableArray *)objectArrayWithFilename:(NSString *)filename;
172 | + (NSMutableArray *)objectArrayWithFilename:(NSString *)filename error:(NSError **)error;
173 |
174 | /**
175 | * 通过plist来创建一个模型数组
176 | * @param file 文件全路径
177 | * @return 模型数组
178 | */
179 | + (NSMutableArray *)objectArrayWithFile:(NSString *)file;
180 | + (NSMutableArray *)objectArrayWithFile:(NSString *)file error:(NSError **)error;
181 |
182 | #pragma mark - 转换为JSON
183 | /**
184 | * 转换为JSON Data
185 | */
186 | - (NSData *)JSONData;
187 | /**
188 | * 转换为字典或者数组
189 | */
190 | - (id)JSONObject;
191 | /**
192 | * 转换为JSON 字符串
193 | */
194 | - (NSString *)JSONString;
195 | @end
196 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/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 |
11 | @class MJProperty;
12 |
13 | /**
14 | * 遍历成员变量用的block
15 | *
16 | * @param property 成员的包装对象
17 | * @param stop YES代表停止遍历,NO代表继续遍历
18 | */
19 | typedef void (^MJPropertiesEnumeration)(MJProperty *property, BOOL *stop);
20 |
21 | /** 将属性名换为其他key去字典中取值 */
22 | typedef NSDictionary * (^MJReplacedKeyFromPropertyName)();
23 | typedef NSString * (^MJReplacedKeyFromPropertyName121)(NSString *propertyName);
24 | /** 数组中需要转换的模型类 */
25 | typedef NSDictionary * (^MJObjectClassInArray)();
26 | /** 用于过滤字典中的值 */
27 | typedef id (^MJNewValueFromOldValue)(id object, id oldValue, MJProperty *property);
28 |
29 | /**
30 | * 成员属性相关的扩展
31 | */
32 | @interface NSObject (MJProperty)
33 | #pragma mark - 遍历
34 | /**
35 | * 遍历所有的成员
36 | */
37 | + (void)enumerateProperties:(MJPropertiesEnumeration)enumeration;
38 |
39 | #pragma mark - 新值配置
40 | /**
41 | * 用于过滤字典中的值
42 | *
43 | * @param newValueFormOldValue 用于过滤字典中的值
44 | */
45 | + (void)setupNewValueFromOldValue:(MJNewValueFromOldValue)newValueFormOldValue;
46 | + (id)getNewValueFromObject:(__weak id)object oldValue:(__weak id)oldValue property:(__weak MJProperty *)property;
47 |
48 | #pragma mark - key配置
49 | /**
50 | * 将属性名换为其他key去字典中取值
51 | *
52 | * @param replacedKeyFromPropertyName 将属性名换为其他key去字典中取值
53 | */
54 | + (void)setupReplacedKeyFromPropertyName:(MJReplacedKeyFromPropertyName)replacedKeyFromPropertyName;
55 | /**
56 | * 将属性名换为其他key去字典中取值
57 | *
58 | * @param replacedKeyFromPropertyName121 将属性名换为其他key去字典中取值
59 | */
60 | + (void)setupReplacedKeyFromPropertyName121:(MJReplacedKeyFromPropertyName121)replacedKeyFromPropertyName121;
61 |
62 | #pragma mark - array model class配置
63 | /**
64 | * 数组中需要转换的模型类
65 | *
66 | * @param objectClassInArray 数组中需要转换的模型类
67 | */
68 | + (void)setupObjectClassInArray:(MJObjectClassInArray)objectClassInArray;
69 | @end
--------------------------------------------------------------------------------
/HBDrawViewDemo/MJExtension/NSObject+MJProperty.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+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 "NSObject+MJProperty.h"
10 | #import "NSObject+MJKeyValue.h"
11 | #import "NSObject+MJCoding.h"
12 | #import "NSObject+MJClass.h"
13 | #import "MJProperty.h"
14 | #import "MJFoundation.h"
15 | #import
16 |
17 | @implementation NSObject (Property)
18 |
19 | static const char MJReplacedKeyFromPropertyNameKey = '\0';
20 | static const char MJReplacedKeyFromPropertyName121Key = '\0';
21 | static const char MJNewValueFromOldValueKey = '\0';
22 | static const char MJObjectClassInArrayKey = '\0';
23 |
24 | static NSMutableDictionary *cachedProperties_;
25 | + (void)load
26 | {
27 | cachedProperties_ = [NSMutableDictionary dictionary];
28 | }
29 |
30 | #pragma mark - --私有方法--
31 | + (NSString *)propertyKey:(NSString *)propertyName
32 | {
33 | MJExtensionAssertParamNotNil2(propertyName, nil);
34 |
35 | __block NSString *key = nil;
36 | // 查看有没有需要替换的key
37 | if ([self respondsToSelector:@selector(replacedKeyFromPropertyName121:)]) {
38 | key = [self replacedKeyFromPropertyName121:propertyName];
39 | }
40 |
41 | // 调用block
42 | if (!key) {
43 | [self enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
44 | MJReplacedKeyFromPropertyName121 block = objc_getAssociatedObject(c, &MJReplacedKeyFromPropertyName121Key);
45 | if (block) {
46 | key = block(propertyName);
47 | }
48 | if (key) *stop = YES;
49 | }];
50 | }
51 |
52 | // 查看有没有需要替换的key
53 | if (!key && [self respondsToSelector:@selector(replacedKeyFromPropertyName)]) {
54 | key = [self replacedKeyFromPropertyName][propertyName];
55 | }
56 |
57 | if (!key) {
58 | [self enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
59 | NSDictionary *dict = objc_getAssociatedObject(c, &MJReplacedKeyFromPropertyNameKey);
60 | if (dict) {
61 | key = dict[propertyName];
62 | }
63 | if (key) *stop = YES;
64 | }];
65 | }
66 |
67 | // 2.用属性名作为key
68 | if (!key) key = propertyName;
69 |
70 | return key;
71 | }
72 |
73 | + (Class)propertyObjectClassInArray:(NSString *)propertyName
74 | {
75 | __block id aClass = nil;
76 | if ([self respondsToSelector:@selector(objectClassInArray)]) {
77 | aClass = [self objectClassInArray][propertyName];
78 | }
79 |
80 | if (!aClass) {
81 | [self enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
82 | NSDictionary *dict = objc_getAssociatedObject(c, &MJObjectClassInArrayKey);
83 | if (dict) {
84 | aClass = dict[propertyName];
85 | }
86 | if (aClass) *stop = YES;
87 | }];
88 | }
89 |
90 | // 如果是NSString类型
91 | if ([aClass isKindOfClass:[NSString class]]) {
92 | aClass = NSClassFromString(aClass);
93 | }
94 | return aClass;
95 | }
96 |
97 | #pragma mark - --公共方法--
98 | + (void)enumerateProperties:(MJPropertiesEnumeration)enumeration
99 | {
100 | // 获得成员变量
101 | NSArray *cachedProperties = [self properties];
102 |
103 | // 遍历成员变量
104 | BOOL stop = NO;
105 | for (MJProperty *property in cachedProperties) {
106 | enumeration(property, &stop);
107 | if (stop) break;
108 | }
109 | }
110 |
111 | #pragma mark - 公共方法
112 | + (NSMutableArray *)properties
113 | {
114 | // 获得成员变量
115 | // 通过关联对象,以及提前定义好的MJCachedPropertiesKey来进行运行时,对所有属性的获取。
116 |
117 | //***objc_getAssociatedObject 方法用于判断当前是否已经获取过MJCachedPropertiesKey对应的关联对象
118 | // 1> 关联到的对象
119 | // 2> 关联的属性 key
120 | NSMutableArray *cachedProperties = cachedProperties_[NSStringFromClass(self)];
121 |
122 | //***
123 | if (cachedProperties == nil) {
124 | cachedProperties = [NSMutableArray array];
125 |
126 | /** 遍历这个类的所有类()不包括NSObject这些基础类 */
127 | [self enumerateClasses:^(__unsafe_unretained Class c, BOOL *stop) {
128 | // 1.获得所有的成员变量
129 | unsigned int outCount = 0;
130 | /**
131 | class_copyIvarList 成员变量,提示有很多第三方框架会使用 Ivar,能够获得更多的信息
132 | 但是:在 swift 中,由于语法结构的变化,使用 Ivar 非常不稳定,经常会崩溃!
133 | class_copyPropertyList 属性
134 | class_copyMethodList 方法
135 | class_copyProtocolList 协议
136 | */
137 | objc_property_t *properties = class_copyPropertyList(c, &outCount);
138 |
139 | // 2.遍历每一个成员变量
140 | for (unsigned int i = 0; i
10 |
11 | @interface NSString (MJExtension)
12 | /**
13 | * 驼峰转下划线(loveYou -> love_you)
14 | */
15 | - (NSString *)underlineFromCamel;
16 | /**
17 | * 下划线转驼峰(love_you -> loveYou)
18 | */
19 | - (NSString *)camelFromUnderline;
20 | /**
21 | * 首字母变大写
22 | */
23 | - (NSString *)firstCharUpper;
24 | /**
25 | * 首字母变小写
26 | */
27 | - (NSString *)firstCharLower;
28 |
29 | - (BOOL)isPureInt;
30 |
31 | - (NSURL *)url;
32 | @end
33 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/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 *)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 *)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 *)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)isPureInt
66 | {
67 | NSScanner *scan = [NSScanner scannerWithString:self];
68 | int val;
69 | return [scan scanInt:&val] && [scan isAtEnd];
70 | }
71 |
72 | - (NSURL *)url
73 | {
74 | return [NSURL URLWithString:(NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)self,(CFStringRef)@"!$&'()*+,-./:;=?@_~%#[]", NULL,kCFStringEncodingUTF8))];
75 | }
76 | @end
77 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // HBDrawViewDemo
4 | //
5 | // Created by 伍宏彬 on 15/11/11.
6 | // Copyright © 2015年 伍宏彬. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // DemoAntiAliasing
4 | //
5 | // Created by Ralph Li on 8/31/15.
6 | // Copyright © 2015 LJC. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "ZYQAssetPickerController.h"
11 | #import "UIView+WHB.h"
12 | #import "HBDrawingBoard.h"
13 | #import "MJExtension.h"
14 |
15 | @interface ViewController ()
16 |
17 |
18 | @property (nonatomic, strong) HBDrawingBoard *drawView;
19 |
20 | @end
21 |
22 | @implementation ViewController
23 |
24 | - (void)viewDidLoad {
25 | [super viewDidLoad];
26 | // Do any additional setup after loading the view, typically from a nib.
27 |
28 | [self.view addSubview:self.drawView];
29 |
30 | }
31 | - (void)viewDidLayoutSubviews
32 | {
33 | [super viewDidLayoutSubviews];
34 |
35 | [self drawSetting:nil];
36 | }
37 | - (IBAction)drawSetting:(id)sender {
38 |
39 | self.drawView.shapType = ((UIButton *)sender).tag;
40 |
41 | [self.drawView showSettingBoard];
42 | }
43 | #pragma mark - UIImagePickerControllerDelegate
44 | - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
45 | {
46 | UIImage *image = info[UIImagePickerControllerOriginalImage];
47 | self.drawView.backImage.image = image;
48 |
49 | __weak typeof(self) weakSelf = self;
50 | [picker dismissViewControllerAnimated:YES completion:^{
51 | [weakSelf.drawView showSettingBoard];
52 | }];
53 |
54 | }
55 | - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
56 | {
57 | __weak typeof(self) weakSelf = self;
58 | [picker dismissViewControllerAnimated:YES completion:^{
59 | [weakSelf.drawView showSettingBoard];
60 | }];
61 | }
62 | #pragma mark - ZYQAssetPickerController Delegate
63 | -(void)assetPickerController:(ZYQAssetPickerController *)picker didFinishPickingAssets:(NSArray *)assets{
64 |
65 | NSMutableArray *marray = [NSMutableArray array];
66 |
67 | for(int i=0;i
12 | #import
13 |
14 | #pragma mark - ZYQAssetPickerController
15 |
16 | @protocol ZYQAssetPickerControllerDelegate;
17 |
18 |
19 | @interface ZYQAssetPickerController : UINavigationController
20 |
21 | @property (nonatomic, weak) id delegate;
22 |
23 |
24 |
25 | @property (nonatomic, strong) ALAssetsFilter *assetsFilter;
26 |
27 | @property (nonatomic, copy, readonly) NSArray *indexPathsForSelectedItems;
28 |
29 | @property (nonatomic, assign) NSInteger maximumNumberOfSelection;
30 | @property (nonatomic, assign) NSInteger minimumNumberOfSelection;
31 |
32 | @property (nonatomic, strong) NSPredicate *selectionFilter;
33 |
34 | @property (nonatomic, assign) BOOL showCancelButton;
35 |
36 | @property (nonatomic, assign) BOOL showEmptyGroups;
37 |
38 | @property (nonatomic, assign) BOOL isFinishDismissViewController;
39 |
40 |
41 | @end
42 |
43 | @protocol ZYQAssetPickerControllerDelegate
44 |
45 | -(void)assetPickerController:(ZYQAssetPickerController *)picker didFinishPickingAssets:(NSArray *)assets;
46 |
47 | @optional
48 |
49 | -(void)assetPickerControllerDidCancel:(ZYQAssetPickerController *)picker;
50 |
51 | -(void)assetPickerController:(ZYQAssetPickerController *)picker didSelectAsset:(ALAsset*)asset;
52 |
53 | -(void)assetPickerController:(ZYQAssetPickerController *)picker didDeselectAsset:(ALAsset*)asset;
54 |
55 | -(void)assetPickerControllerDidMaximum:(ZYQAssetPickerController *)picker;
56 |
57 | -(void)assetPickerControllerDidMinimum:(ZYQAssetPickerController *)picker;
58 |
59 | @end
60 |
61 | #pragma mark - ZYQAssetViewController
62 |
63 | @interface ZYQAssetViewController : UITableViewController
64 |
65 | @property (nonatomic, strong) ALAssetsGroup *assetsGroup;
66 | @property (nonatomic, strong) NSMutableArray *indexPathsForSelectedItems;
67 |
68 | @property (nonatomic,assign) NSInteger number; //新加的,选中的张数
69 |
70 | //@property (nonatomic, strong) UIActivityIndicatorView *activityIndicator;
71 |
72 | @end
73 |
74 | #pragma mark - ZYQVideoTitleView
75 |
76 | @interface ZYQVideoTitleView : UILabel
77 |
78 | @end
79 |
80 | #pragma mark - ZYQTapAssetView
81 |
82 | @protocol ZYQTapAssetViewDelegate
83 |
84 | -(void)touchSelect:(BOOL)select;
85 | -(BOOL)shouldTap;
86 |
87 | @end
88 |
89 | @interface ZYQTapAssetView : UIView
90 |
91 | @property (nonatomic, assign) BOOL selected;
92 | @property (nonatomic, assign) BOOL disabled;
93 | @property (nonatomic, weak) id delegate;
94 |
95 | @end
96 |
97 | #pragma mark - ZYQAssetView
98 |
99 | @protocol ZYQAssetViewDelegate
100 |
101 | -(BOOL)shouldSelectAsset:(ALAsset*)asset;
102 | -(void)tapSelectHandle:(BOOL)select asset:(ALAsset*)asset;
103 |
104 | @end
105 |
106 | @interface ZYQAssetView : UIView
107 |
108 | - (void)bind:(ALAsset *)asset selectionFilter:(NSPredicate*)selectionFilter isSeleced:(BOOL)isSeleced;
109 |
110 | @end
111 |
112 | #pragma mark - ZYQAssetViewCell
113 |
114 | @protocol ZYQAssetViewCellDelegate;
115 |
116 | @interface ZYQAssetViewCell : UITableViewCell
117 |
118 | @property(nonatomic,weak)id delegate;
119 |
120 | - (void)bind:(NSArray *)assets selectionFilter:(NSPredicate*)selectionFilter minimumInteritemSpacing:(float)minimumInteritemSpacing minimumLineSpacing:(float)minimumLineSpacing columns:(int)columns assetViewX:(float)assetViewX;
121 |
122 | @end
123 |
124 | @protocol ZYQAssetViewCellDelegate
125 |
126 | - (BOOL)shouldSelectAsset:(ALAsset*)asset;
127 | - (void)didSelectAsset:(ALAsset*)asset;
128 | - (void)didDeselectAsset:(ALAsset*)asset;
129 |
130 | @end
131 |
132 | #pragma mark - ZYQAssetGroupViewCell
133 |
134 | @interface ZYQAssetGroupViewCell : UITableViewCell
135 |
136 | - (void)bind:(ALAssetsGroup *)assetsGroup;
137 |
138 | @end
139 |
140 | #pragma mark - ZYQAssetGroupViewController
141 |
142 | @interface ZYQAssetGroupViewController : UITableViewController
143 |
144 | @end
145 |
146 |
--------------------------------------------------------------------------------
/HBDrawViewDemo/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // HBDrawViewDemo
4 | //
5 | // Created by 伍宏彬 on 15/11/11.
6 | // Copyright © 2015年 伍宏彬. 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 |
--------------------------------------------------------------------------------
/HBDrawViewDemoTests/HBDrawViewDemoTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // HBDrawViewDemoTests.m
3 | // HBDrawViewDemoTests
4 | //
5 | // Created by 伍宏彬 on 15/11/11.
6 | // Copyright © 2015年 伍宏彬. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface HBDrawViewDemoTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation HBDrawViewDemoTests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 | // Put setup code here. This method is called before the invocation of each test method in the class.
20 | }
21 |
22 | - (void)tearDown {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | [super tearDown];
25 | }
26 |
27 | - (void)testExample {
28 | // This is an example of a functional test case.
29 | // Use XCTAssert and related functions to verify your tests produce the correct results.
30 | }
31 |
32 | - (void)testPerformanceExample {
33 | // This is an example of a performance test case.
34 | [self measureBlock:^{
35 | // Put the code you want to measure the time of here.
36 | }];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/HBDrawViewDemoTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/HBDrawViewDemoUITests/HBDrawViewDemoUITests.m:
--------------------------------------------------------------------------------
1 | //
2 | // HBDrawViewDemoUITests.m
3 | // HBDrawViewDemoUITests
4 | //
5 | // Created by 伍宏彬 on 15/11/11.
6 | // Copyright © 2015年 伍宏彬. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface HBDrawViewDemoUITests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation HBDrawViewDemoUITests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 |
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 |
22 | // In UI tests it is usually best to stop immediately when a failure occurs.
23 | self.continueAfterFailure = NO;
24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
25 | [[[XCUIApplication alloc] init] launch];
26 |
27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
28 | }
29 |
30 | - (void)tearDown {
31 | // Put teardown code here. This method is called after the invocation of each test method in the class.
32 | [super tearDown];
33 | }
34 |
35 | - (void)testExample {
36 | // Use recording to get started writing UI tests.
37 | // Use XCTAssert and related functions to verify your tests produce the correct results.
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/HBDrawViewDemoUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # HBDrawingBoardDemo
2 | ## 画板(涂鸦)实现
3 | ---
4 |
5 | 
6 | 
7 |
8 | ##2017.3.7更新
9 | * 不使用`drawRect`
10 | * 内存消耗低 (把demo中XIB删除掉,内存大概在15M左右)
11 |
12 | ```
13 | //橡皮擦
14 | - (void)setEraseBrush:(HBPath *)path{
15 |
16 | UIGraphicsBeginImageContextWithOptions(self.frame.size, false, 0);
17 |
18 | [self.drawImage.image drawInRect:self.bounds];
19 |
20 | [[UIColor clearColor] set];
21 |
22 | path.bezierPath.lineWidth = _lineWidth;
23 |
24 | [path.bezierPath strokeWithBlendMode:kCGBlendModeClear alpha:1.0];
25 |
26 | [path.bezierPath stroke];
27 |
28 | self.drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
29 |
30 | UIGraphicsEndImageContext();
31 |
32 | }
33 |
34 |
35 | ```
36 |
37 | ### 需求
38 | * 更换`画布背景`(获取 **拍照** 或者 **相册** 的图像)
39 | * 具有`拍照` `截屏`保存功能
40 | * 不同的`画笔颜色,线宽`
41 | * 具有`撤销` `返回` `清屏` `擦除`功能
42 |
43 | ### 思路
44 | 主要分三大块
45 |
46 | * 背景
47 | * 画布
48 | * 画笔的功能界面
49 |
50 | 1.首先获取用户触摸事件`开始`
51 |
52 | ```
53 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
54 | {
55 | CGPoint point = [self getTouchSet:touches];
56 |
57 | HBPath *path = [HBPath pathToPoint:point pathWidth:_lineWidth isEraser:self.ise];
58 |
59 | path.pathColor = _lineColor;
60 |
61 | path.imagePath = [NSString stringWithFormat:@"%@.png",[self getTimeString]];
62 |
63 | [self.paths addObject:path];
64 |
65 | [self.tempPoints addObject:[HBDrawPoint drawPoint:point]];
66 |
67 | if ([self.delegate respondsToSelector:@selector(drawBoard:drawingStatus:model:)]) {
68 | [self.delegate drawBoard:self drawingStatus:HBDrawingStatusBegin model:nil];
69 | }
70 | }
71 | ```
72 | `HBPath`封装的`NSObject`对象
73 |
74 | `paths`:装有`HBPath`对象
75 |
76 | ```
77 | #pragma mark - HBPath
78 | @interface HBPath : NSObject
79 |
80 | @property (nonatomic, strong) UIColor *pathColor;//画笔颜色
81 | @property (nonatomic, assign) CGFloat lineWidth;//线宽
82 | @property (nonatomic, assign) BOOL isEraser;//橡皮擦
83 | @property (nonatomic, assign) HBDrawingShapeType shapType;//绘制样式
84 | @property (nonatomic, copy) NSString *imagePath;//图片路径
85 | @property (nonatomic, strong) UIBezierPath *bezierPath;
86 |
87 |
88 | + (instancetype)pathToPoint:(CGPoint)beginPoint pathWidth:(CGFloat)pathWidth isEraser:(BOOL)isEraser;//初始化对象
89 | - (void)pathLineToPoint:(CGPoint)movePoint WithType:(HBDrawingShapeType)shapeType;//画
90 |
91 | @end
92 |
93 | ```
94 | 2.`移动`
95 |
96 | ```
97 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
98 | {
99 |
100 | CGPoint point = [self getTouchSet:touches];
101 |
102 | HBPath *path = [self.paths lastObject];
103 |
104 | [path pathLineToPoint:point WithType:self.shapType];
105 |
106 | if (self.ise) {
107 | [self setEraseBrush:path];
108 | }else{
109 | [self.drawView setBrush:path];
110 | }
111 |
112 | [self.tempPoints addObject:[HBDrawPoint drawPoint:point]];
113 |
114 | if ([self.delegate respondsToSelector:@selector(drawBoard:drawingStatus:model:)]) {
115 | [self.delegate drawBoard:self drawingStatus:HBDrawingStatusMove model:nil];
116 | }
117 | }
118 |
119 | ```
120 | 3.`结束`
121 |
122 | ```
123 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
124 | {
125 | [self touchesMoved:touches withEvent:event];
126 |
127 | HBPath *path = [self.paths lastObject];
128 |
129 | UIImage *image = [self screenshot:self.drawImage];
130 |
131 | self.drawImage.image = image;
132 |
133 | [self.drawView setBrush:nil];
134 |
135 | NSData *imageData = UIImagePNGRepresentation(image);//UIImageJPEGRepresentation(image, 0.4);
136 |
137 | NSString *filePath = [ThumbnailPath stringByAppendingPathComponent:path.imagePath];
138 |
139 | BOOL isSave = [NSFileManager hb_saveData:imageData filePath:filePath];
140 |
141 | if (isSave) {
142 |
143 | NSLog(@"%@", [NSString stringWithFormat:@"保存成功: %@",filePath]);
144 | }
145 | HBDrawModel *model = [[HBDrawModel alloc] init];
146 | model.paintColor = [_lineColor toColorString];
147 | model.paintSize = @(_lineWidth);
148 | model.isEraser = [NSNumber numberWithBool:path.isEraser];
149 | model.pointList = self.tempPoints;
150 | model.shapType = [NSNumber numberWithInteger:self.shapType];
151 |
152 | if ([self.delegate respondsToSelector:@selector(drawBoard:drawingStatus:model:)]) {
153 | [self.delegate drawBoard:self drawingStatus:HBDrawingStatusEnd model:model];
154 | }
155 |
156 | //清空
157 | [self.tempPoints removeAllObjects];
158 |
159 | }
160 |
161 | ```
162 | >***其中***`HBDrawModel`***对象的作用是:操作结束后传递给外界操作的参数***
163 |
164 | 拥有以下属性:
165 |
166 | ```
167 | /**所有点的集合***/
168 | @property (nonatomic, strong) NSArray * pointList;
169 | /**画笔的颜色***/
170 | @property (nonatomic, copy) NSString * paintColor;
171 | /**背景图片***/
172 | @property (nonatomic, copy) NSString * background;
173 | /**动作 (返回 前进 画 改变背景 清屏)默认是 Action_playing ***/
174 | @property (nonatomic, copy) NSString * action;
175 | /**画笔大小***/
176 | @property (nonatomic, strong) NSNumber * paintSize;
177 | /**设备分辨率 宽***/
178 | @property (nonatomic, strong) NSNumber * width;
179 | /**设备分辨率 高***/
180 | @property (nonatomic, strong) NSNumber * hight;
181 | /**是不是橡皮擦***/
182 | @property (nonatomic, strong) NSNumber * isEraser;
183 |
184 | ```
185 | 4.`绘制`
186 |
187 | ```
188 | - (void)setBrush:(HBPath *)path
189 | {
190 | CAShapeLayer *shapeLayer = (CAShapeLayer *)self.layer;
191 |
192 | shapeLayer.strokeColor = path.pathColor.CGColor;
193 | shapeLayer.fillColor = [UIColor clearColor].CGColor;
194 | shapeLayer.lineJoin = kCALineJoinRound;
195 | shapeLayer.lineCap = kCALineCapRound;
196 | shapeLayer.lineWidth = path.bezierPath.lineWidth;
197 | ((CAShapeLayer *)self.layer).path = path.bezierPath.CGPath;
198 |
199 |
200 | }
201 | ```
202 | >**最后强调一下关于橡皮擦的注意点!**
203 |
204 | >**和绘制线是一样的,区别在于绘制的时候加上下面这句代码。**
205 |
206 | ~~if (self.isEraser)~~
207 | ~~[self.bezierPath strokeWithBlendMode:kCGBlendModeClear alpha:1.0];~~
208 | 更新->在最上面
209 |
210 | **真正的擦除你已经画的线,跟你画布的背景`是不是白色,或者其他颜色`没有关系!如果你的背景是图片,设置画笔的颜色与画布的颜色一致,就不会奏效了。**
211 |
212 | 当然除了上面是使用`贝塞尔路径`绘制以外,你也可以使用上下文去实现,找准这个属性。妈妈再也不用担心橡皮擦啦~~~
213 |
214 | #### 问题
215 | **当两个设备中,一端正在画,另一端绘制对方画的线。如果对方先慢画,后快画。怎么在另一端也绘制出这种速度感??**
216 | **如您知道的话,希望在评论中可以给我一些思路。**
217 | ####解决
218 | 在这里感谢 [@柯拉Sir](http://www.jianshu.com/users/96c00c918ccd) [@梦的森林](http://www.jianshu.com/u/ef83770663b8) 提供的思路。最新的代码已经更新,需要的朋友自取哈。
219 |
220 | >如果这个文章帮到了你,一定给我`Star`哦!
221 |
222 | >[GitHub](https://github.com/WillieWu/HBDrawingBoardDemo.git) **欢迎围观**!!
223 |
--------------------------------------------------------------------------------