├── example.png
├── ScratchCardImageView.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── ScratchCardImageView
├── AppDelegate.swift
├── UIImage+SolidColor.swift
├── ViewController.swift
├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── ViewController0.swift
├── Info.plist
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── ScratchCardImageView.swift
└── ScratchCardTouchContainer.swift
├── LICENSE
├── README.md
└── .gitignore
/example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paleksandrs/ScratchCardImageView/HEAD/example.png
--------------------------------------------------------------------------------
/ScratchCardImageView.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ScratchCardImageView/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // ScratchCardImageView
4 | //
5 | // Created by Aleksandrs Proskurins on 09/12/2016.
6 | // Copyright © 2016 Aleksandrs Proskurins. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
17 | return true
18 | }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/ScratchCardImageView/UIImage+SolidColor.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+SolidColor.swift
3 | // ScratchCardImageView
4 | //
5 | // Created by Aleksandrs Proskurins on 09/12/2016.
6 | // Copyright © 2016 Aleksandrs Proskurins. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public extension UIImage {
12 | public convenience init?(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
13 | let rect = CGRect(origin: .zero, size: size)
14 | UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
15 | color.setFill()
16 | UIRectFill(rect)
17 | let image = UIGraphicsGetImageFromCurrentImageContext()
18 | UIGraphicsEndImageContext()
19 |
20 | guard let cgImage = image?.cgImage else { return nil }
21 | self.init(cgImage: cgImage)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ScratchCardImageView/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // ScratchCardImageView
4 | //
5 | // Created by Aleksandrs Proskurins on 09/12/2016.
6 | // Copyright © 2016 Aleksandrs Proskurins. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController, ScratchCardImageViewDelegate {
12 |
13 | @IBOutlet weak var scratchCard: ScratchCardImageView!
14 |
15 | override func viewDidLoad() {
16 | super.viewDidLoad()
17 |
18 | scratchCard.image = UIImage(color: UIColor.gray, size: scratchCard.frame.size)
19 | scratchCard.lineType = .square
20 | scratchCard.lineWidth = 20
21 | scratchCard.delegate = self
22 | }
23 |
24 | func scratchCardImageViewDidEraseProgress(eraseProgress: Float) {
25 |
26 | print(eraseProgress)
27 | }
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/ScratchCardImageView/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | }
43 | ],
44 | "info" : {
45 | "version" : 1,
46 | "author" : "xcode"
47 | }
48 | }
--------------------------------------------------------------------------------
/ScratchCardImageView/ViewController0.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController0.swift
3 | // ScratchCardImageView
4 | //
5 | // Created by Aleksandrs Proskurins on 09/12/2016.
6 | // Copyright © 2016 Aleksandrs Proskurins. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController0: UIViewController, ScratchCardTouchContainerDelegate {
12 |
13 | @IBOutlet weak var scratchCard: UIImageView!
14 | @IBOutlet var scratchCardTouchContainer: ScratchCardTouchContainer!
15 |
16 | override func viewDidLoad() {
17 | super.viewDidLoad()
18 |
19 | scratchCard.image = UIImage(color: UIColor.gray, size: scratchCard.bounds.size)
20 |
21 |
22 | scratchCardTouchContainer.scratchCardImageView = scratchCard
23 | scratchCardTouchContainer.lineType = .square
24 | scratchCardTouchContainer.lineWidth = 20
25 | scratchCardTouchContainer.delegate = self
26 | }
27 |
28 | func scratchCardTouchContainerDidErase(eraseProgress: Float) {
29 |
30 | print(eraseProgress)
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Aleksandrs Proskurins
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Scratchcard effect
2 |
3 | To achieve scratchcard effect you have to options `ScratchCardTouchContainer` or `ScratchCardImageView`
4 | 
5 |
6 | ###ScratchCardTouchContainer
7 |
8 | A simple `UIView` subclass that allows tracking touch events already outside your `UIImageView` that represents your scratchcard. Just simple pass reference to your scratchcard image view.
9 |
10 | Example:
11 |
12 | ````swift
13 | scratchCardTouchContainer.scratchCardImageView = scratchCard
14 | scratchCardTouchContainer.lineType = .square
15 | scratchCardTouchContainer.lineWidth = 20
16 | ````
17 |
18 | ### ScratchCardImageView
19 |
20 | A simple `UIImageView` subclass that allows your `UIImageView` become a scratchcard. Touch events will be tracked only inside the `UIImageView` bounds. In the storyboard or xib set custom class of your `UIImageView` that represents your scratchcard image to `ScratchCardImageView`
21 |
22 |
23 | For both classes you can set delegate to retrieve erase progress from 0 (not erased) to 1 (fully erased).
24 |
25 | ## License
26 |
27 | `ScratchCardImageView` and `ScratchCardTouchContainer` is released under an [MIT License][mitLink]. See `LICENSE` for details.
28 |
29 | [mitLink]:http://opensource.org/licenses/MIT
30 |
--------------------------------------------------------------------------------
/ScratchCardImageView/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xcuserstate
23 |
24 | ## Obj-C/Swift specific
25 | *.hmap
26 | *.ipa
27 | *.dSYM.zip
28 | *.dSYM
29 |
30 | ## Playgrounds
31 | timeline.xctimeline
32 | playground.xcworkspace
33 |
34 | # Swift Package Manager
35 | #
36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
37 | # Packages/
38 | .build/
39 |
40 | # CocoaPods
41 | #
42 | # We recommend against adding the Pods directory to your .gitignore. However
43 | # you should judge for yourself, the pros and cons are mentioned at:
44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
45 | #
46 | # Pods/
47 |
48 | # Carthage
49 | #
50 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
51 | # Carthage/Checkouts
52 |
53 | Carthage/Build
54 |
55 | # fastlane
56 | #
57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
58 | # screenshots whenever they are needed.
59 | # For more information about the recommended setup visit:
60 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
61 |
62 | fastlane/report.xml
63 | fastlane/Preview.html
64 | fastlane/screenshots
65 | fastlane/test_output
66 |
--------------------------------------------------------------------------------
/ScratchCardImageView/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ScratchCardImageView/ScratchCardImageView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScratchCardImageView.swift
3 | // ScratchCardImageView
4 | //
5 | // Created by Aleksandrs Proskurins on 09/12/2016.
6 | // Copyright © 2016 Aleksandrs Proskurins. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | protocol ScratchCardImageViewDelegate: class {
12 |
13 | func scratchCardImageViewDidEraseProgress(eraseProgress: Float)
14 | }
15 |
16 |
17 | class ScratchCardImageView: UIImageView {
18 |
19 | private var lastPoint: CGPoint?
20 |
21 | var lineType: CGLineCap = .square
22 | var lineWidth: CGFloat = 20.0
23 | weak var delegate: ScratchCardImageViewDelegate?
24 |
25 | override func awakeFromNib() {
26 | super.awakeFromNib()
27 |
28 | isUserInteractionEnabled = true
29 | }
30 |
31 | override func touchesBegan(_ touches: Set, with event: UIEvent?) {
32 |
33 | guard let touch = touches.first else {
34 |
35 | return
36 | }
37 |
38 | lastPoint = touch.location(in: self)
39 | }
40 |
41 | override func touchesMoved(_ touches: Set, with event: UIEvent?) {
42 |
43 | guard let touch = touches.first, let point = lastPoint, let img = image else {
44 |
45 | return
46 | }
47 |
48 | let currentLocation = touch.location(in: self)
49 | eraseBetween(fromPoint: point, currentPoint: currentLocation)
50 | lastPoint = currentLocation
51 |
52 | if let _ = delegate {
53 | let progress = alphaOnlyPersentage(img: img)
54 | delegate?.scratchCardImageViewDidEraseProgress(eraseProgress: progress)
55 | }
56 | }
57 |
58 | func eraseBetween(fromPoint: CGPoint, currentPoint: CGPoint) {
59 |
60 | UIGraphicsBeginImageContext(self.frame.size)
61 |
62 | image?.draw(in: self.bounds)
63 |
64 | let path = CGMutablePath()
65 | path.move(to: fromPoint)
66 | path.addLine(to: currentPoint)
67 |
68 | let context = UIGraphicsGetCurrentContext()!
69 | context.setShouldAntialias(true)
70 | context.setLineCap(lineType)
71 | context.setLineWidth(lineWidth)
72 | context.setBlendMode(.clear)
73 | context.addPath(path)
74 | context.strokePath()
75 |
76 | image = UIGraphicsGetImageFromCurrentImageContext()
77 |
78 | UIGraphicsEndImageContext()
79 | }
80 |
81 | private func alphaOnlyPersentage(img: UIImage) -> Float {
82 |
83 | let width = Int(img.size.width)
84 | let height = Int(img.size.height)
85 |
86 | let bitmapBytesPerRow = width
87 | let bitmapByteCount = bitmapBytesPerRow * height
88 |
89 | let pixelData = UnsafeMutablePointer.allocate(capacity: bitmapByteCount)
90 |
91 | let colorSpace = CGColorSpaceCreateDeviceGray()
92 |
93 | let context = CGContext(data: pixelData,
94 | width: width,
95 | height: height,
96 | bitsPerComponent: 8,
97 | bytesPerRow: bitmapBytesPerRow,
98 | space: colorSpace,
99 | bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.alphaOnly.rawValue).rawValue)!
100 |
101 | let rect = CGRect(x: 0, y: 0, width: width, height: height)
102 | context.clear(rect)
103 | context.draw(img.cgImage!, in: rect)
104 |
105 | var alphaOnlyPixels = 0
106 |
107 | for x in 0...Int(width) {
108 | for y in 0...Int(height) {
109 |
110 | if pixelData[y * width + x] == 0 {
111 | alphaOnlyPixels += 1
112 | }
113 | }
114 | }
115 |
116 | free(pixelData)
117 |
118 | return Float(alphaOnlyPixels) / Float(bitmapByteCount)
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/ScratchCardImageView/ScratchCardTouchContainer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScratchCardTouchContainer.swift
3 | // ScratchCardImageView
4 | //
5 | // Created by Aleksandrs Proskurins on 09/12/2016.
6 | // Copyright © 2016 Aleksandrs Proskurins. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 |
12 | protocol ScratchCardTouchContainerDelegate: class {
13 |
14 | func scratchCardTouchContainerDidErase(eraseProgress: Float)
15 | }
16 |
17 | class ScratchCardTouchContainer: UIView {
18 |
19 | private var lastPoint: CGPoint?
20 |
21 | var lineType: CGLineCap = .square
22 | var lineWidth: CGFloat = 20.0
23 | var scratchCardImageView: UIImageView?
24 | weak var delegate: ScratchCardTouchContainerDelegate?
25 |
26 | override func touchesBegan(_ touches: Set, with event: UIEvent?) {
27 |
28 | guard let touch = touches.first, let imageView = scratchCardImageView else {
29 |
30 | return
31 | }
32 |
33 | lastPoint = touch.location(in: imageView)
34 | }
35 |
36 | override func touchesMoved(_ touches: Set, with event: UIEvent?) {
37 |
38 | guard let touch = touches.first, let point = lastPoint, let imageView = scratchCardImageView else {
39 |
40 | return
41 | }
42 |
43 | let currentLocation = touch.location(in: imageView)
44 | eraseBetween(fromPoint: point, currentPoint: currentLocation, imageView: imageView)
45 | lastPoint = currentLocation
46 |
47 | if let img = imageView.image, let _ = delegate {
48 | let progress = alphaOnlyPersentage(img: img)
49 | delegate?.scratchCardTouchContainerDidErase(eraseProgress: progress)
50 | }
51 | }
52 |
53 | func eraseBetween(fromPoint: CGPoint, currentPoint: CGPoint, imageView: UIImageView) {
54 |
55 | UIGraphicsBeginImageContext(imageView.frame.size)
56 |
57 | imageView.image?.draw(in: imageView.bounds)
58 |
59 | let path = CGMutablePath()
60 | path.move(to: fromPoint)
61 | path.addLine(to: currentPoint)
62 |
63 | let context = UIGraphicsGetCurrentContext()!
64 | context.setShouldAntialias(true)
65 | context.setLineCap(lineType)
66 | context.setLineWidth(lineWidth)
67 | context.setBlendMode(.clear)
68 | context.addPath(path)
69 | context.strokePath()
70 |
71 | imageView.image = UIGraphicsGetImageFromCurrentImageContext()
72 |
73 | UIGraphicsEndImageContext()
74 | }
75 |
76 | private func alphaOnlyPersentage(img: UIImage) -> Float {
77 |
78 | let width = Int(img.size.width)
79 | let height = Int(img.size.height)
80 |
81 | let bitmapBytesPerRow = width
82 | let bitmapByteCount = bitmapBytesPerRow * height
83 |
84 | let pixelData = UnsafeMutablePointer.allocate(capacity: bitmapByteCount)
85 |
86 | let colorSpace = CGColorSpaceCreateDeviceGray()
87 |
88 | let context = CGContext(data: pixelData,
89 | width: width,
90 | height: height,
91 | bitsPerComponent: 8,
92 | bytesPerRow: bitmapBytesPerRow,
93 | space: colorSpace,
94 | bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.alphaOnly.rawValue).rawValue)!
95 |
96 | let rect = CGRect(x: 0, y: 0, width: width, height: height)
97 | context.clear(rect)
98 | context.draw(img.cgImage!, in: rect)
99 |
100 | var alphaOnlyPixels = 0
101 |
102 | for x in 0...Int(width) {
103 | for y in 0...Int(height) {
104 |
105 | if pixelData[y * width + x] == 0 {
106 | alphaOnlyPixels += 1
107 | }
108 | }
109 | }
110 |
111 | free(pixelData)
112 |
113 | return Float(alphaOnlyPixels) / Float(bitmapByteCount)
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/ScratchCardImageView/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
97 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
--------------------------------------------------------------------------------
/ScratchCardImageView.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | FA56BC601DFAF9B600294C20 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA56BC5F1DFAF9B600294C20 /* AppDelegate.swift */; };
11 | FA56BC621DFAF9B600294C20 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA56BC611DFAF9B600294C20 /* ViewController.swift */; };
12 | FA56BC651DFAF9B600294C20 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA56BC631DFAF9B600294C20 /* Main.storyboard */; };
13 | FA56BC671DFAF9B600294C20 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA56BC661DFAF9B600294C20 /* Assets.xcassets */; };
14 | FA56BC6A1DFAF9B600294C20 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA56BC681DFAF9B600294C20 /* LaunchScreen.storyboard */; };
15 | FA56BC721DFAFB3D00294C20 /* UIImage+SolidColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA56BC711DFAFB3D00294C20 /* UIImage+SolidColor.swift */; };
16 | FA56BC741DFAFB8F00294C20 /* ScratchCardImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA56BC731DFAFB8F00294C20 /* ScratchCardImageView.swift */; };
17 | FA64C3381DFB260F000B4A30 /* ScratchCardTouchContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA64C3371DFB260F000B4A30 /* ScratchCardTouchContainer.swift */; };
18 | FA64C33B1DFB2735000B4A30 /* ViewController0.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA64C33A1DFB2735000B4A30 /* ViewController0.swift */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXFileReference section */
22 | FA56BC5C1DFAF9B600294C20 /* ScratchCardImageView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ScratchCardImageView.app; sourceTree = BUILT_PRODUCTS_DIR; };
23 | FA56BC5F1DFAF9B600294C20 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
24 | FA56BC611DFAF9B600294C20 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
25 | FA56BC641DFAF9B600294C20 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
26 | FA56BC661DFAF9B600294C20 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
27 | FA56BC691DFAF9B600294C20 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
28 | FA56BC6B1DFAF9B600294C20 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
29 | FA56BC711DFAFB3D00294C20 /* UIImage+SolidColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+SolidColor.swift"; sourceTree = ""; };
30 | FA56BC731DFAFB8F00294C20 /* ScratchCardImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScratchCardImageView.swift; sourceTree = ""; };
31 | FA64C3371DFB260F000B4A30 /* ScratchCardTouchContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScratchCardTouchContainer.swift; sourceTree = ""; };
32 | FA64C33A1DFB2735000B4A30 /* ViewController0.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController0.swift; sourceTree = ""; };
33 | /* End PBXFileReference section */
34 |
35 | /* Begin PBXFrameworksBuildPhase section */
36 | FA56BC591DFAF9B600294C20 /* Frameworks */ = {
37 | isa = PBXFrameworksBuildPhase;
38 | buildActionMask = 2147483647;
39 | files = (
40 | );
41 | runOnlyForDeploymentPostprocessing = 0;
42 | };
43 | /* End PBXFrameworksBuildPhase section */
44 |
45 | /* Begin PBXGroup section */
46 | FA56BC531DFAF9B600294C20 = {
47 | isa = PBXGroup;
48 | children = (
49 | FA56BC5E1DFAF9B600294C20 /* ScratchCardImageView */,
50 | FA56BC5D1DFAF9B600294C20 /* Products */,
51 | );
52 | sourceTree = "";
53 | };
54 | FA56BC5D1DFAF9B600294C20 /* Products */ = {
55 | isa = PBXGroup;
56 | children = (
57 | FA56BC5C1DFAF9B600294C20 /* ScratchCardImageView.app */,
58 | );
59 | name = Products;
60 | sourceTree = "";
61 | };
62 | FA56BC5E1DFAF9B600294C20 /* ScratchCardImageView */ = {
63 | isa = PBXGroup;
64 | children = (
65 | FA64C3391DFB2617000B4A30 /* Helpers */,
66 | FA56BC731DFAFB8F00294C20 /* ScratchCardImageView.swift */,
67 | FA64C3371DFB260F000B4A30 /* ScratchCardTouchContainer.swift */,
68 | FA56BC5F1DFAF9B600294C20 /* AppDelegate.swift */,
69 | FA64C33A1DFB2735000B4A30 /* ViewController0.swift */,
70 | FA56BC611DFAF9B600294C20 /* ViewController.swift */,
71 | FA56BC631DFAF9B600294C20 /* Main.storyboard */,
72 | FA56BC661DFAF9B600294C20 /* Assets.xcassets */,
73 | FA56BC681DFAF9B600294C20 /* LaunchScreen.storyboard */,
74 | FA56BC6B1DFAF9B600294C20 /* Info.plist */,
75 | );
76 | path = ScratchCardImageView;
77 | sourceTree = "";
78 | };
79 | FA64C3391DFB2617000B4A30 /* Helpers */ = {
80 | isa = PBXGroup;
81 | children = (
82 | FA56BC711DFAFB3D00294C20 /* UIImage+SolidColor.swift */,
83 | );
84 | name = Helpers;
85 | sourceTree = "";
86 | };
87 | /* End PBXGroup section */
88 |
89 | /* Begin PBXNativeTarget section */
90 | FA56BC5B1DFAF9B600294C20 /* ScratchCardImageView */ = {
91 | isa = PBXNativeTarget;
92 | buildConfigurationList = FA56BC6E1DFAF9B600294C20 /* Build configuration list for PBXNativeTarget "ScratchCardImageView" */;
93 | buildPhases = (
94 | FA56BC581DFAF9B600294C20 /* Sources */,
95 | FA56BC591DFAF9B600294C20 /* Frameworks */,
96 | FA56BC5A1DFAF9B600294C20 /* Resources */,
97 | );
98 | buildRules = (
99 | );
100 | dependencies = (
101 | );
102 | name = ScratchCardImageView;
103 | productName = ScratchCardImageView;
104 | productReference = FA56BC5C1DFAF9B600294C20 /* ScratchCardImageView.app */;
105 | productType = "com.apple.product-type.application";
106 | };
107 | /* End PBXNativeTarget section */
108 |
109 | /* Begin PBXProject section */
110 | FA56BC541DFAF9B600294C20 /* Project object */ = {
111 | isa = PBXProject;
112 | attributes = {
113 | LastSwiftUpdateCheck = 0810;
114 | LastUpgradeCheck = 0810;
115 | ORGANIZATIONNAME = "Aleksandrs Proskurins";
116 | TargetAttributes = {
117 | FA56BC5B1DFAF9B600294C20 = {
118 | CreatedOnToolsVersion = 8.1;
119 | DevelopmentTeam = 65H57KS853;
120 | ProvisioningStyle = Automatic;
121 | };
122 | };
123 | };
124 | buildConfigurationList = FA56BC571DFAF9B600294C20 /* Build configuration list for PBXProject "ScratchCardImageView" */;
125 | compatibilityVersion = "Xcode 3.2";
126 | developmentRegion = English;
127 | hasScannedForEncodings = 0;
128 | knownRegions = (
129 | en,
130 | Base,
131 | );
132 | mainGroup = FA56BC531DFAF9B600294C20;
133 | productRefGroup = FA56BC5D1DFAF9B600294C20 /* Products */;
134 | projectDirPath = "";
135 | projectRoot = "";
136 | targets = (
137 | FA56BC5B1DFAF9B600294C20 /* ScratchCardImageView */,
138 | );
139 | };
140 | /* End PBXProject section */
141 |
142 | /* Begin PBXResourcesBuildPhase section */
143 | FA56BC5A1DFAF9B600294C20 /* Resources */ = {
144 | isa = PBXResourcesBuildPhase;
145 | buildActionMask = 2147483647;
146 | files = (
147 | FA56BC6A1DFAF9B600294C20 /* LaunchScreen.storyboard in Resources */,
148 | FA56BC671DFAF9B600294C20 /* Assets.xcassets in Resources */,
149 | FA56BC651DFAF9B600294C20 /* Main.storyboard in Resources */,
150 | );
151 | runOnlyForDeploymentPostprocessing = 0;
152 | };
153 | /* End PBXResourcesBuildPhase section */
154 |
155 | /* Begin PBXSourcesBuildPhase section */
156 | FA56BC581DFAF9B600294C20 /* Sources */ = {
157 | isa = PBXSourcesBuildPhase;
158 | buildActionMask = 2147483647;
159 | files = (
160 | FA56BC621DFAF9B600294C20 /* ViewController.swift in Sources */,
161 | FA64C3381DFB260F000B4A30 /* ScratchCardTouchContainer.swift in Sources */,
162 | FA56BC741DFAFB8F00294C20 /* ScratchCardImageView.swift in Sources */,
163 | FA64C33B1DFB2735000B4A30 /* ViewController0.swift in Sources */,
164 | FA56BC601DFAF9B600294C20 /* AppDelegate.swift in Sources */,
165 | FA56BC721DFAFB3D00294C20 /* UIImage+SolidColor.swift in Sources */,
166 | );
167 | runOnlyForDeploymentPostprocessing = 0;
168 | };
169 | /* End PBXSourcesBuildPhase section */
170 |
171 | /* Begin PBXVariantGroup section */
172 | FA56BC631DFAF9B600294C20 /* Main.storyboard */ = {
173 | isa = PBXVariantGroup;
174 | children = (
175 | FA56BC641DFAF9B600294C20 /* Base */,
176 | );
177 | name = Main.storyboard;
178 | sourceTree = "";
179 | };
180 | FA56BC681DFAF9B600294C20 /* LaunchScreen.storyboard */ = {
181 | isa = PBXVariantGroup;
182 | children = (
183 | FA56BC691DFAF9B600294C20 /* Base */,
184 | );
185 | name = LaunchScreen.storyboard;
186 | sourceTree = "";
187 | };
188 | /* End PBXVariantGroup section */
189 |
190 | /* Begin XCBuildConfiguration section */
191 | FA56BC6C1DFAF9B600294C20 /* Debug */ = {
192 | isa = XCBuildConfiguration;
193 | buildSettings = {
194 | ALWAYS_SEARCH_USER_PATHS = NO;
195 | CLANG_ANALYZER_NONNULL = YES;
196 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
197 | CLANG_CXX_LIBRARY = "libc++";
198 | CLANG_ENABLE_MODULES = YES;
199 | CLANG_ENABLE_OBJC_ARC = YES;
200 | CLANG_WARN_BOOL_CONVERSION = YES;
201 | CLANG_WARN_CONSTANT_CONVERSION = YES;
202 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
203 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
204 | CLANG_WARN_EMPTY_BODY = YES;
205 | CLANG_WARN_ENUM_CONVERSION = YES;
206 | CLANG_WARN_INFINITE_RECURSION = YES;
207 | CLANG_WARN_INT_CONVERSION = YES;
208 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
209 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
210 | CLANG_WARN_UNREACHABLE_CODE = YES;
211 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
212 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
213 | COPY_PHASE_STRIP = NO;
214 | DEBUG_INFORMATION_FORMAT = dwarf;
215 | ENABLE_STRICT_OBJC_MSGSEND = YES;
216 | ENABLE_TESTABILITY = YES;
217 | GCC_C_LANGUAGE_STANDARD = gnu99;
218 | GCC_DYNAMIC_NO_PIC = NO;
219 | GCC_NO_COMMON_BLOCKS = YES;
220 | GCC_OPTIMIZATION_LEVEL = 0;
221 | GCC_PREPROCESSOR_DEFINITIONS = (
222 | "DEBUG=1",
223 | "$(inherited)",
224 | );
225 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
226 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
227 | GCC_WARN_UNDECLARED_SELECTOR = YES;
228 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
229 | GCC_WARN_UNUSED_FUNCTION = YES;
230 | GCC_WARN_UNUSED_VARIABLE = YES;
231 | IPHONEOS_DEPLOYMENT_TARGET = 10.1;
232 | MTL_ENABLE_DEBUG_INFO = YES;
233 | ONLY_ACTIVE_ARCH = YES;
234 | SDKROOT = iphoneos;
235 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
236 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
237 | };
238 | name = Debug;
239 | };
240 | FA56BC6D1DFAF9B600294C20 /* Release */ = {
241 | isa = XCBuildConfiguration;
242 | buildSettings = {
243 | ALWAYS_SEARCH_USER_PATHS = NO;
244 | CLANG_ANALYZER_NONNULL = YES;
245 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
246 | CLANG_CXX_LIBRARY = "libc++";
247 | CLANG_ENABLE_MODULES = YES;
248 | CLANG_ENABLE_OBJC_ARC = YES;
249 | CLANG_WARN_BOOL_CONVERSION = YES;
250 | CLANG_WARN_CONSTANT_CONVERSION = YES;
251 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
252 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
253 | CLANG_WARN_EMPTY_BODY = YES;
254 | CLANG_WARN_ENUM_CONVERSION = YES;
255 | CLANG_WARN_INFINITE_RECURSION = YES;
256 | CLANG_WARN_INT_CONVERSION = YES;
257 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
258 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
259 | CLANG_WARN_UNREACHABLE_CODE = YES;
260 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
261 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
262 | COPY_PHASE_STRIP = NO;
263 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
264 | ENABLE_NS_ASSERTIONS = NO;
265 | ENABLE_STRICT_OBJC_MSGSEND = YES;
266 | GCC_C_LANGUAGE_STANDARD = gnu99;
267 | GCC_NO_COMMON_BLOCKS = YES;
268 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
269 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
270 | GCC_WARN_UNDECLARED_SELECTOR = YES;
271 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
272 | GCC_WARN_UNUSED_FUNCTION = YES;
273 | GCC_WARN_UNUSED_VARIABLE = YES;
274 | IPHONEOS_DEPLOYMENT_TARGET = 10.1;
275 | MTL_ENABLE_DEBUG_INFO = NO;
276 | SDKROOT = iphoneos;
277 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
278 | VALIDATE_PRODUCT = YES;
279 | };
280 | name = Release;
281 | };
282 | FA56BC6F1DFAF9B600294C20 /* Debug */ = {
283 | isa = XCBuildConfiguration;
284 | buildSettings = {
285 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
286 | DEVELOPMENT_TEAM = 65H57KS853;
287 | INFOPLIST_FILE = ScratchCardImageView/Info.plist;
288 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
289 | PRODUCT_BUNDLE_IDENTIFIER = com.ScratchCardImageView;
290 | PRODUCT_NAME = "$(TARGET_NAME)";
291 | SWIFT_VERSION = 3.0;
292 | };
293 | name = Debug;
294 | };
295 | FA56BC701DFAF9B600294C20 /* Release */ = {
296 | isa = XCBuildConfiguration;
297 | buildSettings = {
298 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
299 | DEVELOPMENT_TEAM = 65H57KS853;
300 | INFOPLIST_FILE = ScratchCardImageView/Info.plist;
301 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
302 | PRODUCT_BUNDLE_IDENTIFIER = com.ScratchCardImageView;
303 | PRODUCT_NAME = "$(TARGET_NAME)";
304 | SWIFT_VERSION = 3.0;
305 | };
306 | name = Release;
307 | };
308 | /* End XCBuildConfiguration section */
309 |
310 | /* Begin XCConfigurationList section */
311 | FA56BC571DFAF9B600294C20 /* Build configuration list for PBXProject "ScratchCardImageView" */ = {
312 | isa = XCConfigurationList;
313 | buildConfigurations = (
314 | FA56BC6C1DFAF9B600294C20 /* Debug */,
315 | FA56BC6D1DFAF9B600294C20 /* Release */,
316 | );
317 | defaultConfigurationIsVisible = 0;
318 | defaultConfigurationName = Release;
319 | };
320 | FA56BC6E1DFAF9B600294C20 /* Build configuration list for PBXNativeTarget "ScratchCardImageView" */ = {
321 | isa = XCConfigurationList;
322 | buildConfigurations = (
323 | FA56BC6F1DFAF9B600294C20 /* Debug */,
324 | FA56BC701DFAF9B600294C20 /* Release */,
325 | );
326 | defaultConfigurationIsVisible = 0;
327 | defaultConfigurationName = Release;
328 | };
329 | /* End XCConfigurationList section */
330 | };
331 | rootObject = FA56BC541DFAF9B600294C20 /* Project object */;
332 | }
333 |
--------------------------------------------------------------------------------