Repository: Awalz/SwiftyDraw Branch: master Commit: dab0f3295187 Files: 29 Total size: 106.6 KB Directory structure: gitextract_rxluaobk/ ├── LICENSE ├── Package.swift ├── README.md ├── Source/ │ ├── Brush.swift │ ├── Color.swift │ └── SwiftyDraw.swift ├── SwiftyDraw/ │ ├── Info.plist │ └── SwiftyDraw.h ├── SwiftyDraw.podspec ├── SwiftyDraw.xcodeproj/ │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata/ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata/ │ │ ├── darrenjones.xcuserdatad/ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── shunzhema.xcuserdatad/ │ │ └── UserInterfaceState.xcuserstate │ ├── xcshareddata/ │ │ └── xcschemes/ │ │ └── SwiftyDraw.xcscheme │ └── xcuserdata/ │ └── shunzhema.xcuserdatad/ │ └── xcschemes/ │ └── xcschememanagement.plist └── SwiftyDrawExample/ ├── .gitignore ├── SwiftyDrawExample/ │ ├── AppDelegate.swift │ ├── Assets.xcassets/ │ │ └── AppIcon.appiconset/ │ │ └── Contents.json │ ├── Base.lproj/ │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Extensions.swift │ ├── Info.plist │ ├── SwiftyDrawExample.entitlements │ └── ViewController.swift └── SwiftyDrawExample.xcodeproj/ ├── project.pbxproj ├── project.xcworkspace/ │ ├── contents.xcworkspacedata │ └── xcshareddata/ │ └── IDEWorkspaceChecks.plist └── xcshareddata/ └── xcschemes/ └── SwiftyDrawExample.xcscheme ================================================ FILE CONTENTS ================================================ ================================================ FILE: LICENSE ================================================ Copyright (c) 2018 Linus Geffarth 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.3 import PackageDescription let package = Package( name: "SwiftyDraw", platforms: [ .iOS(.v9) ], products: [ .library(name: "SwiftyDraw", targets: ["SwiftyDraw"]) ], targets: [ .target(name: "SwiftyDraw", path: "Source") ] ) ================================================ FILE: README.md ================================================

SwiftyDraw

Platform: iOS 9.1+ Language: Swift 5 CocoaPods License: MIT

## Overview SwiftyDraw is a simple, light-weight drawing framework written in Swift. SwiftyDraw is built using Core Gaphics and is very easy to implement. ## Requirements * iOS 9.1+ * Swift 5.0 ## Installation ### Cocoapods: SwiftyDraw is available through [CocoaPods](http://cocoapods.org). To install it, add the following line to your Podfile: ```ruby pod 'SwiftyDraw' ``` ### Carthage SwiftyDraw is also available through [Carthage](https://github.com/Carthage/Carthage/blob/master/README.md). To install, add the following line to your Cartfile: ```ruby github "awalz/SwiftyDraw" "master" ``` ### Manual Installation: Simply copy the contents of the Source folder into your project. ## Usage Using SwiftyDraw is very simple: ### Getting Started: Create a SwiftyDrawView and add it to your ViewController: ```swift let drawView = SwiftyDrawView(frame: self.view.frame) self.view.addSubview(drawView) ``` By default, the view will automatically respond to touch gestures and begin drawing. The default brush is `.default`, which has a **black** color. To disable drawing, simply set the `isEnabled` property to `false`: ```swift drawView.isEnabled = false ``` ## Brushes For drawing, we use `Brush` to keep track of styles like `width`, `color`, etc.. We have multiple different default brushes, you can use as follows: ```swift drawView.brush = Brush.default ``` The default brushed are: ```swift public static var `default`: Brush { get } // black, width 3 public static var thin : Brush { get } // black, width 2 public static var medium : Brush { get } // black, width 7 public static var thick : Brush { get } // black, width 10 public static var marker : Brush { get } // flat red-ish, width 10 public static var eraser : Brush { get } // clear, width 8; uses CGBlendMode to erase things ``` ### Adjusted Width Factor `SwiftyDrawView` supports drawing-angle-adjusted brushes. This effectively means, if the user (using an Pencil) draws with the tip of the pencil, the brush will reduce its width a little. If the user draws at a very low angle, with the side of the pencil, the brush will be a little thicker. You can modify this behavior by setting `adjustedWidthFactor` of a brush. If you increase the number (to, say, `5`) the changes will increase. If you reduce the number to `0`, the width will not be adjusted at all. The default value is `1` which causes a slight de-/increase in width. This is an opt-in feature. That means, in `shouldBeginDrawingIn`, you need to call `drawingView.brush.adjustWidth(for: touch)`. ## Further Customization: For more customization, you can modify the different properties of a brush to fit your needs. ### Line Color: The color of a line stroke can be changed by adjusting the `color` property of a brush. SwiftyDraw accepts any `Color`: ```swift drawView.brush.color = Color(.red) ```

or

