├── README.md
├── SDDrawingBoard.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── xcuserdata
│ └── bnqc.xcuserdatad
│ └── xcschemes
│ └── xcschememanagement.plist
└── SDDrawingBoard
├── AppDelegate.h
├── AppDelegate.m
├── Assets.xcassets
├── AppIcon.appiconset
│ └── Contents.json
├── Contents.json
├── slider_thumb.imageset
│ ├── Contents.json
│ ├── 进度按钮@2x.png
│ └── 进度按钮@3x.png
├── 圆形.imageset
│ ├── Contents.json
│ └── 圆形.png
├── 曲线.imageset
│ ├── Contents.json
│ └── 曲线.png
├── 矩形.imageset
│ ├── Contents.json
│ └── 矩形 (1).png
└── 箭头.imageset
│ ├── Contents.json
│ └── 箭头.png
├── Base.lproj
├── LaunchScreen.storyboard
└── Main.storyboard
├── DrawViewController.h
├── DrawViewController.m
├── Info.plist
├── SDDrawView
├── SDBezierPath.h
├── SDBezierPath.m
├── SDDrawView.h
└── SDDrawView.m
├── UIImage+Color.h
├── UIImage+Color.m
└── main.m
/README.md:
--------------------------------------------------------------------------------
1 | # SDDrawView
2 | SDDrawView is iOS DrawingBoard ,SDDrawView have a good arrow's draw way!!! welcome download SDDrawView
3 |
4 | SDDrawView 是 iOS的一个画板工具组件,简单上手~ 包含了线条、矩形、圆形、箭头.颜色设置,线条宽度设置,这里说一下SDDrawView最大的特点就是箭头 不再是以往的那种一个三角形加上一个矩形的样式 而是类似于QQ截图中的矩形,更加的圆滑,欢迎下载尝试!
5 |
6 |
7 |
8 | #### SDDrawView简介
9 | ***
10 | SDDrawView 是一款基于贝塞尔曲线的画板组件,目前样式包含线条、矩形、圆形、箭头等样式.具有调整画板颜色,线条宽度,线条颜色等基本功能.后期准备接入图片涂改,橡皮擦功能,添加文字等功能.至于为什么要做SDDrawView这样的一个三方画板组件,其实SDDrawView大部分功能和现在网上的画板组件都是类似的,是一个不折不扣的造轮子组件.其实,在网上找了很多的画板组件三方中**箭头**样式令人不是太满意显得非常的生硬,大部分是一个矩形加一个三角形组成的多边形箭头.SDDrawView的箭头样式却不同,SDDrawView箭头样式更类似于QQ截图中的箭头,更加的圆滑更加趋近于现实.接下来,看一下SDDrawView的效果演示图.
11 |
12 | 
13 |
14 |
15 |
16 |
17 | #### SDDrawView快速集成
18 | ***
19 | 如何快速集成SDDrawView?非常简单,只需要把[SDDrawViewDemo](https://github.com/wang82426107/SDDrawView)下载下来,然后把Demo中的**SDDrawView**文件夹拖到你的工程中,然后如下导入头文件即可.
20 | ```
21 | #import "SDDrawView.h"
22 | ```
23 | SDDrawView初始化也比较简单.我们初始化一个SDDrawView对象然后添加到对应的View视图上即可.
24 | ```
25 | //懒加载的形式初始化(可用可不用~)
26 | - (SDDrawView *)drawView{
27 |
28 | if(_drawView == nil){
29 | _drawView = [[SDDrawView alloc] initWithFrame:[UIScreen mainScreen].bounds];
30 | _drawView.drawViewColor = [UIColor whiteColor];//画板颜色
31 | _drawView.lineWidth = 2.0f;//线条宽度
32 | _drawView.drawStyle = DrawStyleLine;//样式
33 | _drawView.lineColor = [UIColor redColor];//线条颜色
34 | }
35 | return _drawView;
36 |
37 | }
38 | ```
39 | 图形样式选择是一个枚举值,只需设定对应的样式,就可绘制不同的图形.
40 | ```
41 | typedef enum : NSUInteger {
42 | DrawStyleLine,
43 | DrawStyleSquare,
44 | DrawStyleCircle,
45 | DrawStyleArrow
46 | } DrawStyle;
47 | ```
48 |
49 | 这里说明一下**SDDrawView**所有的属性和方法.
50 |
51 | |属性或者方法|说明|
52 | |:---:|:---:|
53 | |drawViewColor|画板颜色|
54 | |lineWidth|画笔宽度|
55 | |drawStyle|绘制样式 值为DrawStyle的枚举值|
56 | |lineColor|画笔颜色|
57 | |- (void)cleanAction;|清除画板|
58 | |- (void)rollbackAction;|回退上一步|
59 |
60 |
61 |
62 |
63 |
64 | #### [实现过程博客地址传送门](https://www.jianshu.com/p/b778008c61c8)
65 |
--------------------------------------------------------------------------------
/SDDrawingBoard.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | E13E66BA20F43C6D004852A3 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E13E66B920F43C6D004852A3 /* AppDelegate.m */; };
11 | E13E66C020F43C6D004852A3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E13E66BE20F43C6D004852A3 /* Main.storyboard */; };
12 | E13E66C220F43C6F004852A3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E13E66C120F43C6F004852A3 /* Assets.xcassets */; };
13 | E13E66C520F43C6F004852A3 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E13E66C320F43C6F004852A3 /* LaunchScreen.storyboard */; };
14 | E13E66C820F43C6F004852A3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E13E66C720F43C6F004852A3 /* main.m */; };
15 | E13E66D220F43D2B004852A3 /* SDBezierPath.m in Sources */ = {isa = PBXBuildFile; fileRef = E13E66CF20F43D2B004852A3 /* SDBezierPath.m */; };
16 | E13E66D320F43D2B004852A3 /* SDDrawView.m in Sources */ = {isa = PBXBuildFile; fileRef = E13E66D120F43D2B004852A3 /* SDDrawView.m */; };
17 | E1E81DEB20F6FCE900C22ACE /* UIImage+Color.m in Sources */ = {isa = PBXBuildFile; fileRef = E1E81DE920F6FCE900C22ACE /* UIImage+Color.m */; };
18 | E1E81DEE20F7138900C22ACE /* DrawViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E1E81DED20F7138900C22ACE /* DrawViewController.m */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXFileReference section */
22 | E13E66B520F43C6D004852A3 /* SDDrawingBoard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SDDrawingBoard.app; sourceTree = BUILT_PRODUCTS_DIR; };
23 | E13E66B820F43C6D004852A3 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
24 | E13E66B920F43C6D004852A3 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
25 | E13E66BF20F43C6D004852A3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
26 | E13E66C120F43C6F004852A3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
27 | E13E66C420F43C6F004852A3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
28 | E13E66C620F43C6F004852A3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
29 | E13E66C720F43C6F004852A3 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
30 | E13E66CE20F43D2B004852A3 /* SDBezierPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDBezierPath.h; sourceTree = ""; };
31 | E13E66CF20F43D2B004852A3 /* SDBezierPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDBezierPath.m; sourceTree = ""; };
32 | E13E66D020F43D2B004852A3 /* SDDrawView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDDrawView.h; sourceTree = ""; };
33 | E13E66D120F43D2B004852A3 /* SDDrawView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDDrawView.m; sourceTree = ""; };
34 | E1E81DE920F6FCE900C22ACE /* UIImage+Color.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Color.m"; sourceTree = ""; };
35 | E1E81DEA20F6FCE900C22ACE /* UIImage+Color.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Color.h"; sourceTree = ""; };
36 | E1E81DEC20F7138900C22ACE /* DrawViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DrawViewController.h; sourceTree = ""; };
37 | E1E81DED20F7138900C22ACE /* DrawViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DrawViewController.m; sourceTree = ""; };
38 | /* End PBXFileReference section */
39 |
40 | /* Begin PBXFrameworksBuildPhase section */
41 | E13E66B220F43C6D004852A3 /* Frameworks */ = {
42 | isa = PBXFrameworksBuildPhase;
43 | buildActionMask = 2147483647;
44 | files = (
45 | );
46 | runOnlyForDeploymentPostprocessing = 0;
47 | };
48 | /* End PBXFrameworksBuildPhase section */
49 |
50 | /* Begin PBXGroup section */
51 | E13E66AC20F43C6D004852A3 = {
52 | isa = PBXGroup;
53 | children = (
54 | E13E66B720F43C6D004852A3 /* SDDrawingBoard */,
55 | E13E66B620F43C6D004852A3 /* Products */,
56 | );
57 | sourceTree = "";
58 | };
59 | E13E66B620F43C6D004852A3 /* Products */ = {
60 | isa = PBXGroup;
61 | children = (
62 | E13E66B520F43C6D004852A3 /* SDDrawingBoard.app */,
63 | );
64 | name = Products;
65 | sourceTree = "";
66 | };
67 | E13E66B720F43C6D004852A3 /* SDDrawingBoard */ = {
68 | isa = PBXGroup;
69 | children = (
70 | E13E66B820F43C6D004852A3 /* AppDelegate.h */,
71 | E13E66B920F43C6D004852A3 /* AppDelegate.m */,
72 | E1E81DEC20F7138900C22ACE /* DrawViewController.h */,
73 | E1E81DED20F7138900C22ACE /* DrawViewController.m */,
74 | E1E81DEA20F6FCE900C22ACE /* UIImage+Color.h */,
75 | E1E81DE920F6FCE900C22ACE /* UIImage+Color.m */,
76 | E13E66D420F43D4B004852A3 /* SDDrawView */,
77 | E13E66BE20F43C6D004852A3 /* Main.storyboard */,
78 | E13E66C120F43C6F004852A3 /* Assets.xcassets */,
79 | E13E66C320F43C6F004852A3 /* LaunchScreen.storyboard */,
80 | E13E66C620F43C6F004852A3 /* Info.plist */,
81 | E13E66C720F43C6F004852A3 /* main.m */,
82 | );
83 | path = SDDrawingBoard;
84 | sourceTree = "";
85 | };
86 | E13E66D420F43D4B004852A3 /* SDDrawView */ = {
87 | isa = PBXGroup;
88 | children = (
89 | E13E66D020F43D2B004852A3 /* SDDrawView.h */,
90 | E13E66D120F43D2B004852A3 /* SDDrawView.m */,
91 | E13E66CE20F43D2B004852A3 /* SDBezierPath.h */,
92 | E13E66CF20F43D2B004852A3 /* SDBezierPath.m */,
93 | );
94 | path = SDDrawView;
95 | sourceTree = "";
96 | };
97 | /* End PBXGroup section */
98 |
99 | /* Begin PBXNativeTarget section */
100 | E13E66B420F43C6D004852A3 /* SDDrawingBoard */ = {
101 | isa = PBXNativeTarget;
102 | buildConfigurationList = E13E66CB20F43C6F004852A3 /* Build configuration list for PBXNativeTarget "SDDrawingBoard" */;
103 | buildPhases = (
104 | E13E66B120F43C6D004852A3 /* Sources */,
105 | E13E66B220F43C6D004852A3 /* Frameworks */,
106 | E13E66B320F43C6D004852A3 /* Resources */,
107 | );
108 | buildRules = (
109 | );
110 | dependencies = (
111 | );
112 | name = SDDrawingBoard;
113 | productName = SDDrawingBoard;
114 | productReference = E13E66B520F43C6D004852A3 /* SDDrawingBoard.app */;
115 | productType = "com.apple.product-type.application";
116 | };
117 | /* End PBXNativeTarget section */
118 |
119 | /* Begin PBXProject section */
120 | E13E66AD20F43C6D004852A3 /* Project object */ = {
121 | isa = PBXProject;
122 | attributes = {
123 | LastUpgradeCheck = 0940;
124 | ORGANIZATIONNAME = Dong;
125 | TargetAttributes = {
126 | E13E66B420F43C6D004852A3 = {
127 | CreatedOnToolsVersion = 9.4.1;
128 | };
129 | };
130 | };
131 | buildConfigurationList = E13E66B020F43C6D004852A3 /* Build configuration list for PBXProject "SDDrawingBoard" */;
132 | compatibilityVersion = "Xcode 9.3";
133 | developmentRegion = en;
134 | hasScannedForEncodings = 0;
135 | knownRegions = (
136 | en,
137 | Base,
138 | );
139 | mainGroup = E13E66AC20F43C6D004852A3;
140 | productRefGroup = E13E66B620F43C6D004852A3 /* Products */;
141 | projectDirPath = "";
142 | projectRoot = "";
143 | targets = (
144 | E13E66B420F43C6D004852A3 /* SDDrawingBoard */,
145 | );
146 | };
147 | /* End PBXProject section */
148 |
149 | /* Begin PBXResourcesBuildPhase section */
150 | E13E66B320F43C6D004852A3 /* Resources */ = {
151 | isa = PBXResourcesBuildPhase;
152 | buildActionMask = 2147483647;
153 | files = (
154 | E13E66C520F43C6F004852A3 /* LaunchScreen.storyboard in Resources */,
155 | E13E66C220F43C6F004852A3 /* Assets.xcassets in Resources */,
156 | E13E66C020F43C6D004852A3 /* Main.storyboard in Resources */,
157 | );
158 | runOnlyForDeploymentPostprocessing = 0;
159 | };
160 | /* End PBXResourcesBuildPhase section */
161 |
162 | /* Begin PBXSourcesBuildPhase section */
163 | E13E66B120F43C6D004852A3 /* Sources */ = {
164 | isa = PBXSourcesBuildPhase;
165 | buildActionMask = 2147483647;
166 | files = (
167 | E13E66D320F43D2B004852A3 /* SDDrawView.m in Sources */,
168 | E1E81DEE20F7138900C22ACE /* DrawViewController.m in Sources */,
169 | E13E66C820F43C6F004852A3 /* main.m in Sources */,
170 | E1E81DEB20F6FCE900C22ACE /* UIImage+Color.m in Sources */,
171 | E13E66D220F43D2B004852A3 /* SDBezierPath.m in Sources */,
172 | E13E66BA20F43C6D004852A3 /* AppDelegate.m in Sources */,
173 | );
174 | runOnlyForDeploymentPostprocessing = 0;
175 | };
176 | /* End PBXSourcesBuildPhase section */
177 |
178 | /* Begin PBXVariantGroup section */
179 | E13E66BE20F43C6D004852A3 /* Main.storyboard */ = {
180 | isa = PBXVariantGroup;
181 | children = (
182 | E13E66BF20F43C6D004852A3 /* Base */,
183 | );
184 | name = Main.storyboard;
185 | sourceTree = "";
186 | };
187 | E13E66C320F43C6F004852A3 /* LaunchScreen.storyboard */ = {
188 | isa = PBXVariantGroup;
189 | children = (
190 | E13E66C420F43C6F004852A3 /* Base */,
191 | );
192 | name = LaunchScreen.storyboard;
193 | sourceTree = "";
194 | };
195 | /* End PBXVariantGroup section */
196 |
197 | /* Begin XCBuildConfiguration section */
198 | E13E66C920F43C6F004852A3 /* Debug */ = {
199 | isa = XCBuildConfiguration;
200 | buildSettings = {
201 | ALWAYS_SEARCH_USER_PATHS = NO;
202 | CLANG_ANALYZER_NONNULL = YES;
203 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
204 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
205 | CLANG_CXX_LIBRARY = "libc++";
206 | CLANG_ENABLE_MODULES = YES;
207 | CLANG_ENABLE_OBJC_ARC = YES;
208 | CLANG_ENABLE_OBJC_WEAK = YES;
209 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
210 | CLANG_WARN_BOOL_CONVERSION = YES;
211 | CLANG_WARN_COMMA = YES;
212 | CLANG_WARN_CONSTANT_CONVERSION = YES;
213 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
214 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
215 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
216 | CLANG_WARN_EMPTY_BODY = YES;
217 | CLANG_WARN_ENUM_CONVERSION = YES;
218 | CLANG_WARN_INFINITE_RECURSION = YES;
219 | CLANG_WARN_INT_CONVERSION = YES;
220 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
221 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
222 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
223 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
224 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
225 | CLANG_WARN_STRICT_PROTOTYPES = YES;
226 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
227 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
228 | CLANG_WARN_UNREACHABLE_CODE = YES;
229 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
230 | CODE_SIGN_IDENTITY = "iPhone Developer";
231 | COPY_PHASE_STRIP = NO;
232 | DEBUG_INFORMATION_FORMAT = dwarf;
233 | ENABLE_STRICT_OBJC_MSGSEND = YES;
234 | ENABLE_TESTABILITY = YES;
235 | GCC_C_LANGUAGE_STANDARD = gnu11;
236 | GCC_DYNAMIC_NO_PIC = NO;
237 | GCC_NO_COMMON_BLOCKS = YES;
238 | GCC_OPTIMIZATION_LEVEL = 0;
239 | GCC_PREPROCESSOR_DEFINITIONS = (
240 | "DEBUG=1",
241 | "$(inherited)",
242 | );
243 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
244 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
245 | GCC_WARN_UNDECLARED_SELECTOR = YES;
246 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
247 | GCC_WARN_UNUSED_FUNCTION = YES;
248 | GCC_WARN_UNUSED_VARIABLE = YES;
249 | IPHONEOS_DEPLOYMENT_TARGET = 11.4;
250 | MTL_ENABLE_DEBUG_INFO = YES;
251 | ONLY_ACTIVE_ARCH = YES;
252 | SDKROOT = iphoneos;
253 | };
254 | name = Debug;
255 | };
256 | E13E66CA20F43C6F004852A3 /* Release */ = {
257 | isa = XCBuildConfiguration;
258 | buildSettings = {
259 | ALWAYS_SEARCH_USER_PATHS = NO;
260 | CLANG_ANALYZER_NONNULL = YES;
261 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
262 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
263 | CLANG_CXX_LIBRARY = "libc++";
264 | CLANG_ENABLE_MODULES = YES;
265 | CLANG_ENABLE_OBJC_ARC = YES;
266 | CLANG_ENABLE_OBJC_WEAK = YES;
267 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
268 | CLANG_WARN_BOOL_CONVERSION = YES;
269 | CLANG_WARN_COMMA = YES;
270 | CLANG_WARN_CONSTANT_CONVERSION = YES;
271 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
272 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
273 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
274 | CLANG_WARN_EMPTY_BODY = YES;
275 | CLANG_WARN_ENUM_CONVERSION = YES;
276 | CLANG_WARN_INFINITE_RECURSION = YES;
277 | CLANG_WARN_INT_CONVERSION = YES;
278 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
279 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
280 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
281 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
282 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
283 | CLANG_WARN_STRICT_PROTOTYPES = YES;
284 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
285 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
286 | CLANG_WARN_UNREACHABLE_CODE = YES;
287 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
288 | CODE_SIGN_IDENTITY = "iPhone Developer";
289 | COPY_PHASE_STRIP = NO;
290 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
291 | ENABLE_NS_ASSERTIONS = NO;
292 | ENABLE_STRICT_OBJC_MSGSEND = YES;
293 | GCC_C_LANGUAGE_STANDARD = gnu11;
294 | GCC_NO_COMMON_BLOCKS = YES;
295 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
296 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
297 | GCC_WARN_UNDECLARED_SELECTOR = YES;
298 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
299 | GCC_WARN_UNUSED_FUNCTION = YES;
300 | GCC_WARN_UNUSED_VARIABLE = YES;
301 | IPHONEOS_DEPLOYMENT_TARGET = 11.4;
302 | MTL_ENABLE_DEBUG_INFO = NO;
303 | SDKROOT = iphoneos;
304 | VALIDATE_PRODUCT = YES;
305 | };
306 | name = Release;
307 | };
308 | E13E66CC20F43C6F004852A3 /* Debug */ = {
309 | isa = XCBuildConfiguration;
310 | buildSettings = {
311 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
312 | CODE_SIGN_STYLE = Automatic;
313 | DEVELOPMENT_TEAM = T83P3V4T3D;
314 | INFOPLIST_FILE = SDDrawingBoard/Info.plist;
315 | LD_RUNPATH_SEARCH_PATHS = (
316 | "$(inherited)",
317 | "@executable_path/Frameworks",
318 | );
319 | PRODUCT_BUNDLE_IDENTIFIER = com.dong.SDDrawingBoard;
320 | PRODUCT_NAME = "$(TARGET_NAME)";
321 | TARGETED_DEVICE_FAMILY = "1,2";
322 | };
323 | name = Debug;
324 | };
325 | E13E66CD20F43C6F004852A3 /* Release */ = {
326 | isa = XCBuildConfiguration;
327 | buildSettings = {
328 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
329 | CODE_SIGN_STYLE = Automatic;
330 | DEVELOPMENT_TEAM = T83P3V4T3D;
331 | INFOPLIST_FILE = SDDrawingBoard/Info.plist;
332 | LD_RUNPATH_SEARCH_PATHS = (
333 | "$(inherited)",
334 | "@executable_path/Frameworks",
335 | );
336 | PRODUCT_BUNDLE_IDENTIFIER = com.dong.SDDrawingBoard;
337 | PRODUCT_NAME = "$(TARGET_NAME)";
338 | TARGETED_DEVICE_FAMILY = "1,2";
339 | };
340 | name = Release;
341 | };
342 | /* End XCBuildConfiguration section */
343 |
344 | /* Begin XCConfigurationList section */
345 | E13E66B020F43C6D004852A3 /* Build configuration list for PBXProject "SDDrawingBoard" */ = {
346 | isa = XCConfigurationList;
347 | buildConfigurations = (
348 | E13E66C920F43C6F004852A3 /* Debug */,
349 | E13E66CA20F43C6F004852A3 /* Release */,
350 | );
351 | defaultConfigurationIsVisible = 0;
352 | defaultConfigurationName = Release;
353 | };
354 | E13E66CB20F43C6F004852A3 /* Build configuration list for PBXNativeTarget "SDDrawingBoard" */ = {
355 | isa = XCConfigurationList;
356 | buildConfigurations = (
357 | E13E66CC20F43C6F004852A3 /* Debug */,
358 | E13E66CD20F43C6F004852A3 /* Release */,
359 | );
360 | defaultConfigurationIsVisible = 0;
361 | defaultConfigurationName = Release;
362 | };
363 | /* End XCConfigurationList section */
364 | };
365 | rootObject = E13E66AD20F43C6D004852A3 /* Project object */;
366 | }
367 |
--------------------------------------------------------------------------------
/SDDrawingBoard.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SDDrawingBoard.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SDDrawingBoard.xcodeproj/xcuserdata/bnqc.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SDDrawingBoard.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/SDDrawingBoard/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // SDDrawingBoard
4 | //
5 | // Created by bnqc on 2018/7/10.
6 | // Copyright © 2018年 Dong. 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 |
--------------------------------------------------------------------------------
/SDDrawingBoard/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // SDDrawingBoard
4 | //
5 | // Created by bnqc on 2018/7/10.
6 | // Copyright © 2018年 Dong. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "DrawViewController.h"
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 |
20 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
21 | self.window.backgroundColor = [UIColor whiteColor];
22 | UINavigationController *rootNavigationVC = [[UINavigationController alloc] initWithRootViewController:[[DrawViewController alloc] init]];
23 | self.window.rootViewController = rootNavigationVC;
24 | [self.window makeKeyAndVisible];
25 | return YES;
26 | }
27 |
28 |
29 | - (void)applicationWillResignActive:(UIApplication *)application {
30 | // 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.
31 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
32 | }
33 |
34 |
35 | - (void)applicationDidEnterBackground:(UIApplication *)application {
36 | // 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.
37 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
38 | }
39 |
40 |
41 | - (void)applicationWillEnterForeground:(UIApplication *)application {
42 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
43 | }
44 |
45 |
46 | - (void)applicationDidBecomeActive:(UIApplication *)application {
47 | // 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.
48 | }
49 |
50 |
51 | - (void)applicationWillTerminate:(UIApplication *)application {
52 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
53 | }
54 |
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/SDDrawingBoard/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 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/SDDrawingBoard/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/SDDrawingBoard/Assets.xcassets/slider_thumb.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "进度按钮@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "进度按钮@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/SDDrawingBoard/Assets.xcassets/slider_thumb.imageset/进度按钮@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wang82426107/SDDrawView/7cef77bd6f7777785265465088a62fdd37f75587/SDDrawingBoard/Assets.xcassets/slider_thumb.imageset/进度按钮@2x.png
--------------------------------------------------------------------------------
/SDDrawingBoard/Assets.xcassets/slider_thumb.imageset/进度按钮@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wang82426107/SDDrawView/7cef77bd6f7777785265465088a62fdd37f75587/SDDrawingBoard/Assets.xcassets/slider_thumb.imageset/进度按钮@3x.png
--------------------------------------------------------------------------------
/SDDrawingBoard/Assets.xcassets/圆形.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "圆形.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 | }
--------------------------------------------------------------------------------
/SDDrawingBoard/Assets.xcassets/圆形.imageset/圆形.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wang82426107/SDDrawView/7cef77bd6f7777785265465088a62fdd37f75587/SDDrawingBoard/Assets.xcassets/圆形.imageset/圆形.png
--------------------------------------------------------------------------------
/SDDrawingBoard/Assets.xcassets/曲线.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "曲线.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 | }
--------------------------------------------------------------------------------
/SDDrawingBoard/Assets.xcassets/曲线.imageset/曲线.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wang82426107/SDDrawView/7cef77bd6f7777785265465088a62fdd37f75587/SDDrawingBoard/Assets.xcassets/曲线.imageset/曲线.png
--------------------------------------------------------------------------------
/SDDrawingBoard/Assets.xcassets/矩形.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "矩形 (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 | }
--------------------------------------------------------------------------------
/SDDrawingBoard/Assets.xcassets/矩形.imageset/矩形 (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wang82426107/SDDrawView/7cef77bd6f7777785265465088a62fdd37f75587/SDDrawingBoard/Assets.xcassets/矩形.imageset/矩形 (1).png
--------------------------------------------------------------------------------
/SDDrawingBoard/Assets.xcassets/箭头.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "箭头.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 | }
--------------------------------------------------------------------------------
/SDDrawingBoard/Assets.xcassets/箭头.imageset/箭头.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wang82426107/SDDrawView/7cef77bd6f7777785265465088a62fdd37f75587/SDDrawingBoard/Assets.xcassets/箭头.imageset/箭头.png
--------------------------------------------------------------------------------
/SDDrawingBoard/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 |
--------------------------------------------------------------------------------
/SDDrawingBoard/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 |
--------------------------------------------------------------------------------
/SDDrawingBoard/DrawViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DrawViewController.h
3 | // SDDrawingBoard
4 | //
5 | // Created by bnqc on 2018/7/12.
6 | // Copyright © 2018年 Dong. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DrawViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/SDDrawingBoard/DrawViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DrawViewController.m
3 | // SDDrawingBoard
4 | //
5 | // Created by bnqc on 2018/7/12.
6 | // Copyright © 2018年 Dong. All rights reserved.
7 | //
8 |
9 | #import "DrawViewController.h"
10 | #import "UIImage+Color.h"
11 | #import "SDDrawView.h"
12 | #define KcurrentSystemVersion [[UIDevice currentDevice] systemVersion]
13 | #define KmainHeight [UIScreen mainScreen].bounds.size.height
14 | #define KmainWidth [UIScreen mainScreen].bounds.size.width
15 | #define StatusHeight ([[UIApplication sharedApplication]statusBarFrame].size.height)
16 | #define NavigationBarHeight (44.0f)
17 |
18 | @interface DrawViewController ()
19 |
20 | @property(nonatomic,strong)SDDrawView *drawView;
21 | @property(nonatomic,strong)UIButton *lineButton;
22 | @property(nonatomic,strong)UIButton *squareButton;
23 | @property(nonatomic,strong)UIButton *circleButton;
24 | @property(nonatomic,strong)UIButton *arrowButton;
25 | @property(nonatomic,strong)UISlider *lineWidthSlider;//调整线条滑块
26 | @property(nonatomic,strong)UILabel *lineWidthLabel;//调整线条宽度的Label
27 | @property(nonatomic,strong)UIButton *redButton;
28 | @property(nonatomic,strong)UIButton *greenButton;
29 | @property(nonatomic,strong)UIButton *orangeButton;
30 |
31 | @end
32 |
33 | @implementation DrawViewController
34 |
35 | - (void)viewDidLoad {
36 |
37 | [super viewDidLoad];
38 | [self loadNavigationBarAction];
39 | [self.view addSubview:self.lineButton];
40 | [self.view addSubview:self.squareButton];
41 | [self.view addSubview:self.circleButton];
42 | [self.view addSubview:self.arrowButton];
43 | [self.view addSubview:self.drawView];
44 | [self.view addSubview:self.lineWidthSlider];
45 | [self.view addSubview:self.lineWidthLabel];
46 | [self.view addSubview:self.redButton];
47 | [self.view addSubview:self.greenButton];
48 | [self.view addSubview:self.orangeButton];
49 | self.view.backgroundColor = [UIColor whiteColor];
50 |
51 | }
52 |
53 | - (void)viewSafeAreaInsetsDidChange{
54 |
55 | [super viewSafeAreaInsetsDidChange];
56 | if ([KcurrentSystemVersion intValue] > 11.0) {
57 | self.additionalSafeAreaInsets = UIEdgeInsetsMake(44, 0, 0, 10);
58 | }
59 |
60 | }
61 |
62 | - (void)loadNavigationBarAction{
63 |
64 | self.navigationItem.title = @"画板功能";
65 | self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"清空画板" style:UIBarButtonItemStyleDone target:self action:@selector(clearDrawViewAction)];
66 | self.navigationItem.leftBarButtonItem.tintColor = [UIColor blackColor];
67 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"回退上一步" style:UIBarButtonItemStyleDone target:self action:@selector(rollbackDrawViewAction)];
68 | self.navigationItem.rightBarButtonItem.tintColor = [UIColor blackColor];
69 |
70 | }
71 |
72 | - (void)clearDrawViewAction{
73 |
74 | [_drawView cleanAction];
75 |
76 | }
77 |
78 | - (void)rollbackDrawViewAction{
79 |
80 | [_drawView rollbackAction];
81 |
82 | }
83 |
84 | #pragma mark - 懒加载(这种情况没毛用,习惯而已)
85 | - (UIButton *)lineButton{
86 |
87 | if(_lineButton == nil){
88 | _lineButton = [[UIButton alloc] initWithFrame:CGRectMake(0, StatusHeight + NavigationBarHeight, KmainWidth/4.0, 40)];
89 | _lineButton.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1];
90 | _lineButton.selected = YES;
91 | [_lineButton setTitle:@" 直线" forState:UIControlStateNormal];
92 | [_lineButton setImage:[UIImage imageNamed:@"曲线"] forState:UIControlStateNormal];
93 | [_lineButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
94 | [_lineButton setTitleColor:[UIColor redColor] forState:UIControlStateSelected];
95 | [_lineButton addTarget:self action:@selector(selectLineDrawType:) forControlEvents:UIControlEventTouchUpInside];
96 | }
97 | return _lineButton;
98 | }
99 |
100 | - (UIButton *)squareButton{
101 |
102 | if(_squareButton == nil){
103 | _squareButton = [[UIButton alloc] initWithFrame:CGRectMake(KmainWidth/4.0, StatusHeight + NavigationBarHeight, KmainWidth/4.0, 40)];
104 | _squareButton.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1];
105 | [_squareButton setTitle:@" 矩形" forState:UIControlStateNormal];
106 | [_squareButton setImage:[UIImage imageNamed:@"矩形"] forState:UIControlStateNormal];
107 | [_squareButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
108 | [_squareButton setTitleColor:[UIColor redColor] forState:UIControlStateSelected];
109 | [_squareButton addTarget:self action:@selector(selectLineDrawType:) forControlEvents:UIControlEventTouchUpInside];
110 | }
111 | return _squareButton;
112 | }
113 |
114 |
115 | - (UIButton *)circleButton{
116 |
117 | if(_circleButton == nil){
118 | _circleButton = [[UIButton alloc] initWithFrame:CGRectMake(KmainWidth/2.0, StatusHeight + NavigationBarHeight, KmainWidth/4.0, 40)];
119 | _circleButton.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1];
120 | [_circleButton setTitle:@" 圆形" forState:UIControlStateNormal];
121 | [_circleButton setImage:[UIImage imageNamed:@"圆形"] forState:UIControlStateNormal];
122 | [_circleButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
123 | [_circleButton setTitleColor:[UIColor redColor] forState:UIControlStateSelected];
124 | [_circleButton addTarget:self action:@selector(selectLineDrawType:) forControlEvents:UIControlEventTouchUpInside];
125 | }
126 | return _circleButton;
127 | }
128 |
129 |
130 | - (UIButton *)arrowButton{
131 |
132 | if(_arrowButton == nil){
133 | _arrowButton = [[UIButton alloc] initWithFrame:CGRectMake(KmainWidth/4.0*3, StatusHeight + NavigationBarHeight, KmainWidth/4.0, 40)];
134 | _arrowButton.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1];
135 | [_arrowButton setTitle:@" 箭头" forState:UIControlStateNormal];
136 | [_arrowButton setImage:[UIImage imageNamed:@"箭头"] forState:UIControlStateNormal];
137 | [_arrowButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
138 | [_arrowButton setTitleColor:[UIColor redColor] forState:UIControlStateSelected];
139 | [_arrowButton addTarget:self action:@selector(selectLineDrawType:) forControlEvents:UIControlEventTouchUpInside];
140 | }
141 | return _arrowButton;
142 | }
143 |
144 |
145 | - (SDDrawView *)drawView{
146 |
147 | if(_drawView == nil){
148 |
149 | _drawView = [[SDDrawView alloc] initWithFrame:CGRectMake(0, StatusHeight + NavigationBarHeight + 40, KmainWidth, KmainHeight - StatusHeight - NavigationBarHeight - 40 - 40 - 60)];
150 | _drawView.drawViewColor = [UIColor whiteColor];
151 | _drawView.lineWidth = 2.0f;
152 | _drawView.drawStyle = DrawStyleLine;
153 | _drawView.lineColor = [UIColor redColor];
154 | _drawView.layer.borderWidth = 1.0f;
155 | _drawView.layer.borderColor = [self hexStringToColor:@"c0c0c0"].CGColor;
156 | }
157 | return _drawView;
158 |
159 | }
160 |
161 | - (UISlider *)lineWidthSlider{
162 |
163 |
164 | if(_lineWidthSlider == nil){
165 | _lineWidthSlider = [[UISlider alloc] initWithFrame:CGRectMake(20, CGRectGetMaxY(_drawView.frame), KmainWidth - 40 - 60, 40)];
166 | [_lineWidthSlider setThumbImage:[UIImage imageNamed:@"slider_thumb"] forState:UIControlStateNormal];
167 | [_lineWidthSlider addTarget:self action:@selector(lineWidthAction:) forControlEvents:UIControlEventValueChanged];
168 | _lineWidthSlider.minimumTrackTintColor = [self hexStringToColor:@"facc60"];
169 | _lineWidthSlider.minimumValue = 2;
170 | _lineWidthSlider.maximumValue = 8;
171 | }
172 | return _lineWidthSlider;
173 |
174 | }
175 |
176 | - (UILabel *)lineWidthLabel{
177 |
178 | if(_lineWidthLabel == nil){
179 | _lineWidthLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(_lineWidthSlider.frame) + 5, CGRectGetMaxY(_drawView.frame), 55, 40)];
180 | _lineWidthLabel.font = [UIFont systemFontOfSize:12];
181 | _lineWidthLabel.text = @"宽度:2.0";
182 | _lineWidthLabel.textColor = [UIColor blackColor];
183 | }
184 | return _lineWidthLabel;
185 |
186 | }
187 |
188 | - (UIButton *)redButton{
189 |
190 | if(_redButton == nil){
191 | _redButton = [[UIButton alloc] initWithFrame:CGRectMake(20, CGRectGetMaxY(_lineWidthLabel.frame) + 15, KmainWidth/3.0 - 40, 30)];
192 | _redButton.titleLabel.font = [UIFont systemFontOfSize:14];
193 | _redButton.backgroundColor = [UIColor redColor];
194 | _redButton.layer.cornerRadius = 4.0f;
195 | _redButton.layer.masksToBounds = YES;
196 | [_redButton setTitle:@"" forState:UIControlStateNormal];
197 | [_redButton setTitle:@"✔️" forState:UIControlStateSelected];
198 | [_redButton addTarget:self action:@selector(selectDrawViewColorAction:) forControlEvents:UIControlEventTouchUpInside];
199 | _redButton.selected = YES;
200 | }
201 | return _redButton;
202 |
203 | }
204 |
205 | - (UIButton *)greenButton{
206 |
207 | if(_greenButton == nil){
208 | _greenButton = [[UIButton alloc] initWithFrame:CGRectMake(20 + KmainWidth/3.0 , CGRectGetMaxY(_lineWidthLabel.frame) + 15, KmainWidth/3.0 - 40, 30)];
209 | _greenButton.titleLabel.font = [UIFont systemFontOfSize:14];
210 | _greenButton.backgroundColor = [UIColor greenColor];
211 | _greenButton.layer.cornerRadius = 4.0f;
212 | _greenButton.layer.masksToBounds = YES;
213 | [_greenButton setTitle:@"" forState:UIControlStateNormal];
214 | [_greenButton setTitle:@"✔️" forState:UIControlStateSelected];
215 | [_greenButton addTarget:self action:@selector(selectDrawViewColorAction:) forControlEvents:UIControlEventTouchUpInside];
216 | }
217 | return _greenButton;
218 |
219 | }
220 |
221 | - (UIButton *)orangeButton{
222 |
223 | if(_orangeButton == nil){
224 | _orangeButton = [[UIButton alloc] initWithFrame:CGRectMake(20 + KmainWidth/3.0*2 , CGRectGetMaxY(_lineWidthLabel.frame) + 15, KmainWidth/3.0 - 40, 30)];
225 | _orangeButton.titleLabel.font = [UIFont systemFontOfSize:14];
226 | _orangeButton.backgroundColor = [UIColor orangeColor];
227 | _orangeButton.layer.cornerRadius = 4.0f;
228 | _orangeButton.layer.masksToBounds = YES;
229 | [_orangeButton setTitle:@"" forState:UIControlStateNormal];
230 | [_orangeButton setTitle:@"✔️" forState:UIControlStateSelected];
231 | [_orangeButton addTarget:self action:@selector(selectDrawViewColorAction:) forControlEvents:UIControlEventTouchUpInside];
232 | }
233 | return _orangeButton;
234 |
235 | }
236 |
237 | #pragma mark - 选择绘制样式(方式很low)
238 | - (void)selectLineDrawType:(UIButton *)sender{
239 |
240 | _lineButton.selected = NO;
241 | _squareButton.selected = NO;
242 | _circleButton.selected = NO;
243 | _arrowButton.selected = NO;
244 | sender.selected = YES;
245 |
246 | if([sender isEqual: _lineButton]){
247 | _drawView.drawStyle = DrawStyleLine;
248 | }else if([sender isEqual: _squareButton]){
249 | _drawView.drawStyle = DrawStyleSquare;
250 | }else if([sender isEqual: _circleButton]){
251 | _drawView.drawStyle = DrawStyleCircle;
252 | }else{
253 | _drawView.drawStyle = DrawStyleArrow;
254 | }
255 |
256 | }
257 |
258 | #pragma mark - 修改绘制线条的宽度
259 |
260 | //设置宽度 (2.0 -8.0)
261 | - (void)lineWidthAction:(UISlider *)sender{
262 |
263 | _drawView.lineWidth = sender.value;
264 | _lineWidthLabel.text = [NSString stringWithFormat:@"宽度:%.1f",sender.value];
265 |
266 | }
267 |
268 |
269 | #pragma mark - 选择绘制颜色
270 |
271 | - (void)selectDrawViewColorAction:(UIButton *)sender{
272 |
273 | _redButton.selected = NO;
274 | _greenButton.selected = NO;
275 | _orangeButton.selected = NO;
276 | sender.selected = YES;
277 |
278 | if([sender isEqual: _redButton]){
279 | _drawView.lineColor = [UIColor redColor];
280 | }else if([sender isEqual: _greenButton]){
281 | _drawView.lineColor = [UIColor greenColor];
282 | }else{
283 | _drawView.lineColor = [UIColor orangeColor];
284 | }
285 |
286 | }
287 |
288 | #pragma mark - 工具类(颜色)
289 |
290 | - (UIColor *)hexStringToColor:(NSString *)stringToConvert {
291 | NSString *cString = [[stringToConvert
292 | stringByTrimmingCharactersInSet:
293 | [NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
294 | // String should be 6 or 8 characters
295 | if ([cString length] < 6)
296 | return [UIColor blackColor];
297 | // strip 0X if it appears
298 | if ([cString hasPrefix:@"0X"])
299 | cString = [cString substringFromIndex:2];
300 | if ([cString hasPrefix:@"#"])
301 | cString = [cString substringFromIndex:1];
302 | if ([cString length] != 6)
303 | return [UIColor blackColor];
304 | // Separate into r, g, b substrings
305 | NSRange range;
306 | range.location = 0;
307 | range.length = 2;
308 | NSString *rString = [cString substringWithRange:range];
309 | range.location = 2;
310 | NSString *gString = [cString substringWithRange:range];
311 | range.location = 4;
312 | NSString *bString = [cString substringWithRange:range];
313 | // Scan values
314 | unsigned int r, g, b;
315 | [[NSScanner scannerWithString:rString] scanHexInt:&r];
316 | [[NSScanner scannerWithString:gString] scanHexInt:&g];
317 | [[NSScanner scannerWithString:bString] scanHexInt:&b];
318 | return [UIColor colorWithRed:((float)r / 255.0f)
319 | green:((float)g / 255.0f)
320 | blue:((float)b / 255.0f)
321 | alpha:1.0f];
322 | }
323 |
324 |
325 | @end
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
--------------------------------------------------------------------------------
/SDDrawingBoard/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIRequiredDeviceCapabilities
26 |
27 | armv7
28 |
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 |
33 | UISupportedInterfaceOrientations~ipad
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationPortraitUpsideDown
37 | UIInterfaceOrientationLandscapeLeft
38 | UIInterfaceOrientationLandscapeRight
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/SDDrawingBoard/SDDrawView/SDBezierPath.h:
--------------------------------------------------------------------------------
1 | //
2 | // SDBezierPath.h
3 | // SocketClinetDemo
4 | //
5 | // Created by bnqc on 2018/6/11.
6 | // Copyright © 2018年 骚栋. All rights reserved.
7 | //
8 |
9 | #import
10 | typedef enum : NSUInteger {
11 | DrawStyleLine,
12 | DrawStyleSquare,
13 | DrawStyleCircle,
14 | DrawStyleArrow
15 | } DrawStyle;
16 |
17 | @interface SDBezierPath : UIBezierPath
18 |
19 | @property(nonatomic,strong) UIColor *lineColor;//绘制颜色
20 | @property(nonatomic,assign) DrawStyle drawStyle;//绘制样式
21 |
22 | @property(nonatomic,assign) CGPoint startPoint;//当是矩形或者是圆的时候,需要使用到这个属性
23 | @property(nonatomic,assign) CGPoint endPoint;//当是矩形或者是圆的时候,需要使用到这个属性
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/SDDrawingBoard/SDDrawView/SDBezierPath.m:
--------------------------------------------------------------------------------
1 | //
2 | // SDBezierPath.m
3 | // SocketClinetDemo
4 | //
5 | // Created by bnqc on 2018/6/11.
6 | // Copyright © 2018年 骚栋. All rights reserved.
7 | //
8 |
9 | #import "SDBezierPath.h"
10 |
11 | @interface SDBezierPath(){
12 |
13 | double KEY_POINT_LEN1;
14 | double KEY_POINT_LEN2;
15 | double KEY_POINT_LEN3;
16 | double KEY_POINT_ANGLE1;
17 | double KEY_POINT_ANGLE2;
18 | double KEY_POINT_ANGLE3;
19 | double KEY_POINT_RATIO1;
20 | double KEY_POINT_RATIO2;
21 | double KEY_POINT_RATIO3;
22 |
23 | float startX;
24 | float startY;
25 | float endX;
26 | float endY;
27 | }
28 |
29 |
30 | @end
31 |
32 | @implementation SDBezierPath
33 |
34 |
35 | - (void)setDrawStyle:(DrawStyle)drawStyle{
36 |
37 | _drawStyle = drawStyle;
38 | if (_drawStyle == DrawStyleArrow) {
39 |
40 | //初始化箭头的相关固定值
41 | KEY_POINT_LEN1 = 70;
42 | KEY_POINT_LEN2 = 55;
43 | KEY_POINT_LEN3 = 8;
44 | KEY_POINT_ANGLE1 = 30 * M_PI/ 180;
45 | KEY_POINT_ANGLE2 = 18 * M_PI/ 180;
46 | KEY_POINT_ANGLE3 = 90 * M_PI/ 180;
47 | KEY_POINT_RATIO1 = 0.2;
48 | KEY_POINT_RATIO2 = 0.157;
49 | KEY_POINT_RATIO3 = 0.023;
50 | }
51 | }
52 |
53 | - (void)setStartPoint:(CGPoint)startPoint{
54 |
55 | _startPoint = startPoint;
56 | startX = _startPoint.x;
57 | startY = _startPoint.y;
58 | }
59 |
60 | - (void)setEndPoint:(CGPoint)endPoint{
61 | _endPoint = endPoint;
62 | endX = endPoint.x;
63 | endY = endPoint.y;
64 |
65 | if (_drawStyle == DrawStyleArrow) {
66 | [self removeAllPoints];//移除所有的路径点
67 | //配置箭头的6个点位
68 | double len1 = KEY_POINT_LEN1;
69 | double len2 = KEY_POINT_LEN2;
70 | double len3 = KEY_POINT_LEN3;
71 |
72 | double len = sqrt(pow((endX - startX), 2) + pow((endY - startY), 2));
73 | if (len * KEY_POINT_RATIO1 < KEY_POINT_LEN1) {
74 | len1 = len * KEY_POINT_RATIO1;
75 | }
76 | if (len * KEY_POINT_RATIO2 < KEY_POINT_LEN2) {
77 | len2 = len * KEY_POINT_RATIO2;
78 | }
79 | if (len * KEY_POINT_RATIO3 < KEY_POINT_LEN3) {
80 | len3 = len * KEY_POINT_RATIO3;
81 | }
82 | CGPoint arrXY_11 = [self rotateVecWithPx:endX - startX py:endY - startY ang:KEY_POINT_ANGLE1 newLen:len1];
83 | CGPoint arrXY_12 = [self rotateVecWithPx:endX - startX py:endY - startY ang:-KEY_POINT_ANGLE1 newLen:len1];
84 | CGPoint arrXY_21 = [self rotateVecWithPx:endX - startX py:endY - startY ang:KEY_POINT_ANGLE2 newLen:len2];
85 | CGPoint arrXY_22 = [self rotateVecWithPx:endX - startX py:endY - startY ang:-KEY_POINT_ANGLE2 newLen:len2];
86 | CGPoint arrXY_31 = [self rotateVecWithPx:startX - endX py:startY - endY ang:KEY_POINT_ANGLE3 newLen:len3];
87 | CGPoint arrXY_32 = [self rotateVecWithPx:startX - endX py:startY - endY ang:-KEY_POINT_ANGLE3 newLen:len3];;
88 |
89 | float x11 = endX - arrXY_11.x;
90 | float y11 = endY - arrXY_11.y;
91 | float x12 = endX - arrXY_12.x;
92 | float y12 = endY - arrXY_12.y;
93 | float x21 = endX - arrXY_21.x;
94 | float y21 = endY - arrXY_21.y;
95 | float x22 = endX - arrXY_22.x;
96 | float y22 = endY - arrXY_22.y;
97 | float x31 = startX - arrXY_31.x;
98 | float y31 = startY - arrXY_31.y;
99 | float x32 = startX - arrXY_32.x;
100 | float y32 = startY - arrXY_32.y;
101 | [self moveToPoint:endPoint];
102 | [self addLineToPoint:CGPointMake(x11, y11)];
103 | [self addLineToPoint:CGPointMake(x21, y21)];
104 | [self addLineToPoint:CGPointMake(x32, y32)];
105 | [self addLineToPoint:CGPointMake(x31, y31)];
106 | [self addLineToPoint:CGPointMake(x22, y22)];
107 | [self addLineToPoint:CGPointMake(x12, y12)];
108 |
109 | }
110 | }
111 |
112 |
113 | /**
114 | * 极坐标变换
115 | */
116 |
117 | - (CGPoint)rotateVecWithPx:(float)px py:(float)py ang:(double)ang newLen:(double)newLen{
118 |
119 | double vx = px * cos(ang) - py * sin(ang);
120 | double vy = px * sin(ang) + py * cos(ang);
121 | double d = sqrt(vx * vx + vy * vy);
122 | vx = vx / d * newLen;
123 | vy = vy / d * newLen;
124 | return CGPointMake((float) vx, (float) vy);
125 | }
126 |
127 | @end
128 |
--------------------------------------------------------------------------------
/SDDrawingBoard/SDDrawView/SDDrawView.h:
--------------------------------------------------------------------------------
1 | //
2 | // SDDrawView.h
3 | // SocketClinetDemo
4 | //
5 | // Created by bnqc on 2018/6/11.
6 | // Copyright © 2018年 骚栋. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "SDBezierPath.h"
11 |
12 | @interface SDDrawView : UIView
13 |
14 | //SDDrawView是图形绘制的View
15 |
16 | /***********通用属性**************/
17 |
18 | @property(nonatomic,strong) UIColor *drawViewColor;//画板颜色
19 | @property(nonatomic,assign) CGFloat lineWidth;//画笔宽度
20 | @property(nonatomic,assign) DrawStyle drawStyle;//绘制样式
21 | @property(nonatomic,strong) UIColor *lineColor;//画笔颜色
22 |
23 | - (void)cleanAction;//清除画板
24 | - (void)rollbackAction;//回退上一步
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/SDDrawingBoard/SDDrawView/SDDrawView.m:
--------------------------------------------------------------------------------
1 | //
2 | // SDDrawView.m
3 | // SocketClinetDemo
4 | //
5 | // Created by bnqc on 2018/6/11.
6 | // Copyright © 2018年 骚栋. All rights reserved.
7 | //
8 |
9 | #import "SDDrawView.h"
10 |
11 | @interface SDDrawView()
12 |
13 | @property(nonatomic,strong)NSMutableArray *pathsArray;
14 |
15 | @end
16 |
17 | @implementation SDDrawView
18 |
19 | - (instancetype)initWithFrame:(CGRect)frame{
20 |
21 | if (self = [super initWithFrame:frame]) {
22 | _pathsArray = [NSMutableArray arrayWithCapacity:16];
23 | self.backgroundColor = [UIColor whiteColor];
24 | }
25 | return self;
26 | }
27 |
28 | //清除
29 | - (void)cleanAction{
30 | [self.pathsArray removeAllObjects];
31 | //重绘
32 | [self setNeedsDisplay];
33 | }
34 |
35 | //回退
36 | - (void)rollbackAction{
37 | [self.pathsArray removeLastObject];
38 | //重绘
39 | [self setNeedsDisplay];
40 | }
41 |
42 | -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
43 | // 获取触摸对象
44 | UITouch *touch=[touches anyObject];
45 | // 获取手指的位置
46 | CGPoint point=[touch locationInView:touch.view];
47 | //当手指按下的时候就创建一条路径
48 | SDBezierPath *path=[SDBezierPath bezierPath];
49 | path.drawStyle = _drawStyle;
50 | //设置画笔宽度
51 | if(_lineWidth<=0){
52 | [path setLineWidth:5];
53 | }else{
54 | [path setLineWidth:_lineWidth];
55 | }
56 | //设置画笔颜色
57 | [path setLineColor:_lineColor];
58 | //设置起点
59 | switch (path.drawStyle) {
60 | case DrawStyleLine:
61 | [path moveToPoint:point];
62 | break;
63 | case DrawStyleSquare:case DrawStyleCircle:
64 | [path moveToPoint:point];
65 |
66 | path.startPoint = point;
67 | break;
68 | case DrawStyleArrow:
69 | path.startPoint = point;
70 | break;
71 | }
72 | // 把每一次新创建的路径 添加到数组当中
73 | [self.pathsArray addObject:path];
74 | }
75 |
76 |
77 | -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
78 | // 获取触摸对象
79 | UITouch *touch=[touches anyObject];
80 | // 获取手指的位置
81 | CGPoint point=[touch locationInView:touch.view];
82 | // 连线的点
83 | SDBezierPath *path = self.pathsArray.lastObject;
84 |
85 | switch (path.drawStyle) {
86 | case DrawStyleLine:
87 | [path addLineToPoint:point];
88 | break;
89 | case DrawStyleSquare:case DrawStyleCircle:
90 | path.endPoint = point;
91 | break;
92 | case DrawStyleArrow:
93 | path.endPoint = point;
94 |
95 | break;
96 | }
97 |
98 | // 重绘
99 | [self setNeedsDisplay];
100 | }
101 |
102 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
103 | // 连线的点
104 | SDBezierPath *path = self.pathsArray.lastObject;
105 | switch (path.drawStyle) {
106 | case DrawStyleLine:{
107 | // 获取触摸对象
108 | UITouch *touch=[touches anyObject];
109 | // 获取手指的位置
110 | CGPoint point=[touch locationInView:touch.view];
111 | // 连线的点
112 | [[self.pathsArray lastObject] addLineToPoint:point];
113 | // 重绘
114 | [self setNeedsDisplay];
115 |
116 | }break;
117 | case DrawStyleSquare:case DrawStyleCircle:
118 | break;
119 | case DrawStyleArrow:
120 | break;
121 | }
122 | }
123 |
124 |
125 | - (void)drawRect:(CGRect)rect {
126 | // Drawing code
127 | for (SDBezierPath *path in self.pathsArray) {
128 |
129 | switch (path.drawStyle) {
130 | case DrawStyleLine: {
131 | //设置颜色
132 | [path.lineColor set];
133 | // 设置连接处的样式
134 | [path setLineJoinStyle:kCGLineJoinRound];
135 | // 设置头尾的样式
136 | [path setLineCapStyle:kCGLineCapRound];
137 | //渲染
138 | [path stroke];
139 |
140 | }break;
141 | case DrawStyleSquare:{
142 | UIBezierPath *drawPath = [UIBezierPath bezierPathWithRect:CGRectMake(path.startPoint.x, path.startPoint.y, path.endPoint.x - path.startPoint.x, path.endPoint.y - path.startPoint.y)];
143 | //设置宽度
144 | drawPath.lineWidth = path.lineWidth;
145 | //设置颜色
146 | [path.lineColor set];
147 | // 设置连接处的样式
148 | [drawPath setLineJoinStyle:kCGLineJoinRound];
149 | // 设置头尾的样式
150 | [drawPath setLineCapStyle:kCGLineCapRound];
151 | //渲染
152 | [drawPath stroke];
153 |
154 | }break;
155 |
156 | case DrawStyleCircle: {
157 | UIBezierPath *drawPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(path.startPoint.x, path.startPoint.y, path.endPoint.x - path.startPoint.x, path.endPoint.y - path.startPoint.y)];
158 | //设置宽度
159 | drawPath.lineWidth = path.lineWidth;
160 | //设置颜色
161 | [path.lineColor set];
162 | // 设置连接处的样式
163 | [drawPath setLineJoinStyle:kCGLineJoinRound];
164 | // 设置头尾的样式
165 | [drawPath setLineCapStyle:kCGLineCapRound];
166 | //渲染
167 | [drawPath stroke];
168 | }break;
169 | case DrawStyleArrow: {
170 | //设置颜色
171 | [path.lineColor set];
172 | // 设置连接处的样式
173 | [path setLineJoinStyle:kCGLineJoinMiter];
174 | // 设置头尾的样式
175 | [path setLineCapStyle:kCGLineCapSquare];
176 |
177 | [path fill];
178 | }break;
179 | }
180 | }
181 | }
182 |
183 |
184 | @end
185 |
--------------------------------------------------------------------------------
/SDDrawingBoard/UIImage+Color.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+Color.h
3 | // UIImage+Categories
4 | //
5 | // Created by lisong on 16/9/4.
6 | // Copyright © 2016年 lisong. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIImage (Color)
12 |
13 | /** 根据颜色生成纯色图片 */
14 | + (UIImage *)imageWithColor:(UIColor *)color;
15 |
16 | /** 取图片某一像素的颜色 */
17 | - (UIColor *)colorAtPixel:(CGPoint)point;
18 |
19 | /** 获得灰度图 */
20 | - (UIImage *)convertToGrayImage;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/SDDrawingBoard/UIImage+Color.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+Color.m
3 | // UIImage+Categories
4 | //
5 | // Created by lisong on 16/9/4.
6 | // Copyright © 2016年 lisong. All rights reserved.
7 | //
8 |
9 | #import "UIImage+Color.h"
10 |
11 | @implementation UIImage (Color)
12 |
13 | /** 根据颜色生成纯色图片 */
14 | + (UIImage *)imageWithColor:(UIColor *)color
15 | {
16 | CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
17 | UIGraphicsBeginImageContext(rect.size);
18 | CGContextRef context = UIGraphicsGetCurrentContext();
19 |
20 | CGContextSetFillColorWithColor(context, [color CGColor]);
21 | CGContextFillRect(context, rect);
22 |
23 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
24 | UIGraphicsEndImageContext();
25 |
26 | return image;
27 | }
28 |
29 | /** 取图片某一像素的颜色 */
30 | - (UIColor *)colorAtPixel:(CGPoint)point
31 | {
32 | if (!CGRectContainsPoint(CGRectMake(0.0f, 0.0f, self.size.width, self.size.height), point))
33 | {
34 | return nil;
35 | }
36 |
37 | NSInteger pointX = trunc(point.x);
38 | NSInteger pointY = trunc(point.y);
39 | CGImageRef cgImage = self.CGImage;
40 | NSUInteger width = self.size.width;
41 | NSUInteger height = self.size.height;
42 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
43 | int bytesPerPixel = 4;
44 | int bytesPerRow = bytesPerPixel * 1;
45 | NSUInteger bitsPerComponent = 8;
46 | unsigned char pixelData[4] = { 0, 0, 0, 0 };
47 | CGContextRef context = CGBitmapContextCreate(pixelData,
48 | 1,
49 | 1,
50 | bitsPerComponent,
51 | bytesPerRow,
52 | colorSpace,
53 | kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
54 | CGColorSpaceRelease(colorSpace);
55 | CGContextSetBlendMode(context, kCGBlendModeCopy);
56 |
57 | CGContextTranslateCTM(context, -pointX, pointY-(CGFloat)height);
58 | CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, (CGFloat)width, (CGFloat)height), cgImage);
59 | CGContextRelease(context);
60 |
61 | CGFloat red = (CGFloat)pixelData[0] / 255.0f;
62 | CGFloat green = (CGFloat)pixelData[1] / 255.0f;
63 | CGFloat blue = (CGFloat)pixelData[2] / 255.0f;
64 | CGFloat alpha = (CGFloat)pixelData[3] / 255.0f;
65 | return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
66 | }
67 |
68 | /** 获得灰度图 */
69 | - (UIImage *)convertToGrayImage
70 | {
71 | int width = self.size.width;
72 | int height = self.size.height;
73 |
74 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
75 | CGContextRef context = CGBitmapContextCreate(nil,width,height,8,0,colorSpace,kCGImageAlphaNone);
76 | CGColorSpaceRelease(colorSpace);
77 |
78 | if (context == NULL)
79 | {
80 | return nil;
81 | }
82 |
83 | CGContextDrawImage(context,CGRectMake(0, 0, width, height), self.CGImage);
84 | CGImageRef contextRef = CGBitmapContextCreateImage(context);
85 | UIImage *grayImage = [UIImage imageWithCGImage:contextRef];
86 | CGContextRelease(context);
87 | CGImageRelease(contextRef);
88 |
89 | return grayImage;
90 | }
91 |
92 | @end
93 |
--------------------------------------------------------------------------------
/SDDrawingBoard/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // SDDrawingBoard
4 | //
5 | // Created by bnqc on 2018/7/10.
6 | // Copyright © 2018年 Dong. 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 |
--------------------------------------------------------------------------------