├── README.md ├── drawBoard.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── dengw.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── dengw.xcuserdatad │ └── xcschemes │ ├── drawBoard.xcscheme │ └── xcschememanagement.plist ├── drawBoard ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── DrawPath.h ├── DrawPath.m ├── DrawView.h ├── DrawView.m ├── Images.xcassets │ └── AppIcon.appiconset │ │ ├── 1-11112Q40511-50.png │ │ └── Contents.json ├── Info.plist ├── MyButton.h ├── MyButton.m ├── SelectColorView.h ├── SelectColorView.m ├── SelectLineWidthView.h ├── SelectLineWidthView.m ├── ToolView.h ├── ToolView.m ├── ViewController.h ├── ViewController.m ├── main.m └── readme.txt ├── drawBoardTests ├── Info.plist └── drawBoardTests.m └── screenshots ├── screenshots.jpg ├── screenshots2.png ├── screenshots3.png └── screenshots4.png /README.md: -------------------------------------------------------------------------------- 1 | # drawBoard 2 | This software can draw line of different color or font,import photo,erase board and clear board.
3 | 画板支持线条绘画,橡皮,清屏,导入相片并绘画,设置线条粗细,设置线条颜色,以及设置橡皮大小。 4 | screenshots 5 | ----------------------- 6 | one 7 |    8 | one 9 |    10 | one 11 |    12 | one 13 |    14 | 15 | #Blog 16 | My blog is [here](http://my.oschina.net/chars/blog). Welcome to visit! 17 | 18 | #E-mail 19 | Author:chars_d@126.com 20 | 21 | Copyright © deng wei 22 | -------------------------------------------------------------------------------- /drawBoard.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | D53BC74B1B3E4059000BFEAE /* DrawView.m in Sources */ = {isa = PBXBuildFile; fileRef = D53BC74A1B3E4059000BFEAE /* DrawView.m */; }; 11 | D53BC74E1B3E434A000BFEAE /* DrawPath.m in Sources */ = {isa = PBXBuildFile; fileRef = D53BC74D1B3E434A000BFEAE /* DrawPath.m */; }; 12 | D5C698971B3DAEFB00E788DA /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D5C698961B3DAEFB00E788DA /* main.m */; }; 13 | D5C6989A1B3DAEFB00E788DA /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D5C698991B3DAEFB00E788DA /* AppDelegate.m */; }; 14 | D5C6989D1B3DAEFB00E788DA /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D5C6989C1B3DAEFB00E788DA /* ViewController.m */; }; 15 | D5C698A01B3DAEFB00E788DA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D5C6989E1B3DAEFB00E788DA /* Main.storyboard */; }; 16 | D5C698A21B3DAEFB00E788DA /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D5C698A11B3DAEFB00E788DA /* Images.xcassets */; }; 17 | D5C698A51B3DAEFB00E788DA /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = D5C698A31B3DAEFB00E788DA /* LaunchScreen.xib */; }; 18 | D5C698B11B3DAEFB00E788DA /* drawBoardTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D5C698B01B3DAEFB00E788DA /* drawBoardTests.m */; }; 19 | D5D51D881B3E4F7A009DA065 /* ToolView.m in Sources */ = {isa = PBXBuildFile; fileRef = D5D51D871B3E4F7A009DA065 /* ToolView.m */; }; 20 | D5D51D8B1B3E591C009DA065 /* MyButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D5D51D8A1B3E591C009DA065 /* MyButton.m */; }; 21 | D5D51D8E1B3E63FA009DA065 /* SelectColorView.m in Sources */ = {isa = PBXBuildFile; fileRef = D5D51D8D1B3E63FA009DA065 /* SelectColorView.m */; }; 22 | D5D51D911B3E84FD009DA065 /* SelectLineWidthView.m in Sources */ = {isa = PBXBuildFile; fileRef = D5D51D901B3E84FD009DA065 /* SelectLineWidthView.m */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXContainerItemProxy section */ 26 | D5C698AB1B3DAEFB00E788DA /* PBXContainerItemProxy */ = { 27 | isa = PBXContainerItemProxy; 28 | containerPortal = D5C698891B3DAEFB00E788DA /* Project object */; 29 | proxyType = 1; 30 | remoteGlobalIDString = D5C698901B3DAEFB00E788DA; 31 | remoteInfo = drawBoard; 32 | }; 33 | /* End PBXContainerItemProxy section */ 34 | 35 | /* Begin PBXFileReference section */ 36 | D53BC7491B3E4059000BFEAE /* DrawView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawView.h; sourceTree = ""; }; 37 | D53BC74A1B3E4059000BFEAE /* DrawView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DrawView.m; sourceTree = ""; }; 38 | D53BC74C1B3E434A000BFEAE /* DrawPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawPath.h; sourceTree = ""; }; 39 | D53BC74D1B3E434A000BFEAE /* DrawPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DrawPath.m; sourceTree = ""; }; 40 | D5C698911B3DAEFB00E788DA /* drawBoard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = drawBoard.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | D5C698951B3DAEFB00E788DA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 42 | D5C698961B3DAEFB00E788DA /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 43 | D5C698981B3DAEFB00E788DA /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 44 | D5C698991B3DAEFB00E788DA /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 45 | D5C6989B1B3DAEFB00E788DA /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 46 | D5C6989C1B3DAEFB00E788DA /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 47 | D5C6989F1B3DAEFB00E788DA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 48 | D5C698A11B3DAEFB00E788DA /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 49 | D5C698A41B3DAEFB00E788DA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 50 | D5C698AA1B3DAEFB00E788DA /* drawBoardTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = drawBoardTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | D5C698AF1B3DAEFB00E788DA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | D5C698B01B3DAEFB00E788DA /* drawBoardTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = drawBoardTests.m; sourceTree = ""; }; 53 | D5D51D861B3E4F7A009DA065 /* ToolView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ToolView.h; sourceTree = ""; }; 54 | D5D51D871B3E4F7A009DA065 /* ToolView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ToolView.m; sourceTree = ""; }; 55 | D5D51D891B3E591C009DA065 /* MyButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyButton.h; sourceTree = ""; }; 56 | D5D51D8A1B3E591C009DA065 /* MyButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyButton.m; sourceTree = ""; }; 57 | D5D51D8C1B3E63FA009DA065 /* SelectColorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectColorView.h; sourceTree = ""; }; 58 | D5D51D8D1B3E63FA009DA065 /* SelectColorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SelectColorView.m; sourceTree = ""; }; 59 | D5D51D8F1B3E84FD009DA065 /* SelectLineWidthView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectLineWidthView.h; sourceTree = ""; }; 60 | D5D51D901B3E84FD009DA065 /* SelectLineWidthView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SelectLineWidthView.m; sourceTree = ""; }; 61 | /* End PBXFileReference section */ 62 | 63 | /* Begin PBXFrameworksBuildPhase section */ 64 | D5C6988E1B3DAEFB00E788DA /* Frameworks */ = { 65 | isa = PBXFrameworksBuildPhase; 66 | buildActionMask = 2147483647; 67 | files = ( 68 | ); 69 | runOnlyForDeploymentPostprocessing = 0; 70 | }; 71 | D5C698A71B3DAEFB00E788DA /* Frameworks */ = { 72 | isa = PBXFrameworksBuildPhase; 73 | buildActionMask = 2147483647; 74 | files = ( 75 | ); 76 | runOnlyForDeploymentPostprocessing = 0; 77 | }; 78 | /* End PBXFrameworksBuildPhase section */ 79 | 80 | /* Begin PBXGroup section */ 81 | D5C698881B3DAEFB00E788DA = { 82 | isa = PBXGroup; 83 | children = ( 84 | D5C698931B3DAEFB00E788DA /* drawBoard */, 85 | D5C698AD1B3DAEFB00E788DA /* drawBoardTests */, 86 | D5C698921B3DAEFB00E788DA /* Products */, 87 | ); 88 | sourceTree = ""; 89 | }; 90 | D5C698921B3DAEFB00E788DA /* Products */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | D5C698911B3DAEFB00E788DA /* drawBoard.app */, 94 | D5C698AA1B3DAEFB00E788DA /* drawBoardTests.xctest */, 95 | ); 96 | name = Products; 97 | sourceTree = ""; 98 | }; 99 | D5C698931B3DAEFB00E788DA /* drawBoard */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | D5C6989B1B3DAEFB00E788DA /* ViewController.h */, 103 | D5C6989C1B3DAEFB00E788DA /* ViewController.m */, 104 | D5C698981B3DAEFB00E788DA /* AppDelegate.h */, 105 | D5C698991B3DAEFB00E788DA /* AppDelegate.m */, 106 | D5D51D931B3EA39F009DA065 /* view */, 107 | D5D51D921B3EA37D009DA065 /* model */, 108 | D5C6989E1B3DAEFB00E788DA /* Main.storyboard */, 109 | D5C698A11B3DAEFB00E788DA /* Images.xcassets */, 110 | D5C698A31B3DAEFB00E788DA /* LaunchScreen.xib */, 111 | D5C698941B3DAEFB00E788DA /* Supporting Files */, 112 | ); 113 | path = drawBoard; 114 | sourceTree = ""; 115 | }; 116 | D5C698941B3DAEFB00E788DA /* Supporting Files */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | D5C698951B3DAEFB00E788DA /* Info.plist */, 120 | D5C698961B3DAEFB00E788DA /* main.m */, 121 | ); 122 | name = "Supporting Files"; 123 | sourceTree = ""; 124 | }; 125 | D5C698AD1B3DAEFB00E788DA /* drawBoardTests */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | D5C698B01B3DAEFB00E788DA /* drawBoardTests.m */, 129 | D5C698AE1B3DAEFB00E788DA /* Supporting Files */, 130 | ); 131 | path = drawBoardTests; 132 | sourceTree = ""; 133 | }; 134 | D5C698AE1B3DAEFB00E788DA /* Supporting Files */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | D5C698AF1B3DAEFB00E788DA /* Info.plist */, 138 | ); 139 | name = "Supporting Files"; 140 | sourceTree = ""; 141 | }; 142 | D5D51D921B3EA37D009DA065 /* model */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | D53BC74C1B3E434A000BFEAE /* DrawPath.h */, 146 | D53BC74D1B3E434A000BFEAE /* DrawPath.m */, 147 | ); 148 | name = model; 149 | sourceTree = ""; 150 | }; 151 | D5D51D931B3EA39F009DA065 /* view */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | D53BC7491B3E4059000BFEAE /* DrawView.h */, 155 | D53BC74A1B3E4059000BFEAE /* DrawView.m */, 156 | D5D51D861B3E4F7A009DA065 /* ToolView.h */, 157 | D5D51D871B3E4F7A009DA065 /* ToolView.m */, 158 | D5D51D891B3E591C009DA065 /* MyButton.h */, 159 | D5D51D8A1B3E591C009DA065 /* MyButton.m */, 160 | D5D51D8C1B3E63FA009DA065 /* SelectColorView.h */, 161 | D5D51D8D1B3E63FA009DA065 /* SelectColorView.m */, 162 | D5D51D8F1B3E84FD009DA065 /* SelectLineWidthView.h */, 163 | D5D51D901B3E84FD009DA065 /* SelectLineWidthView.m */, 164 | ); 165 | name = view; 166 | sourceTree = ""; 167 | }; 168 | /* End PBXGroup section */ 169 | 170 | /* Begin PBXNativeTarget section */ 171 | D5C698901B3DAEFB00E788DA /* drawBoard */ = { 172 | isa = PBXNativeTarget; 173 | buildConfigurationList = D5C698B41B3DAEFB00E788DA /* Build configuration list for PBXNativeTarget "drawBoard" */; 174 | buildPhases = ( 175 | D5C6988D1B3DAEFB00E788DA /* Sources */, 176 | D5C6988E1B3DAEFB00E788DA /* Frameworks */, 177 | D5C6988F1B3DAEFB00E788DA /* Resources */, 178 | ); 179 | buildRules = ( 180 | ); 181 | dependencies = ( 182 | ); 183 | name = drawBoard; 184 | productName = drawBoard; 185 | productReference = D5C698911B3DAEFB00E788DA /* drawBoard.app */; 186 | productType = "com.apple.product-type.application"; 187 | }; 188 | D5C698A91B3DAEFB00E788DA /* drawBoardTests */ = { 189 | isa = PBXNativeTarget; 190 | buildConfigurationList = D5C698B71B3DAEFB00E788DA /* Build configuration list for PBXNativeTarget "drawBoardTests" */; 191 | buildPhases = ( 192 | D5C698A61B3DAEFB00E788DA /* Sources */, 193 | D5C698A71B3DAEFB00E788DA /* Frameworks */, 194 | D5C698A81B3DAEFB00E788DA /* Resources */, 195 | ); 196 | buildRules = ( 197 | ); 198 | dependencies = ( 199 | D5C698AC1B3DAEFB00E788DA /* PBXTargetDependency */, 200 | ); 201 | name = drawBoardTests; 202 | productName = drawBoardTests; 203 | productReference = D5C698AA1B3DAEFB00E788DA /* drawBoardTests.xctest */; 204 | productType = "com.apple.product-type.bundle.unit-test"; 205 | }; 206 | /* End PBXNativeTarget section */ 207 | 208 | /* Begin PBXProject section */ 209 | D5C698891B3DAEFB00E788DA /* Project object */ = { 210 | isa = PBXProject; 211 | attributes = { 212 | LastUpgradeCheck = 0630; 213 | ORGANIZATIONNAME = dengwei; 214 | TargetAttributes = { 215 | D5C698901B3DAEFB00E788DA = { 216 | CreatedOnToolsVersion = 6.3.2; 217 | }; 218 | D5C698A91B3DAEFB00E788DA = { 219 | CreatedOnToolsVersion = 6.3.2; 220 | TestTargetID = D5C698901B3DAEFB00E788DA; 221 | }; 222 | }; 223 | }; 224 | buildConfigurationList = D5C6988C1B3DAEFB00E788DA /* Build configuration list for PBXProject "drawBoard" */; 225 | compatibilityVersion = "Xcode 3.2"; 226 | developmentRegion = English; 227 | hasScannedForEncodings = 0; 228 | knownRegions = ( 229 | en, 230 | Base, 231 | ); 232 | mainGroup = D5C698881B3DAEFB00E788DA; 233 | productRefGroup = D5C698921B3DAEFB00E788DA /* Products */; 234 | projectDirPath = ""; 235 | projectRoot = ""; 236 | targets = ( 237 | D5C698901B3DAEFB00E788DA /* drawBoard */, 238 | D5C698A91B3DAEFB00E788DA /* drawBoardTests */, 239 | ); 240 | }; 241 | /* End PBXProject section */ 242 | 243 | /* Begin PBXResourcesBuildPhase section */ 244 | D5C6988F1B3DAEFB00E788DA /* Resources */ = { 245 | isa = PBXResourcesBuildPhase; 246 | buildActionMask = 2147483647; 247 | files = ( 248 | D5C698A01B3DAEFB00E788DA /* Main.storyboard in Resources */, 249 | D5C698A51B3DAEFB00E788DA /* LaunchScreen.xib in Resources */, 250 | D5C698A21B3DAEFB00E788DA /* Images.xcassets in Resources */, 251 | ); 252 | runOnlyForDeploymentPostprocessing = 0; 253 | }; 254 | D5C698A81B3DAEFB00E788DA /* Resources */ = { 255 | isa = PBXResourcesBuildPhase; 256 | buildActionMask = 2147483647; 257 | files = ( 258 | ); 259 | runOnlyForDeploymentPostprocessing = 0; 260 | }; 261 | /* End PBXResourcesBuildPhase section */ 262 | 263 | /* Begin PBXSourcesBuildPhase section */ 264 | D5C6988D1B3DAEFB00E788DA /* Sources */ = { 265 | isa = PBXSourcesBuildPhase; 266 | buildActionMask = 2147483647; 267 | files = ( 268 | D5D51D911B3E84FD009DA065 /* SelectLineWidthView.m in Sources */, 269 | D53BC74E1B3E434A000BFEAE /* DrawPath.m in Sources */, 270 | D5D51D8E1B3E63FA009DA065 /* SelectColorView.m in Sources */, 271 | D5C6989D1B3DAEFB00E788DA /* ViewController.m in Sources */, 272 | D5C6989A1B3DAEFB00E788DA /* AppDelegate.m in Sources */, 273 | D5D51D881B3E4F7A009DA065 /* ToolView.m in Sources */, 274 | D53BC74B1B3E4059000BFEAE /* DrawView.m in Sources */, 275 | D5C698971B3DAEFB00E788DA /* main.m in Sources */, 276 | D5D51D8B1B3E591C009DA065 /* MyButton.m in Sources */, 277 | ); 278 | runOnlyForDeploymentPostprocessing = 0; 279 | }; 280 | D5C698A61B3DAEFB00E788DA /* Sources */ = { 281 | isa = PBXSourcesBuildPhase; 282 | buildActionMask = 2147483647; 283 | files = ( 284 | D5C698B11B3DAEFB00E788DA /* drawBoardTests.m in Sources */, 285 | ); 286 | runOnlyForDeploymentPostprocessing = 0; 287 | }; 288 | /* End PBXSourcesBuildPhase section */ 289 | 290 | /* Begin PBXTargetDependency section */ 291 | D5C698AC1B3DAEFB00E788DA /* PBXTargetDependency */ = { 292 | isa = PBXTargetDependency; 293 | target = D5C698901B3DAEFB00E788DA /* drawBoard */; 294 | targetProxy = D5C698AB1B3DAEFB00E788DA /* PBXContainerItemProxy */; 295 | }; 296 | /* End PBXTargetDependency section */ 297 | 298 | /* Begin PBXVariantGroup section */ 299 | D5C6989E1B3DAEFB00E788DA /* Main.storyboard */ = { 300 | isa = PBXVariantGroup; 301 | children = ( 302 | D5C6989F1B3DAEFB00E788DA /* Base */, 303 | ); 304 | name = Main.storyboard; 305 | sourceTree = ""; 306 | }; 307 | D5C698A31B3DAEFB00E788DA /* LaunchScreen.xib */ = { 308 | isa = PBXVariantGroup; 309 | children = ( 310 | D5C698A41B3DAEFB00E788DA /* Base */, 311 | ); 312 | name = LaunchScreen.xib; 313 | sourceTree = ""; 314 | }; 315 | /* End PBXVariantGroup section */ 316 | 317 | /* Begin XCBuildConfiguration section */ 318 | D5C698B21B3DAEFB00E788DA /* Debug */ = { 319 | isa = XCBuildConfiguration; 320 | buildSettings = { 321 | ALWAYS_SEARCH_USER_PATHS = NO; 322 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 323 | CLANG_CXX_LIBRARY = "libc++"; 324 | CLANG_ENABLE_MODULES = YES; 325 | CLANG_ENABLE_OBJC_ARC = YES; 326 | CLANG_WARN_BOOL_CONVERSION = YES; 327 | CLANG_WARN_CONSTANT_CONVERSION = YES; 328 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 329 | CLANG_WARN_EMPTY_BODY = YES; 330 | CLANG_WARN_ENUM_CONVERSION = YES; 331 | CLANG_WARN_INT_CONVERSION = YES; 332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 333 | CLANG_WARN_UNREACHABLE_CODE = YES; 334 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 335 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 336 | COPY_PHASE_STRIP = NO; 337 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 338 | ENABLE_STRICT_OBJC_MSGSEND = YES; 339 | GCC_C_LANGUAGE_STANDARD = gnu99; 340 | GCC_DYNAMIC_NO_PIC = NO; 341 | GCC_NO_COMMON_BLOCKS = YES; 342 | GCC_OPTIMIZATION_LEVEL = 0; 343 | GCC_PREPROCESSOR_DEFINITIONS = ( 344 | "DEBUG=1", 345 | "$(inherited)", 346 | ); 347 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 348 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 349 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 350 | GCC_WARN_UNDECLARED_SELECTOR = YES; 351 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 352 | GCC_WARN_UNUSED_FUNCTION = YES; 353 | GCC_WARN_UNUSED_VARIABLE = YES; 354 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 355 | MTL_ENABLE_DEBUG_INFO = YES; 356 | ONLY_ACTIVE_ARCH = YES; 357 | SDKROOT = iphoneos; 358 | }; 359 | name = Debug; 360 | }; 361 | D5C698B31B3DAEFB00E788DA /* Release */ = { 362 | isa = XCBuildConfiguration; 363 | buildSettings = { 364 | ALWAYS_SEARCH_USER_PATHS = NO; 365 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 366 | CLANG_CXX_LIBRARY = "libc++"; 367 | CLANG_ENABLE_MODULES = YES; 368 | CLANG_ENABLE_OBJC_ARC = YES; 369 | CLANG_WARN_BOOL_CONVERSION = YES; 370 | CLANG_WARN_CONSTANT_CONVERSION = YES; 371 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 372 | CLANG_WARN_EMPTY_BODY = YES; 373 | CLANG_WARN_ENUM_CONVERSION = YES; 374 | CLANG_WARN_INT_CONVERSION = YES; 375 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 376 | CLANG_WARN_UNREACHABLE_CODE = YES; 377 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 378 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 379 | COPY_PHASE_STRIP = NO; 380 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 381 | ENABLE_NS_ASSERTIONS = NO; 382 | ENABLE_STRICT_OBJC_MSGSEND = YES; 383 | GCC_C_LANGUAGE_STANDARD = gnu99; 384 | GCC_NO_COMMON_BLOCKS = YES; 385 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 386 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 387 | GCC_WARN_UNDECLARED_SELECTOR = YES; 388 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 389 | GCC_WARN_UNUSED_FUNCTION = YES; 390 | GCC_WARN_UNUSED_VARIABLE = YES; 391 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 392 | MTL_ENABLE_DEBUG_INFO = NO; 393 | SDKROOT = iphoneos; 394 | VALIDATE_PRODUCT = YES; 395 | }; 396 | name = Release; 397 | }; 398 | D5C698B51B3DAEFB00E788DA /* Debug */ = { 399 | isa = XCBuildConfiguration; 400 | buildSettings = { 401 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 402 | CODE_SIGN_IDENTITY = "iPhone Developer: GuoDong Wang (595AE7GP87)"; 403 | INFOPLIST_FILE = drawBoard/Info.plist; 404 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 405 | PRODUCT_NAME = "$(TARGET_NAME)"; 406 | PROVISIONING_PROFILE = "e9c77214-0f6a-46f4-9cd4-b16616b24642"; 407 | }; 408 | name = Debug; 409 | }; 410 | D5C698B61B3DAEFB00E788DA /* Release */ = { 411 | isa = XCBuildConfiguration; 412 | buildSettings = { 413 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 414 | INFOPLIST_FILE = drawBoard/Info.plist; 415 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 416 | PRODUCT_NAME = "$(TARGET_NAME)"; 417 | PROVISIONING_PROFILE = "e9c77214-0f6a-46f4-9cd4-b16616b24642"; 418 | }; 419 | name = Release; 420 | }; 421 | D5C698B81B3DAEFB00E788DA /* Debug */ = { 422 | isa = XCBuildConfiguration; 423 | buildSettings = { 424 | BUNDLE_LOADER = "$(TEST_HOST)"; 425 | FRAMEWORK_SEARCH_PATHS = ( 426 | "$(SDKROOT)/Developer/Library/Frameworks", 427 | "$(inherited)", 428 | ); 429 | GCC_PREPROCESSOR_DEFINITIONS = ( 430 | "DEBUG=1", 431 | "$(inherited)", 432 | ); 433 | INFOPLIST_FILE = drawBoardTests/Info.plist; 434 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 435 | PRODUCT_NAME = "$(TARGET_NAME)"; 436 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/drawBoard.app/drawBoard"; 437 | }; 438 | name = Debug; 439 | }; 440 | D5C698B91B3DAEFB00E788DA /* Release */ = { 441 | isa = XCBuildConfiguration; 442 | buildSettings = { 443 | BUNDLE_LOADER = "$(TEST_HOST)"; 444 | FRAMEWORK_SEARCH_PATHS = ( 445 | "$(SDKROOT)/Developer/Library/Frameworks", 446 | "$(inherited)", 447 | ); 448 | INFOPLIST_FILE = drawBoardTests/Info.plist; 449 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 450 | PRODUCT_NAME = "$(TARGET_NAME)"; 451 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/drawBoard.app/drawBoard"; 452 | }; 453 | name = Release; 454 | }; 455 | /* End XCBuildConfiguration section */ 456 | 457 | /* Begin XCConfigurationList section */ 458 | D5C6988C1B3DAEFB00E788DA /* Build configuration list for PBXProject "drawBoard" */ = { 459 | isa = XCConfigurationList; 460 | buildConfigurations = ( 461 | D5C698B21B3DAEFB00E788DA /* Debug */, 462 | D5C698B31B3DAEFB00E788DA /* Release */, 463 | ); 464 | defaultConfigurationIsVisible = 0; 465 | defaultConfigurationName = Release; 466 | }; 467 | D5C698B41B3DAEFB00E788DA /* Build configuration list for PBXNativeTarget "drawBoard" */ = { 468 | isa = XCConfigurationList; 469 | buildConfigurations = ( 470 | D5C698B51B3DAEFB00E788DA /* Debug */, 471 | D5C698B61B3DAEFB00E788DA /* Release */, 472 | ); 473 | defaultConfigurationIsVisible = 0; 474 | defaultConfigurationName = Release; 475 | }; 476 | D5C698B71B3DAEFB00E788DA /* Build configuration list for PBXNativeTarget "drawBoardTests" */ = { 477 | isa = XCConfigurationList; 478 | buildConfigurations = ( 479 | D5C698B81B3DAEFB00E788DA /* Debug */, 480 | D5C698B91B3DAEFB00E788DA /* Release */, 481 | ); 482 | defaultConfigurationIsVisible = 0; 483 | defaultConfigurationName = Release; 484 | }; 485 | /* End XCConfigurationList section */ 486 | }; 487 | rootObject = D5C698891B3DAEFB00E788DA /* Project object */; 488 | } 489 | -------------------------------------------------------------------------------- /drawBoard.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /drawBoard.xcodeproj/project.xcworkspace/xcuserdata/dengw.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charsdavy/drawBoard/21f9cf5a4de69a4275a672d37efcb62e7de266d7/drawBoard.xcodeproj/project.xcworkspace/xcuserdata/dengw.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /drawBoard.xcodeproj/xcuserdata/dengw.xcuserdatad/xcschemes/drawBoard.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /drawBoard.xcodeproj/xcuserdata/dengw.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | drawBoard.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | D5C698901B3DAEFB00E788DA 16 | 17 | primary 18 | 19 | 20 | D5C698A91B3DAEFB00E788DA 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /drawBoard/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // drawBoard 4 | // 5 | // Created by dengwei on 15/6/27. 6 | // Copyright (c) 2015年 dengwei. 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 | -------------------------------------------------------------------------------- /drawBoard/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // drawBoard 4 | // 5 | // Created by dengwei on 15/6/27. 6 | // Copyright (c) 2015年 dengwei. 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 | -------------------------------------------------------------------------------- /drawBoard/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /drawBoard/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 | 26 | -------------------------------------------------------------------------------- /drawBoard/DrawPath.h: -------------------------------------------------------------------------------- 1 | // 2 | // DrawPath.h 3 | // drawBoard 4 | // 5 | // Created by dengwei on 15/6/27. 6 | // Copyright (c) 2015年 dengwei. All rights reserved. 7 | // 8 | 9 | //#import 10 | #import 11 | 12 | @interface DrawPath:NSObject 13 | 14 | +(id)drawPathWithCGPath:(CGPathRef)drawPath 15 | color:(UIColor *)color 16 | lineWidth:(CGFloat)lineWidth; 17 | 18 | @property (strong, nonatomic)UIBezierPath *drawPath; 19 | @property (strong, nonatomic)UIColor *drawColor; 20 | @property (assign, nonatomic)CGFloat lineWidth; 21 | 22 | //用户选择的图像 23 | @property (strong, nonatomic)UIImage *image; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /drawBoard/DrawPath.m: -------------------------------------------------------------------------------- 1 | // 2 | // DrawPath.m 3 | // drawBoard 4 | // 5 | // Created by dengwei on 15/6/27. 6 | // Copyright (c) 2015年 dengwei. All rights reserved. 7 | // 8 | 9 | #import "DrawPath.h" 10 | 11 | @implementation DrawPath 12 | 13 | +(id)drawPathWithCGPath:(CGPathRef)drawPath 14 | color:(UIColor *)color 15 | lineWidth:(CGFloat)lineWidth 16 | { 17 | DrawPath *path = [[DrawPath alloc]init]; 18 | 19 | path.drawPath = [UIBezierPath bezierPathWithCGPath:drawPath]; 20 | path.drawColor = color; 21 | path.lineWidth = lineWidth; 22 | 23 | return path; 24 | } 25 | 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /drawBoard/DrawView.h: -------------------------------------------------------------------------------- 1 | // 2 | // DrawView.h 3 | // drawBoard 4 | // 5 | // Created by dengwei on 15/6/27. 6 | // Copyright (c) 2015年 dengwei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DrawView:UIView 12 | 13 | @property (assign, nonatomic)CGFloat lineWidth; 14 | @property (strong, nonatomic)UIColor *drawColor; 15 | @property (strong, nonatomic)UIImage *image; 16 | 17 | -(void)undoStep; 18 | -(void)clearScreen; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /drawBoard/DrawView.m: -------------------------------------------------------------------------------- 1 | // 2 | // DrawView.m 3 | // drawingBoard 4 | // 5 | // Created by dengwei on 15/6/26. 6 | // Copyright (c) 2015年 dengwei. All rights reserved. 7 | // 8 | 9 | #import "DrawView.h" 10 | #import "DrawPath.h" 11 | 12 | @interface DrawView() 13 | 14 | //当前绘图路径 15 | @property (assign, nonatomic)CGMutablePathRef drawPath; 16 | //绘图路径数组 17 | @property (strong, nonatomic)NSMutableArray *drawPathArray; 18 | //路径是否被释放 19 | @property (assign, nonatomic)BOOL pathReleased; 20 | 21 | @end 22 | 23 | @implementation DrawView 24 | 25 | -(id)initWithFrame:(CGRect)frame 26 | { 27 | self = [super initWithFrame:frame]; 28 | 29 | if (self) { 30 | [self setBackgroundColor:[UIColor whiteColor]]; 31 | 32 | //设置属性值 33 | self.lineWidth = 10.0; 34 | self.drawColor = [UIColor redColor]; 35 | } 36 | 37 | return self; 38 | } 39 | 40 | #pragma mark - 绘制视图 41 | //注意:drawRect方法每次都是完整的绘制视图中需要绘制部分内容 42 | -(void)drawRect:(CGRect)rect 43 | { 44 | //1.获取上下文 45 | CGContextRef context = UIGraphicsGetCurrentContext(); 46 | 47 | [self drawView:context]; 48 | 49 | } 50 | 51 | #pragma mark - 绘图视图内容的方法 52 | -(void)drawView:(CGContextRef)context 53 | { 54 | //-------------------------------------- 55 | //首先将绘图数组中的路径全部绘制出来 56 | for(DrawPath *path in self.drawPathArray){ 57 | if (path.image == nil) { 58 | 59 | CGContextAddPath(context, path.drawPath.CGPath); 60 | 61 | [path.drawColor set]; 62 | CGContextSetLineWidth(context, path.lineWidth); 63 | CGContextSetLineCap(context, kCGLineCapRound); 64 | 65 | CGContextDrawPath(context, kCGPathStroke); 66 | }else{ 67 | //有图像,没路径 68 | //CGContextDrawImage(context, self.bounds, path.image.CGImage); 69 | [path.image drawInRect:self.bounds]; 70 | } 71 | } 72 | 73 | //-------------------------------------- 74 | //以下代码绘制当前路径的内容,就是手指还没有离开屏幕 75 | //内存管理部分提到,所有create创建的都要release,而不能设置成NULL 76 | if (self.pathReleased) { 77 | return; 78 | } 79 | 80 | //1.添加路径 81 | CGContextAddPath(context, self.drawPath); 82 | 83 | //2.设置上下文属性 84 | [self.drawColor set]; 85 | CGContextSetLineWidth(context, self.lineWidth); 86 | CGContextSetLineCap(context, kCGLineCapRound); 87 | 88 | //3.绘制路径 89 | CGContextDrawPath(context, kCGPathStroke); 90 | } 91 | 92 | #pragma mark - 触摸事件 93 | #pragma mark - 触摸开始,创建绘图路径 94 | -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 95 | { 96 | UITouch *touch = [touches anyObject]; 97 | CGPoint location = [touch locationInView:self]; 98 | 99 | self.drawPath = CGPathCreateMutable(); 100 | 101 | //记录路径没有被释放 102 | self.pathReleased = NO; 103 | 104 | //在路径中记录触摸的初始点 105 | CGPathMoveToPoint(self.drawPath, NULL, location.x, location.y); 106 | } 107 | #pragma mark - 移动过程中,将触摸点不断添加到绘图路径 108 | -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 109 | { 110 | //可以获取用户当前触摸的点 111 | UITouch *touch = [touches anyObject]; 112 | CGPoint location = [touch locationInView:self]; 113 | 114 | //将触摸点添加至路径 115 | CGPathAddLineToPoint(self.drawPath, NULL, location.x, location.y); 116 | 117 | [self setNeedsDisplay]; 118 | } 119 | 120 | #pragma mark - 触摸结束,释放路径 121 | -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 122 | { 123 | //一笔画完之后将完整的路径添加到路径数组中 124 | //使用数组的懒加载 125 | if (self.drawPathArray == nil) { 126 | self.drawPathArray = [NSMutableArray array]; 127 | } 128 | //要将CGPathRef添加到NSArray之中,需要借助贝塞尔曲线对象 129 | //贝塞尔曲线时UIKit对CGPathRef的一个封装,贝塞尔路径的对象可以直接添加到数组 130 | //UIBezierPath *path = [UIBezierPath bezierPathWithCGPath:self.drawPath]; 131 | 132 | DrawPath *path = [DrawPath drawPathWithCGPath:self.drawPath color:self.drawColor lineWidth:self.lineWidth]; 133 | 134 | //需要记录当前绘制路径的颜色和线宽 135 | [self.drawPathArray addObject:path]; 136 | 137 | 138 | CGPathRelease(self.drawPath); 139 | 140 | //记录路径被释放 141 | self.pathReleased = YES; 142 | 143 | //测试线宽的代码 144 | //self.lineWidth = arc4random() % 20 + 1.0; 145 | } 146 | 147 | #pragma mark - 工具视图执行方法 148 | -(void)undoStep 149 | { 150 | //在执行撤销操作时,当前没有绘图路径 151 | //要做撤销操作,需要把路径数组中最后一条路径删除 152 | [self.drawPathArray removeLastObject]; 153 | 154 | [self setNeedsDisplay]; 155 | } 156 | 157 | -(void)clearScreen 158 | { 159 | //在执行清屏操作时,当前没有绘图路径 160 | //要做清屏操作,只要把路径数组清空即可 161 | [self.drawPathArray removeAllObjects]; 162 | 163 | [self setNeedsDisplay]; 164 | } 165 | 166 | #pragma mark - image的setter方法 167 | -(void)setImage:(UIImage *)image 168 | { 169 | /*目前绘图的方法: 170 | 1.用self.drawPathArray记录已经完成(抬起手指)的路径 171 | 2.用self.drawPath记录当前正在拖动中的路径 172 | 173 | 绘制时,首先绘制self.drawPathArray,然后再绘制self.drawPath 174 | 175 | image传入时,drawPath没有被创建(被release但不是NULL) 176 | 177 | 如果, 178 | 1.将image也添加到self.drawPathArray(DrawPath) 179 | 2.在绘图时,根据是否存在image判断是否绘制路径还是图像,就可以 180 | 实现用一个路径数组即绘制路径,又绘制图像的目的 181 | 182 | 之所以要用一个数组,时因为绘图是有顺序的 183 | 184 | 接下来,首先需要扩充DrawPath,使其支持image 185 | */ 186 | //1.实例化一个新的DrawPath 187 | DrawPath *path = [[DrawPath alloc]init]; 188 | [path setImage:image]; 189 | 190 | //2.将其添加到self.drawPathArray,这个数组是懒加载 191 | if (self.drawPathArray == nil) { 192 | self.drawPathArray = [NSMutableArray array]; 193 | } 194 | 195 | [self.drawPathArray addObject:path]; 196 | 197 | //3.重绘 198 | [self setNeedsDisplay]; 199 | } 200 | 201 | @end 202 | -------------------------------------------------------------------------------- /drawBoard/Images.xcassets/AppIcon.appiconset/1-11112Q40511-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charsdavy/drawBoard/21f9cf5a4de69a4275a672d37efcb62e7de266d7/drawBoard/Images.xcassets/AppIcon.appiconset/1-11112Q40511-50.png -------------------------------------------------------------------------------- /drawBoard/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "29x29", 5 | "idiom" : "iphone", 6 | "filename" : "1-11112Q40511-50.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "idiom" : "iphone", 11 | "size" : "29x29", 12 | "scale" : "3x" 13 | }, 14 | { 15 | "idiom" : "iphone", 16 | "size" : "40x40", 17 | "scale" : "2x" 18 | }, 19 | { 20 | "idiom" : "iphone", 21 | "size" : "40x40", 22 | "scale" : "3x" 23 | }, 24 | { 25 | "idiom" : "iphone", 26 | "size" : "60x60", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "idiom" : "iphone", 31 | "size" : "60x60", 32 | "scale" : "3x" 33 | } 34 | ], 35 | "info" : { 36 | "version" : 1, 37 | "author" : "xcode" 38 | } 39 | } -------------------------------------------------------------------------------- /drawBoard/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.dengwei.test.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | Main 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UIStatusBarHidden 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /drawBoard/MyButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // MyButton.h 3 | // drawBoard 4 | // 5 | // Created by dengwei on 15/6/27. 6 | // Copyright (c) 2015年 dengwei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MyButton:UIButton 12 | 13 | @property (assign, nonatomic)BOOL selectedMyButton; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /drawBoard/MyButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // MyButton.m 3 | // drawBoard 4 | // 5 | // Created by dengwei on 15/6/27. 6 | // Copyright (c) 2015年 dengwei. All rights reserved. 7 | // 8 | 9 | #import "MyButton.h" 10 | 11 | @implementation MyButton 12 | 13 | -(id)initWithFrame:(CGRect)frame 14 | { 15 | self = [super initWithFrame:frame]; 16 | 17 | if (self) { 18 | [self.titleLabel setFont:[UIFont systemFontOfSize:12.0]]; 19 | 20 | [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 21 | 22 | } 23 | 24 | return self; 25 | } 26 | 27 | -(void)drawRect:(CGRect)rect 28 | { 29 | //如果按钮被选中则在按钮的下方画一条红线 30 | if (self.selectedMyButton) { 31 | CGRect frame = CGRectMake(0, self.bounds.size.height - 2, self.bounds.size.width, 2); 32 | 33 | [[UIColor redColor]set]; 34 | UIRectFill(frame); 35 | } 36 | } 37 | 38 | #pragma mark - setter方法 39 | -(void)setSelectedMyButton:(BOOL)selectedMyButton 40 | { 41 | _selectedMyButton = selectedMyButton; 42 | 43 | [self setNeedsDisplay]; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /drawBoard/SelectColorView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SelectColorView.h 3 | // drawBoard 4 | // 5 | // Created by dengwei on 15/6/27. 6 | // Copyright (c) 2015年 dengwei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #pragma mark - 定义块代码 12 | typedef void(^SelectColorBlock)(UIColor *color); 13 | 14 | @interface SelectColorView:UIView 15 | 16 | //扩展initWithFrame方法,增加块代码参数 17 | //该块代码将在选择颜色按钮之后执行 18 | -(id)initWithFrame:(CGRect)frame afterSelectColor:(SelectColorBlock)afterSelectColor; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /drawBoard/SelectColorView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SelectColorView.m 3 | // drawBoard 4 | // 5 | // Created by dengwei on 15/6/27. 6 | // Copyright (c) 2015年 dengwei. All rights reserved. 7 | // 8 | 9 | #import "SelectColorView.h" 10 | 11 | #define kButtonSpace 10.0 12 | 13 | @interface SelectColorView() 14 | { 15 | //选择颜色的块代码变量 16 | SelectColorBlock _selectColorBlock; 17 | } 18 | 19 | @property (strong, nonatomic)NSArray *colorArray; 20 | 21 | @end 22 | 23 | @implementation SelectColorView 24 | 25 | -(id)initWithFrame:(CGRect)frame afterSelectColor:(SelectColorBlock)afterSelectColor 26 | { 27 | self = [super initWithFrame:frame]; 28 | 29 | if (self) { 30 | _selectColorBlock = afterSelectColor; 31 | 32 | [self setBackgroundColor:[UIColor lightGrayColor]]; 33 | 34 | //绘制颜色的按钮 35 | NSArray *array = @[[UIColor darkGrayColor], 36 | [UIColor redColor], 37 | [UIColor greenColor], 38 | [UIColor blueColor], 39 | [UIColor yellowColor], 40 | [UIColor orangeColor], 41 | [UIColor purpleColor], 42 | [UIColor brownColor], 43 | [UIColor blackColor] 44 | ]; 45 | 46 | self.colorArray = array; 47 | [self createColorButtonsWithArray:array]; 48 | 49 | } 50 | 51 | return self; 52 | } 53 | 54 | #pragma mark - 绘制颜色的按钮 55 | -(void)createColorButtonsWithArray:(NSArray *)array 56 | { 57 | //1.计算按钮的位置 58 | //2.设置按钮的颜色,需要使用数组 59 | //需要按钮的宽度,起始点位置 60 | NSInteger index = 0; 61 | NSInteger count = array.count; 62 | CGFloat width = (self.bounds.size.width - (count + 1) * kButtonSpace) / count; 63 | CGFloat height = self.bounds.size.height; 64 | 65 | for(NSString *text in array){ 66 | 67 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 68 | 69 | CGFloat startX = kButtonSpace + index * (width + kButtonSpace); 70 | [button setFrame:CGRectMake(startX, kButtonSpace / 2, width, height - 10)]; 71 | //设置按钮背景颜色 72 | [button setBackgroundColor:array[index]]; 73 | [button setTag:index]; 74 | 75 | 76 | [button addTarget:self action:@selector(tapButton:) forControlEvents:UIControlEventTouchUpInside]; 77 | 78 | [self addSubview:button]; 79 | 80 | index++; 81 | } 82 | } 83 | 84 | #pragma mark - 按钮监听方法 85 | -(void)tapButton:(UIButton *)button 86 | { 87 | //调用块代码 88 | _selectColorBlock(self.colorArray[button.tag]); 89 | 90 | } 91 | 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /drawBoard/SelectLineWidthView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SelectLineWidthView.h 3 | // drawBoard 4 | // 5 | // Created by dengwei on 15/6/27. 6 | // Copyright (c) 2015年 dengwei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #pragma mark - 定义块代码 12 | typedef void(^SelectLineWidthBlock)(CGFloat lineWidth); 13 | 14 | @interface SelectLineWidthView:UIView 15 | 16 | //扩展initWithFrame方法,增加块代码参数 17 | //该块代码将在选择线宽按钮之后执行 18 | -(id)initWithFrame:(CGRect)frame afterSelectLineWidth:(SelectLineWidthBlock)afterSelectLineWidth; 19 | 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /drawBoard/SelectLineWidthView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SelectLineWidthView.m 3 | // drawBoard 4 | // 5 | // Created by dengwei on 15/6/27. 6 | // Copyright (c) 2015年 dengwei. All rights reserved. 7 | // 8 | 9 | #import "SelectLineWidthView.h" 10 | 11 | //针对不同的界面,因为按钮的数量是不同的,有时候需要调整按钮间距,保证好的视觉效果 12 | #define kButtonSpace 10.0 13 | 14 | @interface SelectLineWidthView() 15 | { 16 | SelectLineWidthBlock _selectLineWidthBlock; 17 | } 18 | 19 | @property (strong, nonatomic)NSArray *lineWidthArray; 20 | 21 | @end 22 | 23 | @implementation SelectLineWidthView 24 | 25 | -(id)initWithFrame:(CGRect)frame afterSelectLineWidth:(SelectLineWidthBlock)afterSelectLineWidth 26 | { 27 | self = [super initWithFrame:frame]; 28 | 29 | if (self) { 30 | _selectLineWidthBlock = afterSelectLineWidth; 31 | 32 | [self setBackgroundColor:[UIColor lightGrayColor]]; 33 | 34 | //绘制颜色的按钮 35 | NSArray *array = @[@(1.0),@(3.0),@(5.0),@(8.0),@(10.0),@(15.0),@(20.0)]; 36 | 37 | self.lineWidthArray = array; 38 | [self createLineWidthButtonsWithArray:array]; 39 | } 40 | 41 | return self; 42 | } 43 | 44 | #pragma mark - 创建选择线宽的按钮 45 | -(void)createLineWidthButtonsWithArray:(NSArray *)array 46 | { 47 | //1.计算按钮的位置 48 | //2.设置按钮的颜色,需要使用数组 49 | //需要按钮的宽度,起始点位置 50 | NSInteger index = 0; 51 | NSInteger count = array.count; 52 | CGFloat width = (self.bounds.size.width - (count + 1) * kButtonSpace) / count; 53 | CGFloat height = self.bounds.size.height; 54 | 55 | for(NSString *text in array){ 56 | 57 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 58 | 59 | CGFloat startX = kButtonSpace + index * (width + kButtonSpace); 60 | [button setFrame:CGRectMake(startX, kButtonSpace / 2, width, height - 10)]; 61 | //设置选择线宽的提示文字 62 | NSString *textTip = [NSString stringWithFormat:@"%@", self.lineWidthArray[index]]; 63 | [button setTitle:textTip forState:UIControlStateNormal]; 64 | [button.titleLabel setFont:[UIFont systemFontOfSize:16.0]]; 65 | 66 | [button setTag:index]; 67 | 68 | 69 | [button addTarget:self action:@selector(tapButton:) forControlEvents:UIControlEventTouchUpInside]; 70 | 71 | [self addSubview:button]; 72 | 73 | index++; 74 | } 75 | 76 | } 77 | 78 | #pragma mark - 按钮监听方法 79 | -(void)tapButton:(UIButton *)button 80 | { 81 | //把按钮对应的线宽数值作为块代码参数,执行块代码 82 | _selectLineWidthBlock([self.lineWidthArray[button.tag]floatValue]); 83 | 84 | } 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /drawBoard/ToolView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ToolView.h 3 | // drawBoard 4 | // 5 | // Created by dengwei on 15/6/27. 6 | // Copyright (c) 2015年 dengwei. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SelectColorView.h" 11 | #import "SelectLineWidthView.h" 12 | 13 | #pragma mark - 定义块代码 14 | //typedef void(^ToolViewSelectEraserBlock)(); 15 | //typedef void(^ToolViewSelectUndoBlock)(); 16 | //typedef void(^ToolViewSelectClearScreenBlock)(); 17 | //typedef void(^ToolViewSelectCameraBlock)(); 18 | #pragma mark - 工具视图的操作块代码 19 | typedef void(^ToolViewActionBlock)(); 20 | 21 | @interface ToolView:UIView 22 | 23 | //扩展initWithFrame方法,增加块代码参数 24 | -(id)initWithFrame:(CGRect)frame 25 | afterSelectColor:(SelectColorBlock)afterSelectColor 26 | afterSelectLineWidth:(SelectLineWidthBlock)afterSelectLineWidth 27 | afterSelectEraser:(ToolViewActionBlock)afterSelectEraser 28 | afterSelectUndo:(ToolViewActionBlock)afterSelectUndo 29 | afterSelectClearScreen:(ToolViewActionBlock)afterSelectClearScreen 30 | afterSelectCamera:(ToolViewActionBlock)afterSelectCamera; 31 | 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /drawBoard/ToolView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ToolView.m 3 | // drawBoard 4 | // 5 | // Created by dengwei on 15/6/27. 6 | // Copyright (c) 2015年 dengwei. All rights reserved. 7 | // 8 | 9 | #import "ToolView.h" 10 | #import "MyButton.h" 11 | #import "SelectColorView.h" 12 | 13 | #define kButtonSpace 10.0 14 | 15 | //注意,枚举的顺序要和按钮名称的顺序保持一致 16 | typedef enum 17 | { 18 | kButtonColor = 0, 19 | kButtonLineWidth, 20 | kButtonEarser, 21 | kButtonUndo, 22 | kButtonClearScreen, 23 | kButtonCamera, 24 | kButtonSave 25 | }kButtonActionType; 26 | 27 | @interface ToolView() 28 | { 29 | SelectColorBlock _selectColorBlock; 30 | SelectLineWidthBlock _selectLineWidthBlock; 31 | ToolViewActionBlock _toolViewSelectEraserBlock; 32 | ToolViewActionBlock _toolViewSelectUndoBlock; 33 | ToolViewActionBlock _toolViewSelectClearScreenBlock; 34 | ToolViewActionBlock _toolViewSelectCameraBlock; 35 | } 36 | 37 | @property (weak, nonatomic)MyButton *selectButton; 38 | 39 | @property (weak, nonatomic)SelectColorView *colorView; 40 | 41 | @property (weak, nonatomic)SelectLineWidthView *lineWidthView; 42 | 43 | @end 44 | 45 | @implementation ToolView 46 | 47 | -(id)initWithFrame:(CGRect)frame 48 | afterSelectColor:(SelectColorBlock)afterSelectColor 49 | afterSelectLineWidth:(SelectLineWidthBlock)afterSelectLineWidth 50 | afterSelectEraser:(ToolViewActionBlock)afterSelectEraser 51 | afterSelectUndo:(ToolViewActionBlock)afterSelectUndo 52 | afterSelectClearScreen:(ToolViewActionBlock)afterSelectClearScreen 53 | afterSelectCamera:(ToolViewActionBlock)afterSelectCamera 54 | { 55 | self = [super initWithFrame:frame]; 56 | 57 | if (self) { 58 | _selectColorBlock = afterSelectColor; 59 | _selectLineWidthBlock = afterSelectLineWidth; 60 | _toolViewSelectEraserBlock = afterSelectEraser; 61 | _toolViewSelectUndoBlock = afterSelectUndo; 62 | _toolViewSelectClearScreenBlock = afterSelectClearScreen; 63 | _toolViewSelectCameraBlock = afterSelectCamera; 64 | 65 | [self setBackgroundColor:[UIColor lightGrayColor]]; 66 | 67 | //通过循环的方式创建按钮 68 | NSArray *array = @[@"颜色",@"线宽",@"橡皮",@"撤销",@"清屏",@"相册",@"保存"]; 69 | 70 | [self createButtonsWithArray:array]; 71 | 72 | } 73 | 74 | return self; 75 | } 76 | 77 | #pragma mark - 创建工具视图中的按钮 78 | -(void)createButtonsWithArray:(NSArray *)array 79 | { 80 | //需要按钮的宽度,起始点位置 81 | NSInteger index = 0; 82 | NSInteger count = array.count; 83 | CGFloat width = (self.bounds.size.width - (count + 1) * kButtonSpace) / count; 84 | CGFloat height = self.bounds.size.height; 85 | 86 | for(NSString *text in array){ 87 | 88 | MyButton *button = [MyButton buttonWithType:UIButtonTypeCustom]; 89 | 90 | CGFloat startX = kButtonSpace + index * (width + kButtonSpace); 91 | [button setFrame:CGRectMake(startX, kButtonSpace / 2, width, height - 10)]; 92 | 93 | [button setTitle:text forState:UIControlStateNormal]; 94 | [button setTag:index]; 95 | 96 | 97 | [button addTarget:self action:@selector(tapButton:) forControlEvents:UIControlEventTouchUpInside]; 98 | 99 | [self addSubview:button]; 100 | 101 | //test coding 102 | //[button setSelectedMyButton:YES]; 103 | 104 | index++; 105 | } 106 | } 107 | 108 | #pragma mark - 按钮监听方法 109 | -(void)tapButton:(MyButton *)button 110 | { 111 | 112 | //方法1:遍历所有的按钮,将selectedMyButton设置为NO,取消所有的下方红线 113 | //方法2:在属性中记录前一次选中的按钮,将该按钮的属性设置为NO 114 | if (self.selectButton != nil && self.selectButton != button) { 115 | [self.selectButton setSelectedMyButton:NO]; 116 | } 117 | 118 | //通过设置当前按钮selectedMyButton属性,在下方绘制红线 119 | [button setSelectedMyButton:YES]; 120 | self.selectButton = button; 121 | 122 | switch (button.tag) { 123 | case kButtonColor: 124 | //点击按钮时强行关闭当前显示的子视图 125 | [self forceHideView:self.colorView]; 126 | 127 | //显示/隐藏颜色选择视图 128 | [self showHideColorView]; 129 | break; 130 | case kButtonLineWidth: 131 | [self forceHideView:self.lineWidthView]; 132 | //显示/隐藏线宽选择视图 133 | [self showHideLineWidthView]; 134 | break; 135 | case kButtonEarser: 136 | //以变量的方式调用视图控制器的块代码 137 | _toolViewSelectEraserBlock(); 138 | [self forceHideView:nil]; 139 | break; 140 | case kButtonUndo: 141 | //以变量的方式调用视图控制器的块代码 142 | _toolViewSelectUndoBlock(); 143 | [self forceHideView:nil]; 144 | break; 145 | case kButtonClearScreen: 146 | //以变量的方式调用视图控制器的块代码 147 | _toolViewSelectClearScreenBlock(); 148 | [self forceHideView:nil]; 149 | break; 150 | case kButtonCamera: 151 | //以变量的方式调用视图控制器的块代码 152 | _toolViewSelectCameraBlock(); 153 | [self forceHideView:nil]; 154 | break; 155 | case kButtonSave: 156 | break; 157 | 158 | default: 159 | break; 160 | } 161 | 162 | } 163 | 164 | #pragma mark - 子视图操作方法 165 | #pragma mark 强行隐藏当前显示的子视图 166 | //如果显示的视图与传入的比较视图相同,则不再关闭 167 | -(void)forceHideView:(UIView *)compareView 168 | { 169 | //1.用属性记录当前显示的子视图,强行关闭视图即可 170 | //2.遍历所有子视图,如果处于显示状态,则将其关闭 171 | //3.直接判断子视图,此方法仅适用于子视图数量极少情况 172 | UIView *view = nil; 173 | if (self.colorView.frame.origin.y > 0) { 174 | view = self.colorView; 175 | }else if (self.lineWidthView.frame.origin.y > 0){ 176 | view = self.lineWidthView; 177 | }else{ 178 | return; 179 | } 180 | 181 | if (view == compareView) { 182 | return; 183 | } 184 | 185 | //视图 186 | CGRect toFrame = view.frame; 187 | //工具条视图边框 188 | CGRect toolFrame = self.frame; 189 | 190 | toFrame.origin.y = -44; 191 | toolFrame.size.height = 44; 192 | 193 | [UIView animateWithDuration:0.5f animations:^{ 194 | [self setFrame:toolFrame]; 195 | [view setFrame:toFrame]; 196 | }]; 197 | } 198 | 199 | #pragma mark 显示/隐藏指定视图 200 | -(void)showHideView:(UIView *)view 201 | { 202 | //动画显示视图 203 | CGRect toFrame = view.frame; 204 | //工具条视图边框 205 | CGRect toolFrame = self.frame; 206 | if (toFrame.origin.y < 0) { 207 | //隐藏时显示 208 | toFrame.origin.y = 44; 209 | toolFrame.size.height = 88; 210 | }else{ 211 | toFrame.origin.y = -44; 212 | toolFrame.size.height = 44; 213 | } 214 | 215 | [UIView animateWithDuration:0.5f animations:^{ 216 | [self setFrame:toolFrame]; 217 | [view setFrame:toFrame]; 218 | }]; 219 | } 220 | 221 | #pragma mark 显示/隐藏线宽选择视图 222 | -(void)showHideLineWidthView 223 | { 224 | //1.懒加载线宽视图 225 | if (self.lineWidthView == nil) { 226 | SelectLineWidthView *view = [[SelectLineWidthView alloc]initWithFrame:CGRectMake(0, -44, 375, 44) afterSelectLineWidth:^(CGFloat lineWidth) { 227 | _selectLineWidthBlock(lineWidth); 228 | [self forceHideView:nil]; 229 | 230 | }]; 231 | 232 | [self addSubview:view]; 233 | 234 | self.lineWidthView = view; 235 | 236 | } 237 | //2.动画显示线宽视图 238 | [self showHideView:self.lineWidthView]; 239 | } 240 | 241 | #pragma mark 显示/隐藏颜色选择视图 242 | -(void)showHideColorView 243 | { 244 | //1.懒加载颜色视图 245 | if (self.colorView == nil) { 246 | SelectColorView *view = [[SelectColorView alloc]initWithFrame:CGRectMake(0, -44, 375, 44) afterSelectColor:^(UIColor *color){ 247 | 248 | //以函数的方式调用块代码变量 249 | _selectColorBlock(color); 250 | 251 | //选择颜色后,强行关闭颜色选择子视图 252 | [self forceHideView:nil]; 253 | 254 | }]; 255 | 256 | [self addSubview:view]; 257 | 258 | self.colorView = view; 259 | } 260 | //2.动画显示颜色视图 261 | [self showHideView:self.colorView]; 262 | } 263 | 264 | @end 265 | -------------------------------------------------------------------------------- /drawBoard/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // drawBoard 4 | // 5 | // Created by dengwei on 15/6/27. 6 | // Copyright (c) 2015年 dengwei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /drawBoard/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // drawBoard 4 | // 5 | // Created by dengwei on 15/6/27. 6 | // Copyright (c) 2015年 dengwei. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "DrawView.h" 11 | #import "ToolView.h" 12 | 13 | @interface ViewController () 14 | 15 | @property (weak, nonatomic)DrawView *drawView; 16 | 17 | @end 18 | 19 | @implementation ViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | // Do any additional setup after loading the view, typically from a nib. 24 | 25 | DrawView *drawView = [[DrawView alloc]initWithFrame:self.view.bounds]; 26 | [self.view addSubview:drawView]; 27 | self.drawView = drawView; 28 | 29 | ToolView *toolView = [[ToolView alloc]initWithFrame:CGRectMake(0, 0, 375, 44) afterSelectColor:^(UIColor *color) { 30 | //给绘图视图设置颜色 31 | [drawView setDrawColor:color]; 32 | 33 | 34 | } afterSelectLineWidth:^(CGFloat lineWidth) { 35 | //给绘图视图设置线宽 36 | [drawView setLineWidth:lineWidth]; 37 | 38 | } afterSelectEraser:^{ 39 | [drawView setDrawColor:[UIColor whiteColor]]; 40 | //[drawView setLineWidth:30.0]; 41 | 42 | } afterSelectUndo:^{ 43 | [drawView undoStep]; 44 | } afterSelectClearScreen:^{ 45 | [drawView clearScreen]; 46 | } afterSelectCamera:^{ 47 | //弹出图像选择窗口,来选择照片 48 | UIImagePickerController *picker = [[UIImagePickerController alloc]init]; 49 | 50 | //1.设置照片源 51 | [picker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary]; 52 | 53 | //2.设置代理 54 | [picker setDelegate:self]; 55 | 56 | //3.显示 57 | [self presentViewController:picker animated:YES completion:nil]; 58 | }]; 59 | 60 | [self.view addSubview:toolView]; 61 | } 62 | 63 | #pragma mark - 照片选择代理方法 64 | -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info 65 | { 66 | UIImage *image = info[@"UIImagePickerControllerOriginalImage"]; 67 | 68 | //设置绘图视图 69 | [self.drawView setImage:image]; 70 | 71 | //关闭照片选择窗口 72 | [self dismissViewControllerAnimated:YES completion:nil]; 73 | } 74 | 75 | - (void)didReceiveMemoryWarning { 76 | [super didReceiveMemoryWarning]; 77 | // Dispose of any resources that can be recreated. 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /drawBoard/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // drawBoard 4 | // 5 | // Created by dengwei on 15/6/27. 6 | // Copyright (c) 2015年 dengwei. 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 | -------------------------------------------------------------------------------- /drawBoard/readme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charsdavy/drawBoard/21f9cf5a4de69a4275a672d37efcb62e7de266d7/drawBoard/readme.txt -------------------------------------------------------------------------------- /drawBoardTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.dengwei.test.$(PRODUCT_NAME:rfc1034identifier) 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 | -------------------------------------------------------------------------------- /drawBoardTests/drawBoardTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // drawBoardTests.m 3 | // drawBoardTests 4 | // 5 | // Created by dengwei on 15/6/27. 6 | // Copyright (c) 2015年 dengwei. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface drawBoardTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation drawBoardTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /screenshots/screenshots.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charsdavy/drawBoard/21f9cf5a4de69a4275a672d37efcb62e7de266d7/screenshots/screenshots.jpg -------------------------------------------------------------------------------- /screenshots/screenshots2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charsdavy/drawBoard/21f9cf5a4de69a4275a672d37efcb62e7de266d7/screenshots/screenshots2.png -------------------------------------------------------------------------------- /screenshots/screenshots3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charsdavy/drawBoard/21f9cf5a4de69a4275a672d37efcb62e7de266d7/screenshots/screenshots3.png -------------------------------------------------------------------------------- /screenshots/screenshots4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/charsdavy/drawBoard/21f9cf5a4de69a4275a672d37efcb62e7de266d7/screenshots/screenshots4.png --------------------------------------------------------------------------------