Repository: dehli/TouchDraw Branch: master Commit: fbd92a0fd73d Files: 55 Total size: 149.5 KB Directory structure: gitextract__9wf6idb/ ├── .gitignore ├── .swift-version ├── .travis.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Demo/ │ ├── Podfile │ ├── Pods/ │ │ ├── Local Podspecs/ │ │ │ └── TouchDraw.podspec.json │ │ ├── Pods.xcodeproj/ │ │ │ └── project.pbxproj │ │ └── Target Support Files/ │ │ ├── Pods-TouchDrawDemo/ │ │ │ ├── Info.plist │ │ │ ├── Pods-TouchDrawDemo-acknowledgements.markdown │ │ │ ├── Pods-TouchDrawDemo-acknowledgements.plist │ │ │ ├── Pods-TouchDrawDemo-dummy.m │ │ │ ├── Pods-TouchDrawDemo-frameworks.sh │ │ │ ├── Pods-TouchDrawDemo-resources.sh │ │ │ ├── Pods-TouchDrawDemo-umbrella.h │ │ │ ├── Pods-TouchDrawDemo.debug.xcconfig │ │ │ ├── Pods-TouchDrawDemo.modulemap │ │ │ └── Pods-TouchDrawDemo.release.xcconfig │ │ └── TouchDraw/ │ │ ├── Info.plist │ │ ├── TouchDraw-dummy.m │ │ ├── TouchDraw-prefix.pch │ │ ├── TouchDraw-umbrella.h │ │ ├── TouchDraw.modulemap │ │ └── TouchDraw.xcconfig │ ├── TouchDrawDemo/ │ │ ├── AppDelegate.swift │ │ ├── Base.lproj/ │ │ │ ├── LaunchScreen.xib │ │ │ └── Main.storyboard │ │ ├── Images.xcassets/ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── ViewController.swift │ ├── TouchDrawDemo.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ └── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ └── xcschemes/ │ │ └── TouchDrawDemo.xcscheme │ └── TouchDrawDemo.xcworkspace/ │ ├── contents.xcworkspacedata │ └── xcshareddata/ │ └── IDEWorkspaceChecks.plist ├── LICENSE ├── Package.swift ├── README.md ├── Sources/ │ ├── Stroke.swift │ ├── StrokeSettings.swift │ └── TouchDrawView.swift ├── TouchDraw/ │ ├── Info.plist │ └── TouchDraw.h ├── TouchDraw.podspec ├── TouchDraw.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ ├── TouchDraw.xcscheme │ └── TouchDrawTests.xcscheme ├── TouchDraw.xcworkspace/ │ ├── contents.xcworkspacedata │ └── xcshareddata/ │ └── IDEWorkspaceChecks.plist ├── TouchDrawTests/ │ ├── Info.plist │ └── TouchDrawTests.swift └── install_swiftlint.sh ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Xcode # build/ *.pbxuser !default.pbxuser *.mode1v3 !default.mode1v3 *.mode2v3 !default.mode2v3 *.perspectivev3 !default.perspectivev3 xcuserdata *.xccheckout *.moved-aside DerivedData *.hmap *.ipa *.xcuserstate # CocoaPods # # We recommend against adding the Pods directory to your .gitignore. However # you should judge for yourself, the pros and cons are mentioned at: # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control # # Pods/ # Carthage # # Add this line if you want to avoid checking in source code from Carthage dependencies. # Carthage/Checkouts Carthage/Build # Swift Package Manager .build/ .DS_Store ================================================ FILE: .swift-version ================================================ 3.0.1 ================================================ FILE: .travis.yml ================================================ # Also works for Swift language: objective-c # Xcode version osx_image: xcode14.2 # Specify the opening file for the project xcode_workspace: TouchDraw.xcworkspace # Specify the main build xcode_scheme: TouchDraw # Specify the last iOS sdk xcode_sdk: iphonesimulator install: - ./install_swiftlint.sh script: - swiftlint - set -o pipefail && xcodebuild -workspace $TRAVIS_XCODE_WORKSPACE -scheme $TRAVIS_XCODE_SCHEME -sdk $TRAVIS_XCODE_SDK -destination 'OS=16.2,name=iPhone 14' build test | xcpretty ================================================ FILE: CHANGELOG.md ================================================ # 2.2.0 - Update for Xcode 15 (thanks to @ricsantos!) - Fix assertion due to zero size (thanks to @ricsantos!) - Fix [CI](https://app.travis-ci.com/github/dehli/TouchDraw) # 2.1.3 - Update Package.swift - Make TouchDrawView inherit from UIView # 2.1.2 - Fixed drawing issue where `touchDrawView` and `imageView` bounds didn't line up (thanks to @mkoorn!) - Change base class to `UIImageView` # 2.1.1 - Upgrades project to Swift 4 (thanks to @codyaweber!) # 2.1.0 - Cleaned up a lot of the library's logic - Added eraser functionality (`touchDrawView.setColor(nil)`) - Significant performance improvements! # 2.0.0 - Upgraded project to Swift 3.0.1 (thanks to @sirnacnud!) - Set correct content scale on image contexts (also thanks to @sirnacnud!) - Added some comments # 1.3.1 - Refactored project into 3 separate files (for each class) - Fixed `exportStack` so it follows `NSCoding` - Added deployment target `8.0` # 1.3.0 - Added the ability to import and export the stack. - Made the protocol methods optional. - Made the code more Swifty. # 1.2.4 - Added a few more tests - Updated `README.md` # 1.2.3 - Added a handful of tests - Updated `README.md` # 1.2.2 - Switched project settings to recommended settings - Added documentation # 1.2.1 - Fixed a bug where pressing clear wouldn't trigger `redoDisabled()` - Updated deprecated code - Added documentation # 1.2.0 - Fixed `redo()` and `undo()` so they work with various brush sizes and colors - Implemented `clearEnabled()` to the protocol - Implemented `clearDisabled()` to the protocol - Fixed a bug where `TouchDrawView` only worked when it took up the entire `ViewController`'s screen # 1.1.0 - Implemented `undo()` (using last selected brush settings) - Implemented `redo()` (using last selected brush settings) - Implemented `redoEnabled()` and `redoDisabled()` protocol methods - Implemented `undoEnabled()` and `undoDisabled()` protocol methods # 1.0.0 - Initial release - Implemented `TouchDrawView` which is a subclass of `UIView` that you can draw on - Implemented `clear()` - Implemented `exportDrawing()` - Implemented `setColor(color: UIColor)` - Implemented `setWidth(width: CGFloat)` ================================================ FILE: CODE_OF_CONDUCT.md ================================================ # Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at touchdraw@dehli.io. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing to TouchDraw First off, thank you for wanting to contribute! You rock! When contributing to this repository, please first discuss the change you wish to make via issue before making a change. Please note we have a [Code of Conduct](/CODE_OF_CONDUCT.md), please follow it in all your interactions with the project. ## Example Contributions 1. Report a bug by opening an issue. 2. Request a feature by opening an issue. 3. Discuss a feature you want to implement by opening an issue. 4. Implement a feature, by submitting a pull request. 5. Ask a question, by submitting an issue. ## Pull Request Process 1. Update `README.md` with the changes you made. 2. Add a `master` release to the top of `CHANGELOG.md` if it doesn't exist. 3. Update `CHANGELOG.md` with the changes you made under the `master` release (feel free to tag yourself!) 4. Make sure your public functions and variables are documented. ================================================ FILE: Demo/Podfile ================================================ use_frameworks! target "TouchDrawDemo" do pod 'TouchDraw', path: '../' platform :ios, '8.1' end ================================================ FILE: Demo/Pods/Local Podspecs/TouchDraw.podspec.json ================================================ { "name": "TouchDraw", "version": "2.2.0", "summary": "TouchDraw is a UIView you can draw on.", "description": "TouchDraw is a subclass of UIView that allows you to draw using touch. It exposes the following functions:\n- `exportDrawing() -> UIImage`\n- `clearDrawing()`\n- `undo()`\n- `redo()`\n- `setColor(color: UIColor?)`\n- `setWidth(width: CGFloat)`\n- `importStack(stack: [Stroke])`\n- `exportStack() -> [Stroke]`", "homepage": "https://github.com/dehli/TouchDraw", "license": { "type": "MIT", "file": "LICENSE" }, "authors": { "Christian Paul Dehli": "dehli@gatech.edu" }, "social_media_url": "http://twitter.com/cpdehli", "platforms": { "ios": "12.0" }, "source": { "git": "https://github.com/dehli/TouchDraw.git", "tag": "2.2.0" }, "source_files": "Sources/**/*.{swift}" } ================================================ FILE: Demo/Pods/Pods.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 0B7FB5AEF4AFE5656F49FC413EF85A68 /* TouchDraw-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 5444EA758DA8277797948CF46A4BD61D /* TouchDraw-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 211BC6B5249B4019D4E96B2DC1C033B1 /* Pods-TouchDrawDemo-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A3948C35DF87486E5418BBAF280C0B9 /* Pods-TouchDrawDemo-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 230738C53AF1FD048536B89BC2F237E0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; 305A60A5D22337086B06415810425658 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; 8AACAB505466AEEBB659723597BC0010 /* TouchDraw-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 535B4437B92483FE0DEFB49F0233CAA2 /* TouchDraw-dummy.m */; }; 901A90B21627B4D541D9D2E3E097620C /* Stroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = E89A502373D3E56EA893765C0E295F34 /* Stroke.swift */; }; 9265DE468D201652203B28B34C88A41A /* TouchDrawView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C58B4D42B366C162788F3E351D5FFC9 /* TouchDrawView.swift */; }; A563B92956DA6B1FA7658D6CDB436D05 /* StrokeSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 292F083F3164B387807405A151E5087A /* StrokeSettings.swift */; }; C6C09CF502546B170BC035E6949EED3E /* Pods-TouchDrawDemo-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 8F306792AB76CFE9BD510C21C21DDA11 /* Pods-TouchDrawDemo-dummy.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 8E35F417A86D02995FEDB2F4D222642B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = 4078B568085D268C4E7C16909219F06F; remoteInfo = TouchDraw; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 161082C63FE27DE5BDBF540696422C47 /* TouchDraw.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = TouchDraw.modulemap; sourceTree = ""; }; 17EFE0D395529165BA88E757E8C6E423 /* Pods-TouchDrawDemo-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TouchDrawDemo-acknowledgements.plist"; sourceTree = ""; }; 252BDC1E3A1D8CE686615CAF040C40C2 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; 292F083F3164B387807405A151E5087A /* StrokeSettings.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StrokeSettings.swift; path = Sources/StrokeSettings.swift; sourceTree = ""; }; 4B47A45C432BE77F7E85543804AAB36F /* Pods-TouchDrawDemo-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-TouchDrawDemo-acknowledgements.markdown"; sourceTree = ""; }; 4C79E5A67192ACCB8A58F6FEC33A66B0 /* Pods-TouchDrawDemo-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-TouchDrawDemo-frameworks.sh"; sourceTree = ""; }; 4D21F92790C27EBBAC4B52FD72B2DE46 /* Pods-TouchDrawDemo-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TouchDrawDemo-Info.plist"; sourceTree = ""; }; 535B4437B92483FE0DEFB49F0233CAA2 /* TouchDraw-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "TouchDraw-dummy.m"; sourceTree = ""; }; 5444EA758DA8277797948CF46A4BD61D /* TouchDraw-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "TouchDraw-umbrella.h"; sourceTree = ""; }; 5BE9E964E64F49A3514053001C6A7D9B /* Pods-TouchDrawDemo.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-TouchDrawDemo.modulemap"; sourceTree = ""; }; 6A3948C35DF87486E5418BBAF280C0B9 /* Pods-TouchDrawDemo-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TouchDrawDemo-umbrella.h"; sourceTree = ""; }; 6C58B4D42B366C162788F3E351D5FFC9 /* TouchDrawView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TouchDrawView.swift; path = Sources/TouchDrawView.swift; sourceTree = ""; }; 71BB46656F90C919FB96A3D59DF9B448 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; 71C93A90E631872513BD16F6A5CBB773 /* TouchDraw.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = TouchDraw.debug.xcconfig; sourceTree = ""; }; 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 8F306792AB76CFE9BD510C21C21DDA11 /* Pods-TouchDrawDemo-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-TouchDrawDemo-dummy.m"; sourceTree = ""; }; 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 9DF14A2248C17B3DE202FAACF1A74E0F /* Pods-TouchDrawDemo */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-TouchDrawDemo"; path = Pods_TouchDrawDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; AB4305B9D381159CE22D0332EF5F3E94 /* TouchDraw-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "TouchDraw-prefix.pch"; sourceTree = ""; }; B25A89A67988EC6476500922FAA6DBB1 /* TouchDraw.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = TouchDraw.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; B99C1463AE131BB2E21DC0A3289E396C /* TouchDraw.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = TouchDraw.release.xcconfig; sourceTree = ""; }; C12551E4E94CE844862E86A3A662F241 /* Pods-TouchDrawDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TouchDrawDemo.debug.xcconfig"; sourceTree = ""; }; D0496BAB559274643EE7EE1E2E099158 /* Pods-TouchDrawDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TouchDrawDemo.release.xcconfig"; sourceTree = ""; }; D5A344F9F2434E66FB5F1D5A3846DB8D /* TouchDraw */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = TouchDraw; path = TouchDraw.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E89A502373D3E56EA893765C0E295F34 /* Stroke.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Stroke.swift; path = Sources/Stroke.swift; sourceTree = ""; }; F83D3ADF240DC34AEA8AAC618DF185D2 /* TouchDraw-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "TouchDraw-Info.plist"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 32782AA11DFFDB9B9E789BAB5CFA401F /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 305A60A5D22337086B06415810425658 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; C001423B88228A2DADC9DEEB52DA98F9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 230738C53AF1FD048536B89BC2F237E0 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 03C6AAD9D1FB7A7931B4004660D51EAA /* TouchDraw */ = { isa = PBXGroup; children = ( E89A502373D3E56EA893765C0E295F34 /* Stroke.swift */, 292F083F3164B387807405A151E5087A /* StrokeSettings.swift */, 6C58B4D42B366C162788F3E351D5FFC9 /* TouchDrawView.swift */, 07ADAD9DCDD5FC17491CE21F994D6C5D /* Pod */, 94007F4A847109372D820901155BDADE /* Support Files */, ); name = TouchDraw; path = ../..; sourceTree = ""; }; 0754750D27FCB4E9AD45783F7F7ED513 /* Pods-TouchDrawDemo */ = { isa = PBXGroup; children = ( 5BE9E964E64F49A3514053001C6A7D9B /* Pods-TouchDrawDemo.modulemap */, 4B47A45C432BE77F7E85543804AAB36F /* Pods-TouchDrawDemo-acknowledgements.markdown */, 17EFE0D395529165BA88E757E8C6E423 /* Pods-TouchDrawDemo-acknowledgements.plist */, 8F306792AB76CFE9BD510C21C21DDA11 /* Pods-TouchDrawDemo-dummy.m */, 4C79E5A67192ACCB8A58F6FEC33A66B0 /* Pods-TouchDrawDemo-frameworks.sh */, 4D21F92790C27EBBAC4B52FD72B2DE46 /* Pods-TouchDrawDemo-Info.plist */, 6A3948C35DF87486E5418BBAF280C0B9 /* Pods-TouchDrawDemo-umbrella.h */, C12551E4E94CE844862E86A3A662F241 /* Pods-TouchDrawDemo.debug.xcconfig */, D0496BAB559274643EE7EE1E2E099158 /* Pods-TouchDrawDemo.release.xcconfig */, ); name = "Pods-TouchDrawDemo"; path = "Target Support Files/Pods-TouchDrawDemo"; sourceTree = ""; }; 07ADAD9DCDD5FC17491CE21F994D6C5D /* Pod */ = { isa = PBXGroup; children = ( 71BB46656F90C919FB96A3D59DF9B448 /* LICENSE */, 252BDC1E3A1D8CE686615CAF040C40C2 /* README.md */, B25A89A67988EC6476500922FAA6DBB1 /* TouchDraw.podspec */, ); name = Pod; sourceTree = ""; }; 3077EFCD38303A48958BA55B2CD44E5C /* Products */ = { isa = PBXGroup; children = ( 9DF14A2248C17B3DE202FAACF1A74E0F /* Pods-TouchDrawDemo */, D5A344F9F2434E66FB5F1D5A3846DB8D /* TouchDraw */, ); name = Products; sourceTree = ""; }; 578452D2E740E91742655AC8F1636D1F /* iOS */ = { isa = PBXGroup; children = ( 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */, ); name = iOS; sourceTree = ""; }; 94007F4A847109372D820901155BDADE /* Support Files */ = { isa = PBXGroup; children = ( 161082C63FE27DE5BDBF540696422C47 /* TouchDraw.modulemap */, 535B4437B92483FE0DEFB49F0233CAA2 /* TouchDraw-dummy.m */, F83D3ADF240DC34AEA8AAC618DF185D2 /* TouchDraw-Info.plist */, AB4305B9D381159CE22D0332EF5F3E94 /* TouchDraw-prefix.pch */, 5444EA758DA8277797948CF46A4BD61D /* TouchDraw-umbrella.h */, 71C93A90E631872513BD16F6A5CBB773 /* TouchDraw.debug.xcconfig */, B99C1463AE131BB2E21DC0A3289E396C /* TouchDraw.release.xcconfig */, ); name = "Support Files"; path = "Demo/Pods/Target Support Files/TouchDraw"; sourceTree = ""; }; 965DDADE1A5FCA7F4F91F39C75A16D20 /* Development Pods */ = { isa = PBXGroup; children = ( 03C6AAD9D1FB7A7931B4004660D51EAA /* TouchDraw */, ); name = "Development Pods"; sourceTree = ""; }; CF1408CF629C7361332E53B88F7BD30C = { isa = PBXGroup; children = ( 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, 965DDADE1A5FCA7F4F91F39C75A16D20 /* Development Pods */, D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */, 3077EFCD38303A48958BA55B2CD44E5C /* Products */, E1D450F7B48CE34D607114A7299BD9A6 /* Targets Support Files */, ); sourceTree = ""; }; D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */ = { isa = PBXGroup; children = ( 578452D2E740E91742655AC8F1636D1F /* iOS */, ); name = Frameworks; sourceTree = ""; }; E1D450F7B48CE34D607114A7299BD9A6 /* Targets Support Files */ = { isa = PBXGroup; children = ( 0754750D27FCB4E9AD45783F7F7ED513 /* Pods-TouchDrawDemo */, ); name = "Targets Support Files"; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 89813EFE68021BE7D0CD023843A6C1A5 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 211BC6B5249B4019D4E96B2DC1C033B1 /* Pods-TouchDrawDemo-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; FC3F0EA066AC99758052AF1B2DCC65F4 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 0B7FB5AEF4AFE5656F49FC413EF85A68 /* TouchDraw-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 4078B568085D268C4E7C16909219F06F /* TouchDraw */ = { isa = PBXNativeTarget; buildConfigurationList = 4EBB3B7E7AA48F79976D8FDD4DC27228 /* Build configuration list for PBXNativeTarget "TouchDraw" */; buildPhases = ( FC3F0EA066AC99758052AF1B2DCC65F4 /* Headers */, B6E795E9C40AF26135EEE154F89DCEB9 /* Sources */, C001423B88228A2DADC9DEEB52DA98F9 /* Frameworks */, FA8C4BC0E1F7AAE8E9B334B62A71B051 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = TouchDraw; productName = TouchDraw; productReference = D5A344F9F2434E66FB5F1D5A3846DB8D /* TouchDraw */; productType = "com.apple.product-type.framework"; }; 7A871CE577368070176CD9511C551648 /* Pods-TouchDrawDemo */ = { isa = PBXNativeTarget; buildConfigurationList = 3728BAD3BB84AAE1B5FEBDA7FF2D2B09 /* Build configuration list for PBXNativeTarget "Pods-TouchDrawDemo" */; buildPhases = ( 89813EFE68021BE7D0CD023843A6C1A5 /* Headers */, 8B2227A61DCCD495A8555782349AF713 /* Sources */, 32782AA11DFFDB9B9E789BAB5CFA401F /* Frameworks */, 48D3178E20C35F2FDDB895826A9E0517 /* Resources */, ); buildRules = ( ); dependencies = ( D3B35B855917C6BBB1199C778A8CE4BC /* PBXTargetDependency */, ); name = "Pods-TouchDrawDemo"; productName = Pods_TouchDrawDemo; productReference = 9DF14A2248C17B3DE202FAACF1A74E0F /* Pods-TouchDrawDemo */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ BFDFE7DC352907FC980B868725387E98 /* Project object */ = { isa = PBXProject; attributes = { LastSwiftUpdateCheck = 1300; LastUpgradeCheck = 1300; }; buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( Base, en, ); mainGroup = CF1408CF629C7361332E53B88F7BD30C; productRefGroup = 3077EFCD38303A48958BA55B2CD44E5C /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 7A871CE577368070176CD9511C551648 /* Pods-TouchDrawDemo */, 4078B568085D268C4E7C16909219F06F /* TouchDraw */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 48D3178E20C35F2FDDB895826A9E0517 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; FA8C4BC0E1F7AAE8E9B334B62A71B051 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 8B2227A61DCCD495A8555782349AF713 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( C6C09CF502546B170BC035E6949EED3E /* Pods-TouchDrawDemo-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; B6E795E9C40AF26135EEE154F89DCEB9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 901A90B21627B4D541D9D2E3E097620C /* Stroke.swift in Sources */, A563B92956DA6B1FA7658D6CDB436D05 /* StrokeSettings.swift in Sources */, 8AACAB505466AEEBB659723597BC0010 /* TouchDraw-dummy.m in Sources */, 9265DE468D201652203B28B34C88A41A /* TouchDrawView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ D3B35B855917C6BBB1199C778A8CE4BC /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = TouchDraw; target = 4078B568085D268C4E7C16909219F06F /* TouchDraw */; targetProxy = 8E35F417A86D02995FEDB2F4D222642B /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ 68503FC2431E8A37AE0FB79845599370 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = D0496BAB559274643EE7EE1E2E099158 /* Pods-TouchDrawDemo.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "Target Support Files/Pods-TouchDrawDemo/Pods-TouchDrawDemo-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-TouchDrawDemo/Pods-TouchDrawDemo.modulemap"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; 6E2567B4BB8D2927ED8D381CC59A6391 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = C12551E4E94CE844862E86A3A662F241 /* Pods-TouchDrawDemo.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "Target Support Files/Pods-TouchDrawDemo/Pods-TouchDrawDemo-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-TouchDrawDemo/Pods-TouchDrawDemo.modulemap"; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; 6F8841CFBC22A1D21664A78055B72922 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 71C93A90E631872513BD16F6A5CBB773 /* TouchDraw.debug.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_PREFIX_HEADER = "Target Support Files/TouchDraw/TouchDraw-prefix.pch"; INFOPLIST_FILE = "Target Support Files/TouchDraw/TouchDraw-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/TouchDraw/TouchDraw.modulemap"; PRODUCT_MODULE_NAME = TouchDraw; PRODUCT_NAME = TouchDraw; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; 8F43E8ACC75C6601D5016EC4DBD476D1 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "POD_CONFIGURATION_DEBUG=1", "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.1; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; STRIP_INSTALLED_PRODUCT = NO; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; SYMROOT = "${SRCROOT}/../build"; }; name = Debug; }; 96FC937F9C05C7467D7014D952B370B2 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = B99C1463AE131BB2E21DC0A3289E396C /* TouchDraw.release.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_PREFIX_HEADER = "Target Support Files/TouchDraw/TouchDraw-prefix.pch"; INFOPLIST_FILE = "Target Support Files/TouchDraw/TouchDraw-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/TouchDraw/TouchDraw.modulemap"; PRODUCT_MODULE_NAME = TouchDraw; PRODUCT_NAME = TouchDraw; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; 975D96EA061DE0BC33417E43C6BC053C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "POD_CONFIGURATION_RELEASE=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.1; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; STRIP_INSTALLED_PRODUCT = NO; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; SYMROOT = "${SRCROOT}/../build"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 3728BAD3BB84AAE1B5FEBDA7FF2D2B09 /* Build configuration list for PBXNativeTarget "Pods-TouchDrawDemo" */ = { isa = XCConfigurationList; buildConfigurations = ( 6E2567B4BB8D2927ED8D381CC59A6391 /* Debug */, 68503FC2431E8A37AE0FB79845599370 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { isa = XCConfigurationList; buildConfigurations = ( 8F43E8ACC75C6601D5016EC4DBD476D1 /* Debug */, 975D96EA061DE0BC33417E43C6BC053C /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4EBB3B7E7AA48F79976D8FDD4DC27228 /* Build configuration list for PBXNativeTarget "TouchDraw" */ = { isa = XCConfigurationList; buildConfigurations = ( 6F8841CFBC22A1D21664A78055B72922 /* Debug */, 96FC937F9C05C7467D7014D952B370B2 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */; } ================================================ FILE: Demo/Pods/Target Support Files/Pods-TouchDrawDemo/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier ${PRODUCT_BUNDLE_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType FMWK CFBundleShortVersionString 1.0.0 CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} NSPrincipalClass ================================================ FILE: Demo/Pods/Target Support Files/Pods-TouchDrawDemo/Pods-TouchDrawDemo-acknowledgements.markdown ================================================ # Acknowledgements This application makes use of the following third party libraries: ## TouchDraw The MIT License (MIT) Copyright (c) 2015 Christian Paul Dehli Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Generated by CocoaPods - https://cocoapods.org ================================================ FILE: Demo/Pods/Target Support Files/Pods-TouchDrawDemo/Pods-TouchDrawDemo-acknowledgements.plist ================================================ PreferenceSpecifiers FooterText This application makes use of the following third party libraries: Title Acknowledgements Type PSGroupSpecifier FooterText The MIT License (MIT) Copyright (c) 2015 Christian Paul Dehli Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. License MIT Title TouchDraw Type PSGroupSpecifier FooterText Generated by CocoaPods - https://cocoapods.org Title Type PSGroupSpecifier StringsTable Acknowledgements Title Acknowledgements ================================================ FILE: Demo/Pods/Target Support Files/Pods-TouchDrawDemo/Pods-TouchDrawDemo-dummy.m ================================================ #import @interface PodsDummy_Pods_TouchDrawDemo : NSObject @end @implementation PodsDummy_Pods_TouchDrawDemo @end ================================================ FILE: Demo/Pods/Target Support Files/Pods-TouchDrawDemo/Pods-TouchDrawDemo-frameworks.sh ================================================ #!/bin/sh set -e set -u set -o pipefail function on_error { echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" } trap 'on_error $LINENO' ERR if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy # frameworks to, so exit 0 (signalling the script phase was successful). exit 0 fi echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" BCSYMBOLMAP_DIR="BCSymbolMaps" # This protects against multiple targets copying the same framework dependency at the same time. The solution # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") # Copies and strips a vendored framework install_framework() { if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then local source="${BUILT_PRODUCTS_DIR}/$1" elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" elif [ -r "$1" ]; then local source="$1" fi local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" if [ -L "${source}" ]; then echo "Symlinked..." source="$(readlink -f "${source}")" fi if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then # Locate and install any .bcsymbolmaps if present, and remove them from the .framework before the framework is copied find "${source}/${BCSYMBOLMAP_DIR}" -name "*.bcsymbolmap"|while read f; do echo "Installing $f" install_bcsymbolmap "$f" "$destination" rm "$f" done rmdir "${source}/${BCSYMBOLMAP_DIR}" fi # Use filter instead of exclude so missing patterns don't throw errors. echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" local basename basename="$(basename -s .framework "$1")" binary="${destination}/${basename}.framework/${basename}" if ! [ -r "$binary" ]; then binary="${destination}/${basename}" elif [ -L "${binary}" ]; then echo "Destination binary is symlinked..." dirname="$(dirname "${binary}")" binary="${dirname}/$(readlink "${binary}")" fi # Strip invalid architectures so "fat" simulator / device frameworks work on device if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then strip_invalid_archs "$binary" fi # Resign the code if required by the build settings to avoid unstable apps code_sign_if_enabled "${destination}/$(basename "$1")" # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then local swift_runtime_libs swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) for lib in $swift_runtime_libs; do echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" code_sign_if_enabled "${destination}/${lib}" done fi } # Copies and strips a vendored dSYM install_dsym() { local source="$1" warn_missing_arch=${2:-true} if [ -r "$source" ]; then # Copy the dSYM into the targets temp dir. echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" local basename basename="$(basename -s .dSYM "$source")" binary_name="$(ls "$source/Contents/Resources/DWARF")" binary="${DERIVED_FILES_DIR}/${basename}.dSYM/Contents/Resources/DWARF/${binary_name}" # Strip invalid architectures from the dSYM. if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then strip_invalid_archs "$binary" "$warn_missing_arch" fi if [[ $STRIP_BINARY_RETVAL == 0 ]]; then # Move the stripped file into its final destination. echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --links --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.dSYM" "${DWARF_DSYM_FOLDER_PATH}" else # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. mkdir -p "${DWARF_DSYM_FOLDER_PATH}" touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.dSYM" fi fi } # Used as a return value for each invocation of `strip_invalid_archs` function. STRIP_BINARY_RETVAL=0 # Strip invalid architectures strip_invalid_archs() { binary="$1" warn_missing_arch=${2:-true} # Get architectures for current target binary binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" # Intersect them with the architectures we are building for intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" # If there are no archs supported by this binary then warn the user if [[ -z "$intersected_archs" ]]; then if [[ "$warn_missing_arch" == "true" ]]; then echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." fi STRIP_BINARY_RETVAL=1 return fi stripped="" for arch in $binary_archs; do if ! [[ "${ARCHS}" == *"$arch"* ]]; then # Strip non-valid architectures in-place lipo -remove "$arch" -output "$binary" "$binary" stripped="$stripped $arch" fi done if [[ "$stripped" ]]; then echo "Stripped $binary of architectures:$stripped" fi STRIP_BINARY_RETVAL=0 } # Copies the bcsymbolmap files of a vendored framework install_bcsymbolmap() { local bcsymbolmap_path="$1" local destination="${BUILT_PRODUCTS_DIR}" echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" } # Signs a framework with the provided identity code_sign_if_enabled() { if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then # Use the current code_sign_identity echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then code_sign_cmd="$code_sign_cmd &" fi echo "$code_sign_cmd" eval "$code_sign_cmd" fi } if [[ "$CONFIGURATION" == "Debug" ]]; then install_framework "${BUILT_PRODUCTS_DIR}/TouchDraw/TouchDraw.framework" fi if [[ "$CONFIGURATION" == "Release" ]]; then install_framework "${BUILT_PRODUCTS_DIR}/TouchDraw/TouchDraw.framework" fi if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then wait fi ================================================ FILE: Demo/Pods/Target Support Files/Pods-TouchDrawDemo/Pods-TouchDrawDemo-resources.sh ================================================ #!/bin/sh set -e set -u set -o pipefail if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy # resources to, so exit 0 (signalling the script phase was successful). exit 0 fi mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt > "$RESOURCES_TO_COPY" XCASSET_FILES=() # This protects against multiple targets copying the same framework dependency at the same time. The solution # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") case "${TARGETED_DEVICE_FAMILY:-}" in 1,2) TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" ;; 1) TARGET_DEVICE_ARGS="--target-device iphone" ;; 2) TARGET_DEVICE_ARGS="--target-device ipad" ;; 3) TARGET_DEVICE_ARGS="--target-device tv" ;; 4) TARGET_DEVICE_ARGS="--target-device watch" ;; *) TARGET_DEVICE_ARGS="--target-device mac" ;; esac install_resource() { if [[ "$1" = /* ]] ; then RESOURCE_PATH="$1" else RESOURCE_PATH="${PODS_ROOT}/$1" fi if [[ ! -e "$RESOURCE_PATH" ]] ; then cat << EOM error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. EOM exit 1 fi case $RESOURCE_PATH in *.storyboard) echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} ;; *.xib) echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} ;; *.framework) echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" ;; *.xcdatamodel) echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" ;; *.xcdatamodeld) echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" ;; *.xcmappingmodel) echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" ;; *.xcassets) ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") ;; *) echo "$RESOURCE_PATH" || true echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" ;; esac } mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" fi rm -f "$RESOURCES_TO_COPY" if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] then # Find all other xcassets (this unfortunately includes those of path pods and other targets). OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) while read line; do if [[ $line != "${PODS_ROOT}*" ]]; then XCASSET_FILES+=("$line") fi done <<<"$OTHER_XCASSETS" if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" else printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" fi fi ================================================ FILE: Demo/Pods/Target Support Files/Pods-TouchDrawDemo/Pods-TouchDrawDemo-umbrella.h ================================================ #ifdef __OBJC__ #import #else #ifndef FOUNDATION_EXPORT #if defined(__cplusplus) #define FOUNDATION_EXPORT extern "C" #else #define FOUNDATION_EXPORT extern #endif #endif #endif FOUNDATION_EXPORT double Pods_TouchDrawDemoVersionNumber; FOUNDATION_EXPORT const unsigned char Pods_TouchDrawDemoVersionString[]; ================================================ FILE: Demo/Pods/Target Support Files/Pods-TouchDrawDemo/Pods-TouchDrawDemo.debug.xcconfig ================================================ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/TouchDraw" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/TouchDraw/TouchDraw.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_LDFLAGS = $(inherited) -framework "TouchDraw" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES ================================================ FILE: Demo/Pods/Target Support Files/Pods-TouchDrawDemo/Pods-TouchDrawDemo.modulemap ================================================ framework module Pods_TouchDrawDemo { umbrella header "Pods-TouchDrawDemo-umbrella.h" export * module * { export * } } ================================================ FILE: Demo/Pods/Target Support Files/Pods-TouchDrawDemo/Pods-TouchDrawDemo.release.xcconfig ================================================ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/TouchDraw" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/TouchDraw/TouchDraw.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_LDFLAGS = $(inherited) -framework "TouchDraw" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES ================================================ FILE: Demo/Pods/Target Support Files/TouchDraw/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier ${PRODUCT_BUNDLE_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType FMWK CFBundleShortVersionString 2.2.0 CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} NSPrincipalClass ================================================ FILE: Demo/Pods/Target Support Files/TouchDraw/TouchDraw-dummy.m ================================================ #import @interface PodsDummy_TouchDraw : NSObject @end @implementation PodsDummy_TouchDraw @end ================================================ FILE: Demo/Pods/Target Support Files/TouchDraw/TouchDraw-prefix.pch ================================================ #ifdef __OBJC__ #import #else #ifndef FOUNDATION_EXPORT #if defined(__cplusplus) #define FOUNDATION_EXPORT extern "C" #else #define FOUNDATION_EXPORT extern #endif #endif #endif ================================================ FILE: Demo/Pods/Target Support Files/TouchDraw/TouchDraw-umbrella.h ================================================ #ifdef __OBJC__ #import #else #ifndef FOUNDATION_EXPORT #if defined(__cplusplus) #define FOUNDATION_EXPORT extern "C" #else #define FOUNDATION_EXPORT extern #endif #endif #endif FOUNDATION_EXPORT double TouchDrawVersionNumber; FOUNDATION_EXPORT const unsigned char TouchDrawVersionString[]; ================================================ FILE: Demo/Pods/Target Support Files/TouchDraw/TouchDraw.modulemap ================================================ framework module TouchDraw { umbrella header "TouchDraw-umbrella.h" export * module * { export * } } ================================================ FILE: Demo/Pods/Target Support Files/TouchDraw/TouchDraw.xcconfig ================================================ CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/TouchDraw GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES ================================================ FILE: Demo/TouchDrawDemo/AppDelegate.swift ================================================ // // AppDelegate.swift // TouchDrawDemo // // Created by Christian Paul Dehli on 10/4/15. // import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { return true } } ================================================ FILE: Demo/TouchDrawDemo/Base.lproj/LaunchScreen.xib ================================================ ================================================ FILE: Demo/TouchDrawDemo/Base.lproj/Main.storyboard ================================================ ================================================ FILE: Demo/TouchDrawDemo/Images.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "iphone", "size" : "20x20", "scale" : "2x" }, { "idiom" : "iphone", "size" : "20x20", "scale" : "3x" }, { "idiom" : "iphone", "size" : "29x29", "scale" : "1x" }, { "idiom" : "iphone", "size" : "29x29", "scale" : "2x" }, { "idiom" : "iphone", "size" : "29x29", "scale" : "3x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "3x" }, { "idiom" : "iphone", "size" : "57x57", "scale" : "1x" }, { "idiom" : "iphone", "size" : "57x57", "scale" : "2x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "3x" }, { "idiom" : "ios-marketing", "size" : "1024x1024", "scale" : "1x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Demo/TouchDrawDemo/Images.xcassets/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: Demo/TouchDrawDemo/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 LSRequiresIPhoneOS UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities armv7 CFBundleShortVersionString 1.0 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight ================================================ FILE: Demo/TouchDrawDemo/ViewController.swift ================================================ // // ViewController.swift // TouchDrawDemo // // Created by Christian Paul Dehli on 10/4/15. // import UIKit import TouchDraw class ViewController: UIViewController, TouchDrawViewDelegate { @IBOutlet var drawView: TouchDrawView! @IBOutlet weak var undoButton: UIBarButtonItem! @IBOutlet weak var redoButton: UIBarButtonItem! @IBOutlet weak var clearButton: UIBarButtonItem! @IBOutlet weak var eraserButton: UIBarButtonItem! private static let deltaWidth = CGFloat(2.0) override func viewDidLoad() { super.viewDidLoad() drawView.delegate = self drawView.setWidth(ViewController.deltaWidth) drawView.image = UIImage(named: "image.png") undoButton.isEnabled = false redoButton.isEnabled = false clearButton.isEnabled = false } @IBAction func eraserClicked(_ sender: Any) { drawView.setColor(nil) eraserButton.isEnabled = false } @IBAction func clear(_ sender: AnyObject) { drawView.clearDrawing() } // Slider can vary from 1 to 10 @IBAction func sliderChanged(_ sender: UISlider) { let newWidth = CGFloat(sender.value) * ViewController.deltaWidth drawView.setWidth(newWidth) } @IBAction func randomColor(_ sender: AnyObject) { let red = CGFloat(arc4random() % 255) / 255 let green = CGFloat(arc4random() % 255) / 255 let blue = CGFloat(arc4random() % 255) / 255 let color = UIColor(red: red, green: green, blue: blue, alpha: 1.0) drawView.setColor(color) eraserButton.isEnabled = true } @IBAction func undo(_ sender: AnyObject) { drawView.undo() } @IBAction func redo(_ sender: AnyObject) { drawView.redo() } // MARK: - TouchDrawViewDelegate func undoEnabled() { self.undoButton.isEnabled = true } func undoDisabled() { self.undoButton.isEnabled = false } func redoEnabled() { self.redoButton.isEnabled = true } func redoDisabled() { self.redoButton.isEnabled = false } func clearEnabled() { self.clearButton.isEnabled = true } func clearDisabled() { self.clearButton.isEnabled = false } } ================================================ FILE: Demo/TouchDrawDemo.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 1499231ED199365D934A6218 /* Pods_TouchDrawDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9419262A54A2526BD1ECD17D /* Pods_TouchDrawDemo.framework */; }; 9AD1F41F215DA90C00B15066 /* image.png in Resources */ = {isa = PBXBuildFile; fileRef = 9AD1F41E215DA90C00B15066 /* image.png */; }; EE43D4731A14A6F200311C06 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE43D4721A14A6F200311C06 /* AppDelegate.swift */; }; EE43D4751A14A6F200311C06 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE43D4741A14A6F200311C06 /* ViewController.swift */; }; EE43D4781A14A6F200311C06 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EE43D4761A14A6F200311C06 /* Main.storyboard */; }; EE43D47A1A14A6F200311C06 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EE43D4791A14A6F200311C06 /* Images.xcassets */; }; EE43D47D1A14A6F200311C06 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = EE43D47B1A14A6F200311C06 /* LaunchScreen.xib */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 5484535A4A7D30269DA6B1DD /* Pods-TouchDrawDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TouchDrawDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-TouchDrawDemo/Pods-TouchDrawDemo.release.xcconfig"; sourceTree = ""; }; 9419262A54A2526BD1ECD17D /* Pods_TouchDrawDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TouchDrawDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 9AD1F41E215DA90C00B15066 /* image.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = image.png; sourceTree = SOURCE_ROOT; }; A093867C58B2C460504D298A /* Pods.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods.framework; sourceTree = BUILT_PRODUCTS_DIR; }; A361851B2B8E807E7EFAF51F /* Pods-TouchDrawDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TouchDrawDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-TouchDrawDemo/Pods-TouchDrawDemo.debug.xcconfig"; sourceTree = ""; }; EE43D46D1A14A6F200311C06 /* TouchDrawDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TouchDrawDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; EE43D4711A14A6F200311C06 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; EE43D4721A14A6F200311C06 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; EE43D4741A14A6F200311C06 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; EE43D4771A14A6F200311C06 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; EE43D4791A14A6F200311C06 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; EE43D47C1A14A6F200311C06 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ EE43D46A1A14A6F200311C06 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 1499231ED199365D934A6218 /* Pods_TouchDrawDemo.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 5DDE89E35A71717243AE9141 /* Pods */ = { isa = PBXGroup; children = ( A361851B2B8E807E7EFAF51F /* Pods-TouchDrawDemo.debug.xcconfig */, 5484535A4A7D30269DA6B1DD /* Pods-TouchDrawDemo.release.xcconfig */, ); name = Pods; sourceTree = ""; }; 89D911C21C25988500DB6DDE /* UI */ = { isa = PBXGroup; children = ( EE43D4761A14A6F200311C06 /* Main.storyboard */, ); name = UI; sourceTree = ""; }; B90ADA956422C12ACFECF533 /* Frameworks */ = { isa = PBXGroup; children = ( A093867C58B2C460504D298A /* Pods.framework */, 9419262A54A2526BD1ECD17D /* Pods_TouchDrawDemo.framework */, ); name = Frameworks; sourceTree = ""; }; EE43D4641A14A6F200311C06 = { isa = PBXGroup; children = ( EE43D46F1A14A6F200311C06 /* TouchDrawDemo */, EE43D46E1A14A6F200311C06 /* Products */, B90ADA956422C12ACFECF533 /* Frameworks */, 5DDE89E35A71717243AE9141 /* Pods */, ); sourceTree = ""; }; EE43D46E1A14A6F200311C06 /* Products */ = { isa = PBXGroup; children = ( EE43D46D1A14A6F200311C06 /* TouchDrawDemo.app */, ); name = Products; sourceTree = ""; }; EE43D46F1A14A6F200311C06 /* TouchDrawDemo */ = { isa = PBXGroup; children = ( 9AD1F41E215DA90C00B15066 /* image.png */, 89D911C21C25988500DB6DDE /* UI */, EE43D4721A14A6F200311C06 /* AppDelegate.swift */, EE43D4741A14A6F200311C06 /* ViewController.swift */, EE43D4791A14A6F200311C06 /* Images.xcassets */, EE43D47B1A14A6F200311C06 /* LaunchScreen.xib */, EE43D4701A14A6F200311C06 /* Supporting Files */, ); path = TouchDrawDemo; sourceTree = ""; }; EE43D4701A14A6F200311C06 /* Supporting Files */ = { isa = PBXGroup; children = ( EE43D4711A14A6F200311C06 /* Info.plist */, ); name = "Supporting Files"; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ EE43D46C1A14A6F200311C06 /* TouchDrawDemo */ = { isa = PBXNativeTarget; buildConfigurationList = EE43D48C1A14A6F200311C06 /* Build configuration list for PBXNativeTarget "TouchDrawDemo" */; buildPhases = ( 387D09E087E530047B635643 /* [CP] Check Pods Manifest.lock */, EE43D4691A14A6F200311C06 /* Sources */, EE43D46A1A14A6F200311C06 /* Frameworks */, EE43D46B1A14A6F200311C06 /* Resources */, 92727888AFAFBE90DB06A190 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); dependencies = ( ); name = TouchDrawDemo; productName = TouchDrawDemo; productReference = EE43D46D1A14A6F200311C06 /* TouchDrawDemo.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ EE43D4651A14A6F200311C06 /* Project object */ = { isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0700; LastUpgradeCheck = 0940; ORGANIZATIONNAME = "Christian Paul Dehli"; TargetAttributes = { EE43D46C1A14A6F200311C06 = { CreatedOnToolsVersion = 6.1; LastSwiftMigration = 1000; }; }; }; buildConfigurationList = EE43D4681A14A6F200311C06 /* Build configuration list for PBXProject "TouchDrawDemo" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( English, en, Base, ); mainGroup = EE43D4641A14A6F200311C06; productRefGroup = EE43D46E1A14A6F200311C06 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( EE43D46C1A14A6F200311C06 /* TouchDrawDemo */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ EE43D46B1A14A6F200311C06 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( EE43D4781A14A6F200311C06 /* Main.storyboard in Resources */, EE43D47D1A14A6F200311C06 /* LaunchScreen.xib in Resources */, EE43D47A1A14A6F200311C06 /* Images.xcassets in Resources */, 9AD1F41F215DA90C00B15066 /* image.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ 387D09E087E530047B635643 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "${PODS_PODFILE_DIR_PATH}/Podfile.lock", "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( "$(DERIVED_FILE_DIR)/Pods-TouchDrawDemo-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 92727888AFAFBE90DB06A190 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-TouchDrawDemo/Pods-TouchDrawDemo-frameworks.sh", "${BUILT_PRODUCTS_DIR}/TouchDraw/TouchDraw.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TouchDraw.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-TouchDrawDemo/Pods-TouchDrawDemo-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ EE43D4691A14A6F200311C06 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( EE43D4751A14A6F200311C06 /* ViewController.swift in Sources */, EE43D4731A14A6F200311C06 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ EE43D4761A14A6F200311C06 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( EE43D4771A14A6F200311C06 /* Base */, ); name = Main.storyboard; sourceTree = ""; }; EE43D47B1A14A6F200311C06 /* LaunchScreen.xib */ = { isa = PBXVariantGroup; children = ( EE43D47C1A14A6F200311C06 /* Base */, ); name = LaunchScreen.xib; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ EE43D48A1A14A6F200311C06 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; EE43D48B1A14A6F200311C06 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; VALIDATE_PRODUCT = YES; }; name = Release; }; EE43D48D1A14A6F200311C06 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = A361851B2B8E807E7EFAF51F /* Pods-TouchDrawDemo.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = 1; INFOPLIST_FILE = TouchDrawDemo/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "TouchDraw Demo"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = io.dehli.touchdraw; PRODUCT_NAME = TouchDrawDemo; SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; EE43D48E1A14A6F200311C06 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 5484535A4A7D30269DA6B1DD /* Pods-TouchDrawDemo.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CURRENT_PROJECT_VERSION = 1; INFOPLIST_FILE = TouchDrawDemo/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "TouchDraw Demo"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = io.dehli.touchdraw; PRODUCT_NAME = TouchDrawDemo; SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ EE43D4681A14A6F200311C06 /* Build configuration list for PBXProject "TouchDrawDemo" */ = { isa = XCConfigurationList; buildConfigurations = ( EE43D48A1A14A6F200311C06 /* Debug */, EE43D48B1A14A6F200311C06 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; EE43D48C1A14A6F200311C06 /* Build configuration list for PBXNativeTarget "TouchDrawDemo" */ = { isa = XCConfigurationList; buildConfigurations = ( EE43D48D1A14A6F200311C06 /* Debug */, EE43D48E1A14A6F200311C06 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = EE43D4651A14A6F200311C06 /* Project object */; } ================================================ FILE: Demo/TouchDrawDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: Demo/TouchDrawDemo.xcodeproj/xcshareddata/xcschemes/TouchDrawDemo.xcscheme ================================================ ================================================ FILE: Demo/TouchDrawDemo.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: Demo/TouchDrawDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2015 Christian Paul Dehli Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Package.swift ================================================ // swift-tools-version:5.0 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "TouchDraw", platforms: [ .iOS(.v10) ], products: [ .library(name: "TouchDraw", targets: ["TouchDraw"]) ], targets: [ .target(name: "TouchDraw", path: "Sources") ] ) ================================================ FILE: README.md ================================================ # TouchDraw [![](https://travis-ci.org/dehli/TouchDraw.svg?branch=master)](https://travis-ci.org/dehli/TouchDraw) [![Join the chat at https://gitter.im/dehli/TouchDraw](https://badges.gitter.im/dehli/TouchDraw.svg)](https://gitter.im/dehli/TouchDraw?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) The `TouchDraw` module allows you to use the `TouchDrawView` class. This is a subclass of `UIView` which allows you to draw pictures with your finger. ## Installation The easiest way to include `TouchDraw` is by using `CocoaPods` and adding the following to your `Podfile`. ``` use_frameworks! pod 'TouchDraw', '~> 2.2' ``` If you're not using CocoaPods, you can add the `TouchDrawView.swift` file to your project. ## Usage You can either programmatically add the `TouchDrawView` or add it using storyboards. #### Storyboards If using storyboards, you must add a `UIView` to your storyboard. Give it the `TouchDrawView` class, and `TouchDraw` module. ![Storyboard class](https://cloud.githubusercontent.com/assets/5856011/14061970/1da011c8-f365-11e5-8362-4bbe956b6152.png) #### Code If programmatically adding the view, you can use the `init(frame: CGRect)` method to create a new instance of `TouchDrawView`. You must make sure to write `import TouchDraw` at the top of the class, and also set `isUserInteractionEnabled` to `true`. #### Customizing When customizing the `TouchDrawView` you can setting its `delegate`. The container can conform to parts of `TouchDrawViewDelegate`, which has the following functions: ``` func undoEnabled() { // triggered when undo is enabled // (only if it was previously disabled) } ``` ``` func undoDisabled() { // triggered when undo is disabled // (only if it previously enabled) } ``` ``` func redoEnabled() { // triggered when redo is enabled // (only if it was previously disabled) } ``` ``` func redoDisabled() { // triggered when redo is disabled // (only if it previously enabled) } ``` ``` func clearEnabled() { // triggered when clear is enabled // (only if it was previously disabled) } ``` ``` func clearDisabled() { // triggered when clear is disabled // (only if it previously enabled) } ``` The `TouchDrawView` exposes the following methods: - `exportDrawing() -> UIImage` - Exports a UIImage version of the drawing. - `clearDrawing()` - Clears the TouchDrawView. - `undo()` - Undo the last stroke. - `redo()` - Redo what was undone. - `setColor(color: UIColor?)` - Sets the color of future strokes, if you pass `nil` you will be erasing. - `setWidth(width: CGFloat)` - Sets the width of future strokes. - `importStack(stack: [Stroke])` - Set the `TouchDrawView` to have certain strokes (usually will be used in conjunction with `exportStack()`. - `exportStack() -> [Stroke]` - Exports the strokes from a `TouchDrawView` so they can be imported later. ## Demo If you'd like to see this library in action, you can download the entire repository and open [Demo/TouchDrawDemo.xcworkspace](Demo/TouchDrawDemo.xcworkspace). [Demo/TouchDrawDemo/ViewController.swift](Demo/TouchDrawDemo/ViewController.swift) is where most of its functionality is demonstrated. ![Demo Screenshot](https://user-images.githubusercontent.com/5856011/27687865-877fc650-5ca6-11e7-9621-48e2051ff25f.png) ## License This package has the MIT license, which can be found here: [LICENSE](/LICENSE). ## Code of Conduct Please make sure to follow the [Code of Conduct](/CODE_OF_CONDUCT.md) when you interact with this project. Thanks! ================================================ FILE: Sources/Stroke.swift ================================================ // // Stroke.swift // TouchDraw // // Created by Christian Paul Dehli on 9/4/16. // import Foundation import UIKit /// A drawing stroke open class Stroke: NSObject { /// The points that make up the stroke internal var points: [CGPoint] /// The properties of the stroke internal var settings: StrokeSettings /// Default initializer override public init() { points = [] settings = StrokeSettings() super.init() } /// Initialize a stroke with certain points and settings public convenience init(points: [CGPoint], settings: StrokeSettings) { self.init() self.points = points self.settings = StrokeSettings(settings) } /// Used to decode a Stroke with a decoder required public convenience init?(coder aDecoder: NSCoder) { var points = aDecoder.decodeObject(forKey: Stroke.pointsKey) as? [CGPoint] if points == nil { points = [] } var settings = aDecoder.decodeObject(forKey: Stroke.settingsKey) as? StrokeSettings if settings == nil { settings = StrokeSettings() } self.init(points: points!, settings: settings!) } } // MARK: - NSCoding extension Stroke: NSCoding { internal static let pointsKey = "points" internal static let settingsKey = "settings" /// Used to encode a Stroke with a coder open func encode(with aCoder: NSCoder) { aCoder.encode(self.points, forKey: Stroke.pointsKey) aCoder.encode(self.settings, forKey: Stroke.settingsKey) } } ================================================ FILE: Sources/StrokeSettings.swift ================================================ // // StrokeSettings.swift // TouchDraw // // Created by Christian Paul Dehli on 9/4/16. // import Foundation import UIKit /// Properties to describe a stroke (color, width) open class StrokeSettings: NSObject { /// Color of the brush private static let defaultColor = CIColor(color: UIColor.black) internal var color: CIColor? /// Width of the brush private static let defaultWidth = CGFloat(10.0) internal var width: CGFloat /// Default initializer override public init() { color = StrokeSettings.defaultColor width = StrokeSettings.defaultWidth super.init() } /// Initializes a StrokeSettings with another StrokeSettings object public convenience init(_ settings: StrokeSettings) { self.init() self.color = settings.color self.width = settings.width } /// Initializes a StrokeSettings with a color and width public convenience init(color: CIColor?, width: CGFloat) { self.init() self.color = color self.width = width } /// Used to decode a StrokeSettings with a decoder required public convenience init?(coder aDecoder: NSCoder) { let color = aDecoder.decodeObject(forKey: StrokeSettings.colorKey) as? CIColor var width = aDecoder.decodeObject(forKey: StrokeSettings.widthKey) as? CGFloat if width == nil { width = StrokeSettings.defaultWidth } self.init(color: color, width: width!) } } // MARK: - NSCoding extension StrokeSettings: NSCoding { internal static let colorKey = "color" internal static let widthKey = "width" /// Used to encode a StrokeSettings with a coder open func encode(with aCoder: NSCoder) { aCoder.encode(self.color, forKey: StrokeSettings.colorKey) aCoder.encode(self.width, forKey: StrokeSettings.widthKey) } } ================================================ FILE: Sources/TouchDrawView.swift ================================================ // // TouchDrawView.swift // TouchDraw // // Created by Christian Paul Dehli // import Foundation import UIKit /// The protocol which the container of TouchDrawView can conform to @objc public protocol TouchDrawViewDelegate { /// triggered when undo is enabled (only if it was previously disabled) @objc optional func undoEnabled() /// triggered when undo is disabled (only if it previously enabled) @objc optional func undoDisabled() /// triggered when redo is enabled (only if it was previously disabled) @objc optional func redoEnabled() /// triggered when redo is disabled (only if it previously enabled) @objc optional func redoDisabled() /// triggered when clear is enabled (only if it was previously disabled) @objc optional func clearEnabled() /// triggered when clear is disabled (only if it previously enabled) @objc optional func clearDisabled() } /// A subclass of UIView which allows you to draw on the view using your fingers open class TouchDrawView: UIView { /// Should be set in whichever class is using the TouchDrawView open weak var delegate: TouchDrawViewDelegate? /// Drawn underneath the strokes open var image: UIImage? { didSet(oldImage) { redrawStack() } } /// Used to register undo and redo actions fileprivate var touchDrawUndoManager = UndoManager() /// Used to keep track of all the strokes internal var stack: [Stroke] = [] /// Used to keep track of the current StrokeSettings fileprivate let settings = StrokeSettings() /// This is used to render a user's strokes fileprivate let imageView = UIImageView() /// Initializes a TouchDrawView instance override public init(frame: CGRect) { super.init(frame: frame) initialize(frame) } /// Initializes a TouchDrawView instance public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) initialize(CGRect.zero) } /// Adds the subviews and initializes stack private func initialize(_ frame: CGRect) { addSubview(imageView) draw(frame) } /// Sets the frames of the subviews override open func draw(_ rect: CGRect) { imageView.frame = rect } /// Imports the stack so that previously exported stack can be used open func importStack(_ stack: [Stroke]) { // Make sure undo is disabled if touchDrawUndoManager.canUndo { delegate?.undoDisabled?() } // Make sure that redo is disabled if touchDrawUndoManager.canRedo { delegate?.redoDisabled?() } // Make sure that clear is enabled if self.stack.count == 0 && stack.count > 0 { delegate?.clearEnabled?() } self.stack = stack redrawStack() touchDrawUndoManager.removeAllActions() } /// Used to export the current stack (each individual stroke) open func exportStack() -> [Stroke] { return stack } /// Exports the current drawing open func exportDrawing() -> UIImage { UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, false, UIScreen.main.scale) imageView.image?.draw(in: imageView.bounds) let imageFromContext = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return imageFromContext! } /// Clears the drawing @objc open func clearDrawing() { if !touchDrawUndoManager.canUndo { delegate?.undoEnabled?() } if touchDrawUndoManager.canRedo { delegate?.redoDisabled?() } if stack.count > 0 { delegate?.clearDisabled?() } touchDrawUndoManager.registerUndo(withTarget: self, selector: #selector(pushAll(_:)), object: stack) stack = [] redrawStack() } /// Sets the brush's color open func setColor(_ color: UIColor?) { if color == nil { settings.color = nil } else { settings.color = CIColor(color: color!) } } /// Sets the brush's width open func setWidth(_ width: CGFloat) { settings.width = width } /// If possible, it will redo the last undone stroke open func redo() { if touchDrawUndoManager.canRedo { let stackCount = stack.count if !touchDrawUndoManager.canUndo { delegate?.undoEnabled?() } touchDrawUndoManager.redo() if !touchDrawUndoManager.canRedo { self.delegate?.redoDisabled?() } updateClear(oldStackCount: stackCount) } } /// If possible, it will undo the last stroke open func undo() { if touchDrawUndoManager.canUndo { let stackCount = stack.count if !touchDrawUndoManager.canRedo { delegate?.redoEnabled?() } touchDrawUndoManager.undo() if !touchDrawUndoManager.canUndo { delegate?.undoDisabled?() } updateClear(oldStackCount: stackCount) } } /// Update clear after either undo or redo internal func updateClear(oldStackCount: Int) { if oldStackCount > 0 && stack.count == 0 { delegate?.clearDisabled?() } else if oldStackCount == 0 && stack.count > 0 { delegate?.clearEnabled?() } } /// Removes the last Stroke from stack @objc internal func popDrawing() { touchDrawUndoManager.registerUndo(withTarget: self, selector: #selector(pushDrawing(_:)), object: stack.popLast()) redrawStack() } /// Adds a new stroke to the stack @objc internal func pushDrawing(_ stroke: Stroke) { stack.append(stroke) drawStrokeWithContext(stroke) touchDrawUndoManager.registerUndo(withTarget: self, selector: #selector(popDrawing), object: nil) } /// Draws all of the strokes @objc internal func pushAll(_ strokes: [Stroke]) { stack = strokes redrawStack() touchDrawUndoManager.registerUndo(withTarget: self, selector: #selector(clearDrawing), object: nil) } open override func layoutSubviews() { super.layoutSubviews() redrawStack() } } // MARK: - Touch Actions extension TouchDrawView { /// Triggered when touches begin override open func touchesBegan(_ touches: Set, with event: UIEvent?) { if let touch = touches.first { let stroke = Stroke(points: [touch.location(in: self)], settings: settings) stack.append(stroke) } } /// Triggered when touches move override open func touchesMoved(_ touches: Set, with event: UIEvent?) { if let touch = touches.first { let stroke = stack.last! let lastPoint = stroke.points.last let currentPoint = touch.location(in: self) drawLineWithContext(fromPoint: lastPoint!, toPoint: currentPoint, properties: stroke.settings) stroke.points.append(currentPoint) } } /// Triggered whenever touches end, resulting in a newly created Stroke override open func touchesEnded(_ touches: Set, with event: UIEvent?) { let stroke = stack.last! if stroke.points.count == 1 { let lastPoint = stroke.points.last! drawLineWithContext(fromPoint: lastPoint, toPoint: lastPoint, properties: stroke.settings) } if !touchDrawUndoManager.canUndo { delegate?.undoEnabled?() } if touchDrawUndoManager.canRedo { delegate?.redoDisabled?() } if stack.count == 1 { delegate?.clearEnabled?() } touchDrawUndoManager.registerUndo(withTarget: self, selector: #selector(popDrawing), object: nil) } } // MARK: - Drawing fileprivate extension TouchDrawView { /// Begins the image context func beginImageContext() { UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, false, UIScreen.main.scale) } /// Ends image context and sets UIImage to what was on the context func endImageContext() { imageView.image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() } /// Draws the current image for context func drawCurrentImage() { imageView.image?.draw(in: imageView.bounds) } /// Clears view, then draws stack func redrawStack() { if imageView.frame.size == .zero { return } beginImageContext() image?.draw(in: imageView.bounds) for stroke in stack { drawStroke(stroke) } endImageContext() } /// Draws a single Stroke func drawStroke(_ stroke: Stroke) { let properties = stroke.settings let points = stroke.points if points.count == 1 { let point = points[0] drawLine(fromPoint: point, toPoint: point, properties: properties) } for index in stride(from: 1, to: points.count, by: 1) { let point0 = points[index - 1] let point1 = points[index] drawLine(fromPoint: point0, toPoint: point1, properties: properties) } } /// Draws a single Stroke (begins/ends context func drawStrokeWithContext(_ stroke: Stroke) { beginImageContext() drawCurrentImage() drawStroke(stroke) endImageContext() } /// Draws a line between two points func drawLine(fromPoint: CGPoint, toPoint: CGPoint, properties: StrokeSettings) { let context = UIGraphicsGetCurrentContext() context!.move(to: CGPoint(x: fromPoint.x, y: fromPoint.y)) context!.addLine(to: CGPoint(x: toPoint.x, y: toPoint.y)) context!.setLineCap(CGLineCap.round) context!.setLineWidth(properties.width) let color = properties.color if color != nil { context!.setStrokeColor(red: properties.color!.red, green: properties.color!.green, blue: properties.color!.blue, alpha: properties.color!.alpha) context!.setBlendMode(CGBlendMode.normal) } else { context!.setBlendMode(CGBlendMode.clear) } context!.strokePath() } /// Draws a line between two points (begins/ends context) func drawLineWithContext(fromPoint: CGPoint, toPoint: CGPoint, properties: StrokeSettings) { beginImageContext() drawCurrentImage() drawLine(fromPoint: fromPoint, toPoint: toPoint, properties: properties) endImageContext() } } ================================================ FILE: TouchDraw/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType FMWK CFBundleShortVersionString 2.2.0 CFBundleSignature ???? CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass ================================================ FILE: TouchDraw/TouchDraw.h ================================================ // // TouchDraw.h // TouchDraw // // Created by Christian Paul Dehli on 10/10/15. // Copyright © 2015 Christian Paul Dehli. All rights reserved. // #import //! Project version number for TouchDraw. FOUNDATION_EXPORT double TouchDrawVersionNumber; //! Project version string for TouchDraw. FOUNDATION_EXPORT const unsigned char TouchDrawVersionString[]; // In this header, you should import all the public headers of your framework using statements like #import ================================================ FILE: TouchDraw.podspec ================================================ # New version checklist: # Bump version in TouchDraw.podspec # Bump version in TouchDraw/Info.plist # Run pod install in Demo # Update README.md # Update CHANGELOG.md # Make sure each function and variable is documented # Add release on GitHub # pod trunk push TouchDraw.podspec (after pulling latest from master) Pod::Spec.new do |s| s.name = "TouchDraw" s.version = "2.2.0" s.summary = "TouchDraw is a UIView you can draw on." s.description = <<-DESC TouchDraw is a subclass of UIView that allows you to draw using touch. It exposes the following functions: - `exportDrawing() -> UIImage` - `clearDrawing()` - `undo()` - `redo()` - `setColor(color: UIColor?)` - `setWidth(width: CGFloat)` - `importStack(stack: [Stroke])` - `exportStack() -> [Stroke]` DESC s.homepage = "https://github.com/dehli/TouchDraw" # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" s.license = { :type => "MIT", :file => "LICENSE" } s.author = { "Christian Paul Dehli" => "dehli@gatech.edu" } s.social_media_url = "http://twitter.com/cpdehli" s.platform = :ios s.ios.deployment_target = "12.0" s.source = { :git => "https://github.com/dehli/TouchDraw.git", :tag => "#{s.version}"} s.source_files = "Sources/**/*.{swift}" end ================================================ FILE: TouchDraw.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 895DEB791CB8ADF100498FB2 /* TouchDrawView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 895DEB781CB8ADF100498FB2 /* TouchDrawView.swift */; }; 89DF760D1D7D177700D789A8 /* Stroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89DF760B1D7D177700D789A8 /* Stroke.swift */; }; 89DF760E1D7D177700D789A8 /* StrokeSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89DF760C1D7D177700D789A8 /* StrokeSettings.swift */; }; 89EADBB71CB87C23001130A8 /* TouchDrawTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89EADBB61CB87C23001130A8 /* TouchDrawTests.swift */; }; 89EADBB91CB87C23001130A8 /* TouchDraw.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 89F60F6B1BC9580000BCDD93 /* TouchDraw.framework */; }; 89F60F6F1BC9580000BCDD93 /* TouchDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = 89F60F6E1BC9580000BCDD93 /* TouchDraw.h */; settings = {ATTRIBUTES = (Public, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 89EADBBA1CB87C23001130A8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 89F60F621BC9580000BCDD93 /* Project object */; proxyType = 1; remoteGlobalIDString = 89F60F6A1BC9580000BCDD93; remoteInfo = TouchDraw; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 895DEB781CB8ADF100498FB2 /* TouchDrawView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TouchDrawView.swift; path = Sources/TouchDrawView.swift; sourceTree = ""; }; 89DF760B1D7D177700D789A8 /* Stroke.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Stroke.swift; path = Sources/Stroke.swift; sourceTree = ""; }; 89DF760C1D7D177700D789A8 /* StrokeSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = StrokeSettings.swift; path = Sources/StrokeSettings.swift; sourceTree = ""; }; 89EADBB41CB87C23001130A8 /* TouchDrawTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TouchDrawTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 89EADBB61CB87C23001130A8 /* TouchDrawTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TouchDrawTests.swift; sourceTree = ""; }; 89EADBB81CB87C23001130A8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 89F60F6B1BC9580000BCDD93 /* TouchDraw.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TouchDraw.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 89F60F6E1BC9580000BCDD93 /* TouchDraw.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TouchDraw.h; sourceTree = ""; }; 89F60F701BC9580000BCDD93 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 89EADBB11CB87C23001130A8 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 89EADBB91CB87C23001130A8 /* TouchDraw.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 89F60F671BC9580000BCDD93 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 895DEB7A1CB8AF9400498FB2 /* Sources */ = { isa = PBXGroup; children = ( 895DEB781CB8ADF100498FB2 /* TouchDrawView.swift */, 89DF760B1D7D177700D789A8 /* Stroke.swift */, 89DF760C1D7D177700D789A8 /* StrokeSettings.swift */, ); name = Sources; sourceTree = ""; }; 89EADBB51CB87C23001130A8 /* TouchDrawTests */ = { isa = PBXGroup; children = ( 89EADBB61CB87C23001130A8 /* TouchDrawTests.swift */, 89EADBB81CB87C23001130A8 /* Info.plist */, ); path = TouchDrawTests; sourceTree = ""; }; 89F60F611BC9580000BCDD93 = { isa = PBXGroup; children = ( 895DEB7A1CB8AF9400498FB2 /* Sources */, 89F60F6D1BC9580000BCDD93 /* TouchDraw */, 89EADBB51CB87C23001130A8 /* TouchDrawTests */, 89F60F6C1BC9580000BCDD93 /* Products */, ); sourceTree = ""; }; 89F60F6C1BC9580000BCDD93 /* Products */ = { isa = PBXGroup; children = ( 89F60F6B1BC9580000BCDD93 /* TouchDraw.framework */, 89EADBB41CB87C23001130A8 /* TouchDrawTests.xctest */, ); name = Products; sourceTree = ""; }; 89F60F6D1BC9580000BCDD93 /* TouchDraw */ = { isa = PBXGroup; children = ( 89F60F6E1BC9580000BCDD93 /* TouchDraw.h */, 89F60F701BC9580000BCDD93 /* Info.plist */, ); path = TouchDraw; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 89F60F681BC9580000BCDD93 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 89F60F6F1BC9580000BCDD93 /* TouchDraw.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 89EADBB31CB87C23001130A8 /* TouchDrawTests */ = { isa = PBXNativeTarget; buildConfigurationList = 89EADBBC1CB87C23001130A8 /* Build configuration list for PBXNativeTarget "TouchDrawTests" */; buildPhases = ( 89EADBB01CB87C23001130A8 /* Sources */, 89EADBB11CB87C23001130A8 /* Frameworks */, 89EADBB21CB87C23001130A8 /* Resources */, ); buildRules = ( ); dependencies = ( 89EADBBB1CB87C23001130A8 /* PBXTargetDependency */, ); name = TouchDrawTests; productName = TouchDrawTests; productReference = 89EADBB41CB87C23001130A8 /* TouchDrawTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; 89F60F6A1BC9580000BCDD93 /* TouchDraw */ = { isa = PBXNativeTarget; buildConfigurationList = 89F60F7F1BC9580000BCDD93 /* Build configuration list for PBXNativeTarget "TouchDraw" */; buildPhases = ( 89F60F661BC9580000BCDD93 /* Sources */, 89F60F671BC9580000BCDD93 /* Frameworks */, 89F60F681BC9580000BCDD93 /* Headers */, 89F60F691BC9580000BCDD93 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = TouchDraw; productName = TouchDraw; productReference = 89F60F6B1BC9580000BCDD93 /* TouchDraw.framework */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 89F60F621BC9580000BCDD93 /* Project object */ = { isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0730; LastUpgradeCheck = 0940; ORGANIZATIONNAME = "Christian Paul Dehli"; TargetAttributes = { 89EADBB31CB87C23001130A8 = { CreatedOnToolsVersion = 7.3; LastSwiftMigration = 0900; }; 89F60F6A1BC9580000BCDD93 = { CreatedOnToolsVersion = 7.0.1; LastSwiftMigration = 0900; }; }; }; buildConfigurationList = 89F60F651BC9580000BCDD93 /* Build configuration list for PBXProject "TouchDraw" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( English, en, ); mainGroup = 89F60F611BC9580000BCDD93; productRefGroup = 89F60F6C1BC9580000BCDD93 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 89F60F6A1BC9580000BCDD93 /* TouchDraw */, 89EADBB31CB87C23001130A8 /* TouchDrawTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 89EADBB21CB87C23001130A8 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 89F60F691BC9580000BCDD93 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 89EADBB01CB87C23001130A8 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 89EADBB71CB87C23001130A8 /* TouchDrawTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 89F60F661BC9580000BCDD93 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 89DF760E1D7D177700D789A8 /* StrokeSettings.swift in Sources */, 895DEB791CB8ADF100498FB2 /* TouchDrawView.swift in Sources */, 89DF760D1D7D177700D789A8 /* Stroke.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 89EADBBB1CB87C23001130A8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 89F60F6A1BC9580000BCDD93 /* TouchDraw */; targetProxy = 89EADBBA1CB87C23001130A8 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ 89EADBBD1CB87C23001130A8 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_NONNULL = YES; INFOPLIST_FILE = TouchDrawTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.dehli.TouchDrawTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 4.0; }; name = Debug; }; 89EADBBE1CB87C23001130A8 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ANALYZER_NONNULL = YES; INFOPLIST_FILE = TouchDrawTests/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.dehli.TouchDrawTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 4.0; }; name = Release; }; 89F60F7D1BC9580000BCDD93 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; 89F60F7E1BC9580000BCDD93 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; 89F60F801BC9580000BCDD93 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_MODULES = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = TouchDraw/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.dehli.TouchDraw; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 4.0; }; name = Debug; }; 89F60F811BC9580000BCDD93 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_MODULES = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = TouchDraw/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = io.dehli.TouchDraw; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 4.0; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 89EADBBC1CB87C23001130A8 /* Build configuration list for PBXNativeTarget "TouchDrawTests" */ = { isa = XCConfigurationList; buildConfigurations = ( 89EADBBD1CB87C23001130A8 /* Debug */, 89EADBBE1CB87C23001130A8 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 89F60F651BC9580000BCDD93 /* Build configuration list for PBXProject "TouchDraw" */ = { isa = XCConfigurationList; buildConfigurations = ( 89F60F7D1BC9580000BCDD93 /* Debug */, 89F60F7E1BC9580000BCDD93 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 89F60F7F1BC9580000BCDD93 /* Build configuration list for PBXNativeTarget "TouchDraw" */ = { isa = XCConfigurationList; buildConfigurations = ( 89F60F801BC9580000BCDD93 /* Debug */, 89F60F811BC9580000BCDD93 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 89F60F621BC9580000BCDD93 /* Project object */; } ================================================ FILE: TouchDraw.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: TouchDraw.xcodeproj/xcshareddata/xcschemes/TouchDraw.xcscheme ================================================ ================================================ FILE: TouchDraw.xcodeproj/xcshareddata/xcschemes/TouchDrawTests.xcscheme ================================================ ================================================ FILE: TouchDraw.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: TouchDraw.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: TouchDrawTests/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 ================================================ FILE: TouchDrawTests/TouchDrawTests.swift ================================================ // // TouchDrawTests.swift // TouchDrawTests // // Created by Christian Paul Dehli on 10/10/15. // Copyright © 2015 Christian Paul Dehli. All rights reserved. // import XCTest @testable import TouchDraw class TouchDrawTests: XCTestCase, TouchDrawViewDelegate { var undoIsEnabled: Bool! var redoIsEnabled: Bool! var clearIsEnabled: Bool! var touchDrawView: TouchDrawView! override func setUp() { super.setUp() undoIsEnabled = false redoIsEnabled = false clearIsEnabled = false touchDrawView = TouchDrawView(frame: CGRect(x: 0, y: 0, width: 256, height: 256)) touchDrawView.delegate = self } override func tearDown() { // Put teardown code here. This method is called after the invocation of each test method in the class. super.tearDown() } /// Tests that exportDrawing does indeed return a UIImage func testExportDrawing() { simulateTouch() let image = touchDrawView.exportDrawing() XCTAssertNotNil(image, "Image shouldn't be nil") } /// Tests that changing the color works func testChangeColor() { let color = UIColor.red touchDrawView.setColor(color) simulateTouch() let stroke = touchDrawView.stack.first! XCTAssert(stroke.settings.color == CIColor(color: color), "Expected stroke to be red") } /// Tests that changing the width works func testChangeWidth() { let width = CGFloat(100.0) touchDrawView.setWidth(width) simulateTouch() let stroke = touchDrawView.stack.first! XCTAssert(stroke.settings.width == width, "Expected stroke to have width of 100") } /// Tests whether clear empties the strokes func testClear() { simulateTouch() XCTAssert(touchDrawView.stack.count > 0, "Should have strokes on view") touchDrawView.clearDrawing() XCTAssert(touchDrawView.stack.count == 0, "Should not have strokes on view") } /// Tests to make sure clear is enabled after you make a stroke func testClearEnabled() { simulateTouch() XCTAssertTrue(clearIsEnabled, "Clear should be enabled after a stroke") } /// Tests to make sure clear is diabled after calling clearDrawing() func testClearDisabled() { simulateTouch() touchDrawView.clearDrawing() XCTAssertFalse(clearIsEnabled, "Clear should not be enabled after calling clearDrawing()") } /// Tests undo functionality func testUndo() { simulateTouch() XCTAssert(touchDrawView.stack.count == 1, "Should have one stroke") touchDrawView.undo() XCTAssert(touchDrawView.stack.count == 0, "Should not have any strokes") } /// Tests whether TouchDrawView enables undo after one point is drawn func testUndoEnabled() { simulateTouch() XCTAssertTrue(undoIsEnabled, "Undo should be enabled") } /// Tests whether TouchDrawView enables undo after one point is drawn func testUndoDisabled() { simulateTouch() touchDrawView.undo() XCTAssertFalse(undoIsEnabled, "Undo should not be enabled") } /// Tests redo functionality func testRedo() { simulateTouch() XCTAssert(touchDrawView.stack.count == 1, "Should have one stroke") touchDrawView.undo() XCTAssert(touchDrawView.stack.count == 0, "Should not have any strokes") touchDrawView.redo() XCTAssert(touchDrawView.stack.count == 1, "Should have one stroke") } /// Tests whether TouchDrawView enables redo after undoing a point func testRedoEnabled() { simulateTouch() touchDrawView.undo() XCTAssertTrue(redoIsEnabled, "Redo should be enabled") } /// Tests whether TouchDrawView disables redo when no more redos are available func testRedoDisabled() { simulateTouch() touchDrawView.undo() // Redo is now enabled (covered in another test) touchDrawView.redo() XCTAssertFalse(redoIsEnabled, "Redo should not be enabled") } /// Tests that importing a stack triggers clearEnabled func testImportStack() { let stroke = Stroke() stroke.points = [CGPoint(x: 0, y: 0)] touchDrawView.importStack([stroke]) XCTAssertTrue(clearIsEnabled, "Clear should be enabled after calling importStack") } /// Tests that importing an empty stack does not trigger clearEnabled func testImportEmptyStack() { touchDrawView.importStack([]) XCTAssertFalse(clearIsEnabled, "Clear should be not be enabled after calling importStack") } /// Tests that you can draw a Stroke with no points func testEmptyStroke() { let stroke = Stroke() touchDrawView.importStack([stroke]) XCTAssert(touchDrawView.stack.count == 1) } /// Tests that you can properly encode/decode a Stroke array func testEncoder() { let path = NSTemporaryDirectory() as NSString let locToSave = path.appendingPathComponent("testEncoder") let points0 = [CGPoint(x: 1, y: 2)] let settings0 = StrokeSettings() settings0.color = CIColor(color: .blue) settings0.width = 10.0 let stroke0 = Stroke(points: points0, settings: settings0) let points1 = [CGPoint(x: 1, y: 2), CGPoint(x: 3, y: 4)] let settings1 = StrokeSettings() settings1.color = nil settings1.width = 2.5 let stroke1 = Stroke(points: points1, settings: settings1) // save Strokes NSKeyedArchiver.archiveRootObject([stroke0, stroke1], toFile: locToSave) // load Strokes let data = NSKeyedUnarchiver.unarchiveObject(withFile: locToSave) as? [Stroke] XCTAssertNotNil(data) XCTAssertEqual(data!.count, 2) XCTAssertEqual(data!.first!.points, points0) XCTAssertEqual(data!.first?.settings.color?.alpha, settings0.color?.alpha) XCTAssertEqual(data!.first?.settings.color?.red, settings0.color?.red) XCTAssertEqual(data!.first?.settings.color?.green, settings0.color?.green) XCTAssertEqual(data!.first?.settings.color?.blue, settings0.color?.blue) XCTAssertEqual(data!.first?.settings.width, settings0.width) XCTAssertEqual(data!.last!.points, points1) XCTAssertEqual(data!.last!.settings.color, settings1.color) XCTAssertEqual(data!.last!.settings.width, settings1.width) } /// Internal function used to simulate a touch fileprivate func simulateTouch() { var touches = Set() touches.insert(UITouch()) touchDrawView.touchesBegan(touches, with: nil) touchDrawView.touchesEnded(touches, with: nil) } // MARK: - TouchDrawViewDelegate func undoEnabled() { self.undoIsEnabled = true } func undoDisabled() { self.undoIsEnabled = false } func redoEnabled() { self.redoIsEnabled = true } func redoDisabled() { self.redoIsEnabled = false } func clearEnabled() { self.clearIsEnabled = true } func clearDisabled() { self.clearIsEnabled = false } } ================================================ FILE: install_swiftlint.sh ================================================ #!/bin/bash # Installs the SwiftLint package. # Tries to get the precompiled .pkg file from Github, but if that # fails just recompiles from source. # Source: https://alexplescan.com/posts/2016/03/03/setting-up-swiftlint-on-travis-ci/ set -e SWIFTLINT_PKG_PATH="/tmp/SwiftLint.pkg" SWIFTLINT_PKG_URL="https://github.com/realm/SwiftLint/releases/download/0.20.0/SwiftLint.pkg" wget --output-document=$SWIFTLINT_PKG_PATH $SWIFTLINT_PKG_URL if [ -f $SWIFTLINT_PKG_PATH ]; then echo "SwiftLint package exists! Installing it..." sudo installer -pkg $SWIFTLINT_PKG_PATH -target / else echo "SwiftLint package doesn't exist. Compiling from source..." && git clone https://github.com/realm/SwiftLint.git /tmp/SwiftLint && cd /tmp/SwiftLint && git submodule update --init --recursive && sudo make install fi