├── .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 | ![设置面板.png](http://upload-images.jianshu.io/upload_images/620797-e1ad3a155ac6ca04.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 6 | ![背景.png](http://upload-images.jianshu.io/upload_images/620797-fd9af1591c471961.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 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 | --------------------------------------------------------------------------------