```swift drawView.brush.color = Color(UIColor(colorLiteralRed: 0.75, green: 0.50, blue: 0.88, alpha: 1.0)) ``` We have our own implementation of `UIColor` – `Color` – to be able to de-/encode it. ### Line Width: The width of a line stroke can be changed by adjusting the `width` property of a brush. SwiftyDraw accepts any positive `CGFloat`: ```swift drawView.brush.width = 5.0 ``` ### Line Opacity: The opacity of a line stroke can be changed by adjusting the `lineOpacity` property. SwiftyDraw accepts any `CGFloat` between `0` and `1`: ```swift drawView.brush.opacity = 0.5 ``` ## Editing ### Clear All: If you wish to clear the entire canvas, simply call the `clear` function: ```swift drawView.clear() ``` ### Drawing History: ```swift drawView.undo() ``` ...and redo: ```swift drawView.redo() ``` To en-/disable custom un- & redo buttons, you can use `.canUndo` and `.canRedo`. ## Apple Pencil Integration Apple Pencil can be used for drawing in a SwiftyDrawView, just like a finger. Special features, however, regarding Apple Pencil 2 are only supported on iOS 12.1 and above versions. ### Apple Pencil 2 Double Tap action #### Enable/ Disable pencil interaction Apple Pencil interaction is enabled by default, but you can set `drawView.isPencilInteractive` to change that setting. #### Pencil Events When double tapping the pencil, SwiftyDraw will check the user preferences set in the system. If the preference is set to switch to eraser, SwiftyDraw will switch between normal and erasing mode; if set to last used tool, SwiftyDraw will switch between current and previous brush. ## Delegate SwiftyDraw has delegate functions to notify you when a user is interacting with a SwiftDrawView. To access these delegate methods, have your View Controller conform to the `SwiftyDrawViewDelegate` protocol: ```swift class ViewController: UIViewController, SwiftyDrawViewDelegate ``` ### Delegate methods ```swift func swiftyDraw(shouldBeginDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) -> Bool func swiftyDraw(didBeginDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) func swiftyDraw(isDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) func swiftyDraw(didFinishDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) func swiftyDraw(didCancelDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) ``` --- ## Contribution This project was built by [Awalz](https://github.com/Awalz) and is mostly maintained & improved by [LinusGeffarth](https://github.com/LinusGeffarth). If you'd like to propose any enhancements, bug fixes, etc., feel free to create a pull request or an issue respectively. ### Contact If you have any questions, or just want to say *Hi!*, you can reach me via [Twitter](https://twitter.com/linusgeffarth), or [email](mailto:linus@geffarth.com). ### LICENSE SwiftyDraw is available under the MIT license. See the LICENSE file for more info. ================================================ FILE: Source/Brush.swift ================================================ // // Brush.swift // Sketch // // Created by Linus Geffarth on 02.05.18. // Copyright © 2018 Linus Geffarth. All rights reserved. // import UIKit public class Brush: Codable { public var color: Color /// Original brush width set when initializing the brush. Not affected by updating the brush width. Used to determine adjusted width private var _originalWidth: CGFloat /// Original brush width set when initializing the brush. Not affected by updating the brush width. Used to determine adjusted width public var originalWidth: CGFloat { return _originalWidth } public var width: CGFloat public var opacity: CGFloat public var adjustedWidthFactor: CGFloat = 1 /// Allows for actually erasing content, by setting it to `.clear`. Default is `.normal` public var blendMode: BlendMode = .normal public init(color: UIColor = .black, width: CGFloat = 3, opacity: CGFloat = 1, adjustedWidthFactor: CGFloat = 1, blendMode: BlendMode = .normal) { self.color = Color(color) self._originalWidth = width self.width = width self.opacity = opacity self.adjustedWidthFactor = adjustedWidthFactor self.blendMode = blendMode } private func adjustedWidth(for touch: UITouch) -> CGFloat { guard #available(iOS 9.1, *), touch.type == .pencil else { return originalWidth } return (originalWidth*(1-adjustedWidthFactor/10*2)) + (adjustedWidthFactor/touch.altitudeAngle) } public func adjustWidth(for touch: UITouch) { width = adjustedWidth(for: touch) } // MARK: - Static brushes public static var `default`: Brush { return Brush(color: .black, width: 3, opacity: 1) } public static var thin: Brush { return Brush(color: .black, width: 2, opacity: 1) } public static var medium: Brush { return Brush(color: .black, width: 7, opacity: 1) } public static var thick: Brush { return Brush(color: .black, width: 12, opacity: 1) } public static var marker: Brush { return Brush(color: #colorLiteral(red: 0.920953393, green: 0.447560966, blue: 0.4741248488, alpha: 1), width: 10, opacity: 0.3) } public static var eraser: Brush { return Brush(adjustedWidthFactor: 5, blendMode: .clear) } public static var selection: Brush { return Brush(color: .clear, width: 1, opacity: 1) } } extension Brush: Equatable, Comparable, CustomStringConvertible { public static func ==(lhs: Brush, rhs: Brush) -> Bool { return ( lhs.color.uiColor == rhs.color.uiColor && lhs.originalWidth == rhs.originalWidth && lhs.opacity == rhs.opacity ) } public static func <(lhs: Brush, rhs: Brush) -> Bool { return ( lhs.width < rhs.width ) } public var description: String { return "" } } ================================================ FILE: Source/Color.swift ================================================ // // Color.swift // SwiftyDrawExample // // Created by Linus Geffarth on 17.04.19. // Copyright © 2019 Walzy. All rights reserved. // import UIKit public struct Color : Codable { private var red: CGFloat = 0.0 private var green: CGFloat = 0.0 private var blue: CGFloat = 0.0 private var alpha: CGFloat = 0.0 public var uiColor: UIColor { UIColor(red: red, green: green, blue: blue, alpha: alpha) } public init(_ uiColor: UIColor) { uiColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha) } } public enum BlendMode: String, Codable { case normal = "normal" case clear = "clear" var cgBlendMode: CGBlendMode { switch self { case .normal: return .normal case .clear: return .clear } } } ================================================ FILE: Source/SwiftyDraw.swift ================================================ /*Copyright (c) 2016, Andrew Walz. Redistribution and use in source and binary forms, with or without modification,are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ import UIKit // MARK: - Public Protocol Declarations /// SwiftyDrawView Delegate @objc public protocol SwiftyDrawViewDelegate: AnyObject { /** SwiftyDrawViewDelegate called when a touch gesture should begin on the SwiftyDrawView using given touch type - Parameter view: SwiftyDrawView where touches occured. - Parameter touchType: Type of touch occuring. */ func swiftyDraw(shouldBeginDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) -> Bool /** SwiftyDrawViewDelegate called when a touch gesture begins on the SwiftyDrawView. - Parameter view: SwiftyDrawView where touches occured. */ func swiftyDraw(didBeginDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) /** SwiftyDrawViewDelegate called when touch gestures continue on the SwiftyDrawView. - Parameter view: SwiftyDrawView where touches occured. */ func swiftyDraw(isDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) /** SwiftyDrawViewDelegate called when touches gestures finish on the SwiftyDrawView. - Parameter view: SwiftyDrawView where touches occured. */ func swiftyDraw(didFinishDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) /** SwiftyDrawViewDelegate called when there is an issue registering touch gestures on the SwiftyDrawView. - Parameter view: SwiftyDrawView where touches occured. */ func swiftyDraw(didCancelDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) } /// UIView Subclass where touch gestures are translated into Core Graphics drawing open class SwiftyDrawView: UIView { /// Current brush being used for drawing public var brush: Brush = .default { didSet { previousBrush = oldValue } } /// Determines whether touch gestures should be registered as drawing strokes on the current canvas public var isEnabled = true /// Determines how touch gestures are treated /// draw - freehand draw /// line - draws straight lines **WARNING:** experimental feature, may not work properly. public enum DrawMode { case draw, line, ellipse, rect } public var drawMode:DrawMode = .draw /// Determines whether paths being draw would be filled or stroked. public var shouldFillPath = false /// Determines whether responde to Apple Pencil interactions, like the Double tap for Apple Pencil 2 to switch tools. public var isPencilInteractive : Bool = true { didSet { if #available(iOS 12.1, *) { pencilInteraction.isEnabled = isPencilInteractive } } } /// Public SwiftyDrawView delegate @IBOutlet public weak var delegate: SwiftyDrawViewDelegate? @available(iOS 9.1, *) public enum TouchType: Equatable, CaseIterable { case finger, pencil var uiTouchTypes: [UITouch.TouchType] { switch self { case .finger: return [.direct, .indirect] case .pencil: return [.pencil, .stylus ] } } } /// Determines which touch types are allowed to draw; default: `[.finger, .pencil]` (all) @available(iOS 9.1, *) public lazy var allowedTouchTypes: [TouchType] = [.finger, .pencil] public var drawItems: [DrawItem] = [] public var drawingHistory: [DrawItem] = [] public var firstPoint: CGPoint = .zero // created this variable public var currentPoint: CGPoint = .zero // made public private var previousPoint: CGPoint = .zero private var previousPreviousPoint: CGPoint = .zero // For pencil interactions @available(iOS 12.1, *) lazy private var pencilInteraction = UIPencilInteraction() /// Save the previous brush for Apple Pencil interaction Switch to previous tool private var previousBrush: Brush = .default public enum ShapeType { case rectangle, roundedRectangle, ellipse } public struct DrawItem { public var path: CGMutablePath public var brush: Brush public var isFillPath: Bool public init(path: CGMutablePath, brush: Brush, isFillPath: Bool) { self.path = path self.brush = brush self.isFillPath = isFillPath } } /// Public init(frame:) implementation override public init(frame: CGRect) { super.init(frame: frame) self.backgroundColor = .clear // receive pencil interaction if supported if #available(iOS 12.1, *) { pencilInteraction.delegate = self self.addInteraction(pencilInteraction) } } /// Public init(coder:) implementation required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self.backgroundColor = .clear //Receive pencil interaction if supported if #available(iOS 12.1, *) { pencilInteraction.delegate = self self.addInteraction(pencilInteraction) } } /// Overriding draw(rect:) to stroke paths override open func draw(_ rect: CGRect) { guard let context: CGContext = UIGraphicsGetCurrentContext() else { return } for item in drawItems { context.setLineCap(.round) context.setLineJoin(.round) context.setLineWidth(item.brush.width) context.setBlendMode(item.brush.blendMode.cgBlendMode) context.setAlpha(item.brush.opacity) if (item.isFillPath) { context.setFillColor(item.brush.color.uiColor.cgColor) context.addPath(item.path) context.fillPath() } else { context.setStrokeColor(item.brush.color.uiColor.cgColor) context.addPath(item.path) context.strokePath() } } } /// touchesBegan implementation to capture strokes override open func touchesBegan(_ touches: Set, with event: UIEvent?) { guard isEnabled, let touch = touches.first else { return } if #available(iOS 9.1, *) { guard allowedTouchTypes.flatMap({ $0.uiTouchTypes }).contains(touch.type) else { return } } guard delegate?.swiftyDraw(shouldBeginDrawingIn: self, using: touch) ?? true else { return } delegate?.swiftyDraw(didBeginDrawingIn: self, using: touch) setTouchPoints(touch, view: self) firstPoint = touch.location(in: self) let newLine = DrawItem(path: CGMutablePath(), brush: Brush(color: brush.color.uiColor, width: brush.width, opacity: brush.opacity, blendMode: brush.blendMode), isFillPath: drawMode != .draw && drawMode != .line ? shouldFillPath : false) addLine(newLine) } /// touchesMoves implementation to capture strokes override open func touchesMoved(_ touches: Set, with event: UIEvent?) { guard isEnabled, let touch = touches.first else { return } if #available(iOS 9.1, *) { guard allowedTouchTypes.flatMap({ $0.uiTouchTypes }).contains(touch.type) else { return } } delegate?.swiftyDraw(isDrawingIn: self, using: touch) updateTouchPoints(for: touch, in: self) switch (drawMode) { case .line: drawItems.removeLast() setNeedsDisplay() let newLine = DrawItem(path: CGMutablePath(), brush: Brush(color: brush.color.uiColor, width: brush.width, opacity: brush.opacity, blendMode: brush.blendMode), isFillPath: false) newLine.path.addPath(createNewStraightPath()) addLine(newLine) break case .draw: let newPath = createNewPath() if let currentPath = drawItems.last { currentPath.path.addPath(newPath) } break case .ellipse: drawItems.removeLast() setNeedsDisplay() let newLine = DrawItem(path: CGMutablePath(), brush: Brush(color: brush.color.uiColor, width: brush.width, opacity: brush.opacity, blendMode: brush.blendMode), isFillPath: shouldFillPath) newLine.path.addPath(createNewShape(type: .ellipse)) addLine(newLine) break case .rect: drawItems.removeLast() setNeedsDisplay() let newLine = DrawItem(path: CGMutablePath(), brush: Brush(color: brush.color.uiColor, width: brush.width, opacity: brush.opacity, blendMode: brush.blendMode), isFillPath: shouldFillPath) newLine.path.addPath(createNewShape(type: .rectangle)) addLine(newLine) break } } func addLine(_ newLine: DrawItem) { drawItems.append(newLine) drawingHistory = drawItems // adding a new item should also update history } /// touchedEnded implementation to capture strokes override open func touchesEnded(_ touches: Set, with event: UIEvent?) { guard isEnabled, let touch = touches.first else { return } delegate?.swiftyDraw(didFinishDrawingIn: self, using: touch) } /// touchedCancelled implementation override open func touchesCancelled(_ touches: Set, with event: UIEvent?) { guard isEnabled, let touch = touches.first else { return } delegate?.swiftyDraw(didCancelDrawingIn: self, using: touch) } /// Displays paths passed by replacing all other contents with provided paths public func display(drawItems: [DrawItem]) { self.drawItems = drawItems drawingHistory = drawItems setNeedsDisplay() } /// Determines whether a last change can be undone public var canUndo: Bool { return drawItems.count > 0 } /// Determines whether an undone change can be redone public var canRedo: Bool { return drawingHistory.count > drawItems.count } /// Undo the last change public func undo() { guard canUndo else { return } drawItems.removeLast() setNeedsDisplay() } /// Redo the last change public func redo() { guard canRedo, let line = drawingHistory[safe: drawItems.count] else { return } drawItems.append(line) setNeedsDisplay() } /// Clear all stroked lines on canvas public func clear() { drawItems = [] setNeedsDisplay() } /********************************** Private Functions **********************************/ private func setTouchPoints(_ touch: UITouch,view: UIView) { previousPoint = touch.previousLocation(in: view) previousPreviousPoint = touch.previousLocation(in: view) currentPoint = touch.location(in: view) } private func updateTouchPoints(for touch: UITouch,in view: UIView) { previousPreviousPoint = previousPoint previousPoint = touch.previousLocation(in: view) currentPoint = touch.location(in: view) } private func createNewPath() -> CGMutablePath { let midPoints = getMidPoints() let subPath = createSubPath(midPoints.0, mid2: midPoints.1) let newPath = addSubPathToPath(subPath) return newPath } private func createNewStraightPath() -> CGMutablePath { let pt1 : CGPoint = firstPoint let pt2 : CGPoint = currentPoint let subPath = createStraightSubPath(pt1, mid2: pt2) let newPath = addSubPathToPath(subPath) return newPath } private func createNewShape(type :ShapeType, corner:CGPoint = CGPoint(x: 1.0, y: 1.0)) -> CGMutablePath { let pt1 : CGPoint = firstPoint let pt2 : CGPoint = currentPoint let width = abs(pt1.x - pt2.x) let height = abs(pt1.y - pt2.y) let newPath = CGMutablePath() if width > 0, height > 0 { let bounds = CGRect(x: min(pt1.x, pt2.x), y: min(pt1.y, pt2.y), width: width, height: height) switch (type) { case .ellipse: newPath.addEllipse(in: bounds) break case .rectangle: newPath.addRect(bounds) break case .roundedRectangle: newPath.addRoundedRect(in: bounds, cornerWidth: corner.x, cornerHeight: corner.y) } } return addSubPathToPath(newPath) } private func calculateMidPoint(_ p1 : CGPoint, p2 : CGPoint) -> CGPoint { return CGPoint(x: (p1.x + p2.x) * 0.5, y: (p1.y + p2.y) * 0.5); } private func getMidPoints() -> (CGPoint, CGPoint) { let mid1 : CGPoint = calculateMidPoint(previousPoint, p2: previousPreviousPoint) let mid2 : CGPoint = calculateMidPoint(currentPoint, p2: previousPoint) return (mid1, mid2) } private func createSubPath(_ mid1: CGPoint, mid2: CGPoint) -> CGMutablePath { let subpath : CGMutablePath = CGMutablePath() subpath.move(to: CGPoint(x: mid1.x, y: mid1.y)) subpath.addQuadCurve(to: CGPoint(x: mid2.x, y: mid2.y), control: CGPoint(x: previousPoint.x, y: previousPoint.y)) return subpath } private func createStraightSubPath(_ mid1: CGPoint, mid2: CGPoint) -> CGMutablePath { let subpath : CGMutablePath = CGMutablePath() subpath.move(to: mid1) subpath.addLine(to: mid2) return subpath } private func addSubPathToPath(_ subpath: CGMutablePath) -> CGMutablePath { let bounds : CGRect = subpath.boundingBox let drawBox : CGRect = bounds.insetBy(dx: -2.0 * brush.width, dy: -2.0 * brush.width) self.setNeedsDisplay(drawBox) return subpath } } // MARK: - Extensions extension Collection { /// Returns the element at the specified index if it is within bounds, otherwise nil. subscript (safe index: Index) -> Element? { return indices.contains(index) ? self[index] : nil } } @available(iOS 12.1, *) extension SwiftyDrawView : UIPencilInteractionDelegate{ public func pencilInteractionDidTap(_ interaction: UIPencilInteraction) { let preference = UIPencilInteraction.preferredTapAction if preference == .switchEraser { let currentBlend = self.brush.blendMode if currentBlend != .clear { self.brush.blendMode = .clear } else { self.brush.blendMode = .normal } } else if preference == .switchPrevious { self.brush = self.previousBrush } } } extension SwiftyDrawView.DrawItem: Codable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) let pathData = try container.decode(Data.self, forKey: .path) let uiBezierPath = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(pathData) as! UIBezierPath path = uiBezierPath.cgPath as! CGMutablePath brush = try container.decode(Brush.self, forKey: .brush) isFillPath = try container.decode(Bool.self, forKey: .isFillPath) } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) let uiBezierPath = UIBezierPath(cgPath: path) var pathData: Data? if #available(iOS 11.0, *) { pathData = try NSKeyedArchiver.archivedData(withRootObject: uiBezierPath, requiringSecureCoding: false) } else { pathData = NSKeyedArchiver.archivedData(withRootObject: uiBezierPath) } try container.encode(pathData!, forKey: .path) try container.encode(brush, forKey: .brush) try container.encode(isFillPath, forKey: .isFillPath) } enum CodingKeys: String, CodingKey { case brush case path case isFillPath } } ================================================ FILE: SwiftyDraw/Info.plist ================================================ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleVersion $(CURRENT_PROJECT_VERSION) ================================================ FILE: SwiftyDraw/SwiftyDraw.h ================================================ // // SwiftyDraw.h // SwiftyDraw // // Created by Shunzhe Ma on 2/6/19. // #import //! Project version number for SwiftyDraw. FOUNDATION_EXPORT double SwiftyDrawVersionNumber; //! Project version string for SwiftyDraw. FOUNDATION_EXPORT const unsigned char SwiftyDrawVersionString[]; // In this header, you should import all the public headers of your framework using statements like #import ================================================ FILE: SwiftyDraw.podspec ================================================ Pod::Spec.new do |s| s.name = 'SwiftyDraw' s.version = '2.4.1' s.summary = 'A simple, core graphics drawing framework written in Swift' s.description = <<-DESC SwiftyDraw is a simple drawing framework written in Swift. SwiftyDraw is built using Core Gaphics and is very easy to implement DESC s.homepage = 'https://github.com/Awalz/SwiftyDraw' s.license = { :type => 'MIT', :file => 'LICENSE' } s.author = { 'Linus Geffarth' => 'hello@ogli.codes' } s.source = { :git => 'https://github.com/Awalz/SwiftyDraw.git', :tag => s.version } s.social_media_url = '' s.ios.deployment_target = '9.0' s.swift_version = '5.0' s.source_files = 'Source/**/*' s.frameworks = 'UIKit' end ================================================ FILE: SwiftyDraw.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 50; objects = { /* Begin PBXBuildFile section */ 6297C0F6240FBBE3008DBC24 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6297C0F5240FBBE3008DBC24 /* Color.swift */; }; DA81B079220BEA1B008184FF /* SwiftyDraw.h in Headers */ = {isa = PBXBuildFile; fileRef = DA81B077220BEA1B008184FF /* SwiftyDraw.h */; settings = {ATTRIBUTES = (Public, ); }; }; DA81B07D220BEA28008184FF /* SwiftyDraw.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA81B06D220BE9C8008184FF /* SwiftyDraw.swift */; }; DA81B07E220BEA28008184FF /* Brush.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA81B06E220BE9C8008184FF /* Brush.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 6297C0F5240FBBE3008DBC24 /* Color.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = ""; }; DA81B06D220BE9C8008184FF /* SwiftyDraw.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftyDraw.swift; sourceTree = ""; }; DA81B06E220BE9C8008184FF /* Brush.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Brush.swift; sourceTree = ""; }; DA81B074220BEA1B008184FF /* SwiftyDraw.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftyDraw.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DA81B077220BEA1B008184FF /* SwiftyDraw.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SwiftyDraw.h; sourceTree = ""; }; DA81B078220BEA1B008184FF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ DA81B071220BEA1B008184FF /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ DA81B062220BE9A6008184FF = { isa = PBXGroup; children = ( DA81B06C220BE9C8008184FF /* Source */, DA81B076220BEA1B008184FF /* SwiftyDraw */, DA81B075220BEA1B008184FF /* Products */, ); sourceTree = ""; }; DA81B06C220BE9C8008184FF /* Source */ = { isa = PBXGroup; children = ( DA81B06D220BE9C8008184FF /* SwiftyDraw.swift */, DA81B06E220BE9C8008184FF /* Brush.swift */, 6297C0F5240FBBE3008DBC24 /* Color.swift */, ); path = Source; sourceTree = ""; }; DA81B075220BEA1B008184FF /* Products */ = { isa = PBXGroup; children = ( DA81B074220BEA1B008184FF /* SwiftyDraw.framework */, ); name = Products; sourceTree = ""; }; DA81B076220BEA1B008184FF /* SwiftyDraw */ = { isa = PBXGroup; children = ( DA81B077220BEA1B008184FF /* SwiftyDraw.h */, DA81B078220BEA1B008184FF /* Info.plist */, ); path = SwiftyDraw; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ DA81B06F220BEA1B008184FF /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( DA81B079220BEA1B008184FF /* SwiftyDraw.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ DA81B073220BEA1B008184FF /* SwiftyDraw */ = { isa = PBXNativeTarget; buildConfigurationList = DA81B07A220BEA1B008184FF /* Build configuration list for PBXNativeTarget "SwiftyDraw" */; buildPhases = ( DA81B06F220BEA1B008184FF /* Headers */, DA81B070220BEA1B008184FF /* Sources */, DA81B071220BEA1B008184FF /* Frameworks */, DA81B072220BEA1B008184FF /* Resources */, ); buildRules = ( ); dependencies = ( ); name = SwiftyDraw; productName = SwiftyDraw; productReference = DA81B074220BEA1B008184FF /* SwiftyDraw.framework */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ DA81B063220BE9A6008184FF /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 1130; TargetAttributes = { DA81B073220BEA1B008184FF = { CreatedOnToolsVersion = 10.1; LastSwiftMigration = 1130; }; }; }; buildConfigurationList = DA81B066220BE9A6008184FF /* Build configuration list for PBXProject "SwiftyDraw" */; compatibilityVersion = "Xcode 9.3"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, ); mainGroup = DA81B062220BE9A6008184FF; productRefGroup = DA81B075220BEA1B008184FF /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( DA81B073220BEA1B008184FF /* SwiftyDraw */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ DA81B072220BEA1B008184FF /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ DA81B070220BEA1B008184FF /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( DA81B07D220BEA28008184FF /* SwiftyDraw.swift in Sources */, DA81B07E220BEA28008184FF /* Brush.swift in Sources */, 6297C0F6240FBBE3008DBC24 /* Color.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ DA81B067220BE9A6008184FF /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { 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_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_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; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; ONLY_ACTIVE_ARCH = YES; }; name = Debug; }; DA81B068220BE9A6008184FF /* Release */ = { isa = XCBuildConfiguration; buildSettings = { 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_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_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; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; }; name = Release; }; DA81B07B220BEA1B008184FF /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; 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_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; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; 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 = ( "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; INFOPLIST_FILE = SwiftyDraw/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.SwiftyDraw; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; DA81B07C220BEA1B008184FF /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; 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_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; CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; 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; INFOPLIST_FILE = SwiftyDraw/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 12.1; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.SwiftyDraw; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ DA81B066220BE9A6008184FF /* Build configuration list for PBXProject "SwiftyDraw" */ = { isa = XCConfigurationList; buildConfigurations = ( DA81B067220BE9A6008184FF /* Debug */, DA81B068220BE9A6008184FF /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; DA81B07A220BEA1B008184FF /* Build configuration list for PBXNativeTarget "SwiftyDraw" */ = { isa = XCConfigurationList; buildConfigurations = ( DA81B07B220BEA1B008184FF /* Debug */, DA81B07C220BEA1B008184FF /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = DA81B063220BE9A6008184FF /* Project object */; } ================================================ FILE: SwiftyDraw.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: SwiftyDraw.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: SwiftyDraw.xcodeproj/xcshareddata/xcschemes/SwiftyDraw.xcscheme ================================================ ================================================ FILE: SwiftyDraw.xcodeproj/xcuserdata/shunzhema.xcuserdatad/xcschemes/xcschememanagement.plist ================================================ SchemeUserState SwiftyDraw.xcscheme_^#shared#^_ orderHint 0 SuppressBuildableAutocreation DA81B073220BEA1B008184FF primary ================================================ FILE: SwiftyDrawExample/.gitignore ================================================ # OS X .DS_Store # Xcode build/ *.pbxuser !default.pbxuser *.mode1v3 !default.mode1v3 *.mode2v3 !default.mode2v3 *.perspectivev3 !default.perspectivev3 xcuserdata/ *.xccheckout profile *.moved-aside DerivedData *.hmap *.ipa # Bundler .bundle # Add this line if you want to avoid checking in source code from Carthage dependencies. # Carthage/Checkouts Carthage/Build # 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 # # Note: if you ignore the Pods directory, make sure to uncomment # `pod install` in .travis.yml # # Pods/ ================================================ FILE: SwiftyDrawExample/SwiftyDrawExample/AppDelegate.swift ================================================ import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { return true } func applicationWillResignActive(_ application: UIApplication) { } func applicationDidEnterBackground(_ application: UIApplication) { } func applicationWillEnterForeground(_ application: UIApplication) { } func applicationDidBecomeActive(_ application: UIApplication) { } func applicationWillTerminate(_ application: UIApplication) { } } ================================================ FILE: SwiftyDrawExample/SwiftyDrawExample/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "iphone", "size" : "20x20", "scale" : "2x" }, { "idiom" : "iphone", "size" : "20x20", "scale" : "3x" }, { "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" : "60x60", "scale" : "2x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "3x" }, { "idiom" : "ios-marketing", "size" : "1024x1024", "scale" : "1x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: SwiftyDrawExample/SwiftyDrawExample/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: SwiftyDrawExample/SwiftyDrawExample/Base.lproj/Main.storyboard ================================================ ================================================ FILE: SwiftyDrawExample/SwiftyDrawExample/Extensions.swift ================================================ // // Extensions.swift // SwiftyDrawExample // // Created by Linus Geffarth on 22.02.19. // Copyright © 2019 Walzy. All rights reserved. // import UIKit @IBDesignable extension UIView { @IBInspectable var cornerRadius: CGFloat { set { layer.cornerRadius = newValue } get { return layer.cornerRadius } } @IBInspectable var borderColor: UIColor { set { layer.borderColor = newValue.cgColor } get { return UIColor(cgColor: layer.borderColor!) } } @IBInspectable var borderWidth: CGFloat { set { layer.borderWidth = newValue } get { return layer.borderWidth } } } extension CGMutablePath { func adding(path: CGPath) -> CGMutablePath { addPath(path) return self } } ================================================ FILE: SwiftyDrawExample/SwiftyDrawExample/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleVersion 1 LSRequiresIPhoneOS UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities armv7 UIRequiresFullScreen UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight ================================================ FILE: SwiftyDrawExample/SwiftyDrawExample/SwiftyDrawExample.entitlements ================================================ com.apple.security.app-sandbox com.apple.security.network.client ================================================ FILE: SwiftyDrawExample/SwiftyDrawExample/ViewController.swift ================================================ import UIKit extension ViewController: SwiftyDrawViewDelegate { func swiftyDraw(shouldBeginDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) -> Bool { return true } func swiftyDraw(didBeginDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) { updateHistoryButtons() } func swiftyDraw(isDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) { } func swiftyDraw(didFinishDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) { } func swiftyDraw(didCancelDrawingIn drawingView: SwiftyDrawView, using touch: UITouch) { } } class ViewController: UIViewController { @IBOutlet weak var drawView: SwiftyDrawView! @IBOutlet weak var eraserButton: UIButton! @IBOutlet weak var fillModeButton: UIButton! @IBOutlet weak var drawModeSelector: UISegmentedControl! @IBOutlet weak var undoButton: UIButton! @IBOutlet weak var redoButton: UIButton! override func viewDidLoad() { super.viewDidLoad() updateHistoryButtons() drawView.delegate = self drawView.brush.width = 7 if #available(iOS 9.1, *) { drawView.allowedTouchTypes = [.finger, .pencil] } } @IBAction func selectedColor(_ button: UIButton) { guard let color = button.backgroundColor else { return } drawView.brush.color = Color(color) deactivateEraser() } @IBAction func undo() { drawView.undo() updateHistoryButtons() } @IBAction func redo() { drawView.redo() updateHistoryButtons() } func updateHistoryButtons() { undoButton.isEnabled = drawView.canUndo redoButton.isEnabled = drawView.canRedo } @IBAction func toggleEraser() { if drawView.brush.blendMode == .normal { //Switch to clear activateEraser() } else { //Switch to normal deactivateEraser() } } @IBAction func clearCanvas() { drawView.clear() deactivateEraser() } @IBAction func setDrawMode() { switch (drawModeSelector.selectedSegmentIndex) { case 1: drawView.drawMode = .line fillModeButton.isHidden = true break case 2: drawView.drawMode = .ellipse fillModeButton.isHidden = false break case 3: drawView.drawMode = .rect fillModeButton.isHidden = false break default: drawView.drawMode = .draw fillModeButton.isHidden = true break } } @IBAction func toggleStraightLine() { drawView.shouldFillPath = !drawView.shouldFillPath if (drawView.shouldFillPath) { fillModeButton.tintColor = .red fillModeButton.setTitle("activate stroke mode", for: .normal) } else { fillModeButton.tintColor = self.view.tintColor fillModeButton.setTitle("activate fill mode", for: .normal) } } @IBAction func changedWidth(_ slider: UISlider) { drawView.brush.width = CGFloat(slider.value) } @IBAction func changedOpacity(_ slider: UISlider) { drawView.brush.opacity = CGFloat(slider.value) deactivateEraser() } func activateEraser() { drawView.brush.blendMode = .clear eraserButton.tintColor = .red eraserButton.setTitle("deactivate eraser", for: .normal) } func deactivateEraser() { drawView.brush.blendMode = .normal eraserButton.tintColor = self.view.tintColor eraserButton.setTitle("activate eraser", for: .normal) } } ================================================ FILE: SwiftyDrawExample/SwiftyDrawExample.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 1671B1561DE8CBA100ED5239 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1671B1551DE8CBA100ED5239 /* AppDelegate.swift */; }; 1671B1581DE8CBA100ED5239 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1671B1571DE8CBA100ED5239 /* ViewController.swift */; }; 1671B15B1DE8CBA100ED5239 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1671B1591DE8CBA100ED5239 /* Main.storyboard */; }; 1671B15D1DE8CBA100ED5239 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1671B15C1DE8CBA100ED5239 /* Assets.xcassets */; }; 1671B1601DE8CBA100ED5239 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1671B15E1DE8CBA100ED5239 /* LaunchScreen.storyboard */; }; 882DC28322202B8A00B03866 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 882DC28222202B8A00B03866 /* Extensions.swift */; }; 88AF845922677ABC0070277F /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88AF845822677ABC0070277F /* Color.swift */; }; 94CEF9EF2168F8350036EF15 /* SwiftyDraw.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94CEF9ED2168F8350036EF15 /* SwiftyDraw.swift */; }; 94CEF9F02168F8350036EF15 /* Brush.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94CEF9EE2168F8350036EF15 /* Brush.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 1671B1521DE8CBA100ED5239 /* SwiftyDrawExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftyDrawExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1671B1551DE8CBA100ED5239 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 1671B1571DE8CBA100ED5239 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 1671B15A1DE8CBA100ED5239 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 1671B15C1DE8CBA100ED5239 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 1671B15F1DE8CBA100ED5239 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 1671B1611DE8CBA100ED5239 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 882DC28222202B8A00B03866 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 88AF845822677ABC0070277F /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = ""; }; 94CEF9ED2168F8350036EF15 /* SwiftyDraw.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftyDraw.swift; sourceTree = ""; }; 94CEF9EE2168F8350036EF15 /* Brush.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Brush.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 1671B14F1DE8CBA100ED5239 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 1671B1491DE8CBA100ED5239 = { isa = PBXGroup; children = ( 1671B1541DE8CBA100ED5239 /* SwiftyDrawExample */, 94CEF9EC2168F8350036EF15 /* Source */, 1671B1531DE8CBA100ED5239 /* Products */, ); sourceTree = ""; }; 1671B1531DE8CBA100ED5239 /* Products */ = { isa = PBXGroup; children = ( 1671B1521DE8CBA100ED5239 /* SwiftyDrawExample.app */, ); name = Products; sourceTree = ""; }; 1671B1541DE8CBA100ED5239 /* SwiftyDrawExample */ = { isa = PBXGroup; children = ( 1671B1551DE8CBA100ED5239 /* AppDelegate.swift */, 1671B1571DE8CBA100ED5239 /* ViewController.swift */, 882DC28222202B8A00B03866 /* Extensions.swift */, 1671B1591DE8CBA100ED5239 /* Main.storyboard */, 1671B15C1DE8CBA100ED5239 /* Assets.xcassets */, 1671B15E1DE8CBA100ED5239 /* LaunchScreen.storyboard */, 1671B1611DE8CBA100ED5239 /* Info.plist */, ); path = SwiftyDrawExample; sourceTree = ""; }; 94CEF9EC2168F8350036EF15 /* Source */ = { isa = PBXGroup; children = ( 94CEF9ED2168F8350036EF15 /* SwiftyDraw.swift */, 88AF845822677ABC0070277F /* Color.swift */, 94CEF9EE2168F8350036EF15 /* Brush.swift */, ); name = Source; path = ../Source; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 1671B1511DE8CBA100ED5239 /* SwiftyDrawExample */ = { isa = PBXNativeTarget; buildConfigurationList = 1671B1641DE8CBA100ED5239 /* Build configuration list for PBXNativeTarget "SwiftyDrawExample" */; buildPhases = ( 1671B14E1DE8CBA100ED5239 /* Sources */, 1671B14F1DE8CBA100ED5239 /* Frameworks */, 1671B1501DE8CBA100ED5239 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = SwiftyDrawExample; productName = SwiftyDrawExample; productReference = 1671B1521DE8CBA100ED5239 /* SwiftyDrawExample.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 1671B14A1DE8CBA100ED5239 /* Project object */ = { isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0810; LastUpgradeCheck = 1020; ORGANIZATIONNAME = Walzy; TargetAttributes = { 1671B1511DE8CBA100ED5239 = { CreatedOnToolsVersion = 8.1; DevelopmentTeam = 578YR5HPG3; LastSwiftMigration = 1020; ProvisioningStyle = Automatic; }; }; }; buildConfigurationList = 1671B14D1DE8CBA100ED5239 /* Build configuration list for PBXProject "SwiftyDrawExample" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 1671B1491DE8CBA100ED5239; productRefGroup = 1671B1531DE8CBA100ED5239 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 1671B1511DE8CBA100ED5239 /* SwiftyDrawExample */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 1671B1501DE8CBA100ED5239 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 1671B1601DE8CBA100ED5239 /* LaunchScreen.storyboard in Resources */, 1671B15D1DE8CBA100ED5239 /* Assets.xcassets in Resources */, 1671B15B1DE8CBA100ED5239 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 1671B14E1DE8CBA100ED5239 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 94CEF9F02168F8350036EF15 /* Brush.swift in Sources */, 882DC28322202B8A00B03866 /* Extensions.swift in Sources */, 94CEF9EF2168F8350036EF15 /* SwiftyDraw.swift in Sources */, 1671B1581DE8CBA100ED5239 /* ViewController.swift in Sources */, 1671B1561DE8CBA100ED5239 /* AppDelegate.swift in Sources */, 88AF845922677ABC0070277F /* Color.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 1671B1591DE8CBA100ED5239 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( 1671B15A1DE8CBA100ED5239 /* Base */, ); name = Main.storyboard; sourceTree = ""; }; 1671B15E1DE8CBA100ED5239 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( 1671B15F1DE8CBA100ED5239 /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 1671B1621DE8CBA100ED5239 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; 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_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_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; 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 = 10.1; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; 1671B1631DE8CBA100ED5239 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; 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_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_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; 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 = 10.1; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; VALIDATE_PRODUCT = YES; }; name = Release; }; 1671B1651DE8CBA100ED5239 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = 578YR5HPG3; INFOPLIST_FILE = SwiftyDrawExample/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.linus-geffarth.SwiftyDrawExample"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; 1671B1661DE8CBA100ED5239 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = 578YR5HPG3; INFOPLIST_FILE = SwiftyDrawExample/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.linus-geffarth.SwiftyDrawExample"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1671B14D1DE8CBA100ED5239 /* Build configuration list for PBXProject "SwiftyDrawExample" */ = { isa = XCConfigurationList; buildConfigurations = ( 1671B1621DE8CBA100ED5239 /* Debug */, 1671B1631DE8CBA100ED5239 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 1671B1641DE8CBA100ED5239 /* Build configuration list for PBXNativeTarget "SwiftyDrawExample" */ = { isa = XCConfigurationList; buildConfigurations = ( 1671B1651DE8CBA100ED5239 /* Debug */, 1671B1661DE8CBA100ED5239 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 1671B14A1DE8CBA100ED5239 /* Project object */; } ================================================ FILE: SwiftyDrawExample/SwiftyDrawExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: SwiftyDrawExample/SwiftyDrawExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: SwiftyDrawExample/SwiftyDrawExample.xcodeproj/xcshareddata/xcschemes/SwiftyDrawExample.xcscheme ================================================