├── screen.gif
├── Icomations.xcodeproj
├── xcuserdata
│ └── paoloboschini.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── Icomations.xcscheme
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ └── paoloboschini.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ │ └── Icomations.xccheckout
└── project.pbxproj
├── Icomations
├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Info.plist
├── AppDelegate.swift
├── Base.lproj
│ └── LaunchScreen.xib
├── ViewController.swift
├── Icomation.swift
└── View.xib
├── IcomationsTests
├── Info.plist
└── IcomationsTests.swift
├── README.md
└── LICENSE
/screen.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paoloboschini/Icomations/HEAD/screen.gif
--------------------------------------------------------------------------------
/Icomations.xcodeproj/xcuserdata/paoloboschini.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/Icomations.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Icomations.xcodeproj/project.xcworkspace/xcuserdata/paoloboschini.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paoloboschini/Icomations/HEAD/Icomations.xcodeproj/project.xcworkspace/xcuserdata/paoloboschini.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Icomations.xcodeproj/xcuserdata/paoloboschini.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Icomations.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 8705F9781A81809B006EFFA3
16 |
17 | primary
18 |
19 |
20 | 8705F98D1A81809B006EFFA3
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Icomations/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/IcomationsTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | Paolo-Boschini.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Icomations
2 | ====
3 |
4 | Swifty hamburger animations
5 |
6 | 
7 |
8 | Basic Usage
9 | ========
10 |
11 | See example project for a demo.
12 |
13 | Import Icomation.swift in your project. Add a button to your view via Interface Builder, change the class to Icomation in the Identity Inspector and connect an outlet to it. Or create a new Icomation in code
14 | ```swift
15 | var icomation = Icomation(frame: CGRectMake(0, 0, 50, 50))
16 | view.addSubview(icomation)
17 | ```
18 |
19 | Set a type
20 | ```swift
21 | icomation.type = IconType.ArrowUp
22 | ```
23 |
24 | Choose a color for each segment (default is white)
25 | ```swift
26 | icomation.topShape.strokeColor = UIColor.redColor().CGColor
27 | icomation.middleShape.strokeColor = UIColor.blueColor().CGColor
28 | icomation.bottomShape.strokeColor = UIColor.blackColor().CGColor
29 | ```
30 |
31 | Set a duration for the animation
32 | ```swift
33 | icomation.animationDuration = 1.0
34 | ```
35 |
36 | Set the number of rotations for the animation
37 | ```swift
38 | icomation.numberOfRotations = 3
39 | ```
--------------------------------------------------------------------------------
/IcomationsTests/IcomationsTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // IcomationsTests.swift
3 | // IcomationsTests
4 | //
5 | // Created by Paolo Boschini on 03/02/15.
6 | // Copyright (c) 2015 Paolo Boschini. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import XCTest
11 |
12 | class IcomationsTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | XCTAssert(true, "Pass")
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measureBlock() {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Paolo Boschini
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 |
23 |
--------------------------------------------------------------------------------
/Icomations/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | Paolo-Boschini.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Icomations.xcodeproj/project.xcworkspace/xcshareddata/Icomations.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | 3F9F7ADC-A12C-4BAE-9DA4-A964BA88C58D
9 | IDESourceControlProjectName
10 | Icomations
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | 34CCD18B62416183306B28C234CDB765D2883BC1
14 | github.com:paoloboschini/Icomations.git
15 |
16 | IDESourceControlProjectPath
17 | Icomations.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | 34CCD18B62416183306B28C234CDB765D2883BC1
21 | ../..
22 |
23 | IDESourceControlProjectURL
24 | github.com:paoloboschini/Icomations.git
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | 34CCD18B62416183306B28C234CDB765D2883BC1
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | 34CCD18B62416183306B28C234CDB765D2883BC1
36 | IDESourceControlWCCName
37 | Icomations
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Icomations/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Icomations
4 | //
5 | // Created by Paolo Boschini on 03/02/15.
6 | // Copyright (c) 2015 Paolo Boschini. 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: [NSObject: AnyObject]?) -> Bool {
17 |
18 | let vc = ViewController()
19 | window = UIWindow(frame: UIScreen.mainScreen().bounds)
20 | window?.rootViewController = UINavigationController(rootViewController: vc)
21 | window?.makeKeyAndVisible()
22 |
23 | return true
24 | }
25 |
26 | func applicationWillResignActive(application: UIApplication) {
27 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
28 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
29 | }
30 |
31 | func applicationDidEnterBackground(application: UIApplication) {
32 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
33 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
34 | }
35 |
36 | func applicationWillEnterForeground(application: UIApplication) {
37 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
38 | }
39 |
40 | func applicationDidBecomeActive(application: UIApplication) {
41 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
42 | }
43 |
44 | func applicationWillTerminate(application: UIApplication) {
45 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
46 | }
47 |
48 |
49 | }
50 |
51 |
--------------------------------------------------------------------------------
/Icomations/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Icomations/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // Icomations
4 | //
5 | // Created by Paolo Boschini on 03/02/15.
6 | // Copyright (c) 2015 Paolo Boschini. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
12 |
13 | @IBOutlet var tableView: UITableView!
14 | private var data = ["Duration: ", "Rotations: "]
15 | private var steppers = [UIStepper(), UIStepper()]
16 |
17 | @IBOutlet var arrowUp: Icomation!
18 | @IBOutlet var arrowDown: Icomation!
19 | @IBOutlet var arrowLeft: Icomation!
20 | @IBOutlet var arrowRight: Icomation!
21 | @IBOutlet var close: Icomation!
22 | @IBOutlet var smallArrowUp: Icomation!
23 | @IBOutlet var smallArrowDown: Icomation!
24 | @IBOutlet var smallArrowLeft: Icomation!
25 | @IBOutlet var smallArrowRight: Icomation!
26 | @IBOutlet var smallClose: Icomation!
27 | var icons: [Icomation]!
28 |
29 | init() {
30 | super.init(nibName: "View", bundle: nil)
31 | }
32 |
33 | required init(coder aDecoder: NSCoder) {
34 | super.init(coder: aDecoder)
35 | }
36 |
37 | override func viewDidLoad() {
38 | tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
39 | tableView.delaysContentTouches = false
40 | steppers[0].stepValue = 0.1
41 | steppers[0].value = 1.0
42 | data[0] = "Duration: \(steppers[0].value)"
43 |
44 | steppers[1].stepValue = 1
45 | data[1] = "Rotations: \(Int(steppers[1].value))"
46 |
47 | arrowUp.type = IconType.ArrowUp
48 | arrowDown.type = IconType.ArrowDown
49 | arrowLeft.type = IconType.ArrowLeft
50 | arrowRight.type = IconType.ArrowRight
51 |
52 | smallArrowUp.type = IconType.SmallArrowUp
53 | smallArrowDown.type = IconType.SmallArrowDown
54 | smallArrowLeft.type = IconType.SmallArrowLeft
55 | smallArrowRight.type = IconType.SmallArrowRight
56 |
57 | close.type = IconType.Close
58 | smallClose.type = IconType.SmallClose
59 |
60 | icons = [arrowUp, arrowDown, arrowLeft, arrowRight, smallArrowUp, smallArrowDown, smallArrowLeft, smallArrowRight, close, smallClose]
61 |
62 | title = "Icomations"
63 |
64 | // Add icomation via code
65 | // var icomation = Icomation(frame: CGRectMake(0, 0, 50, 50))
66 | // icomation.type = IconType.ArrowUp
67 | // icomation.animationDuration = 1.0
68 | // icomation.numberOfRotations = 3
69 | // icomation.addTarget(self, action: "click", forControlEvents: UIControlEvents.TouchUpInside)
70 | //
71 | // icomation.topShape.strokeColor = UIColor.redColor().CGColor
72 | // icomation.middleShape.strokeColor = UIColor.whiteColor().CGColor
73 | // icomation.bottomShape.strokeColor = UIColor.blackColor().CGColor
74 | // tableView.addSubview(icomation)
75 | }
76 |
77 | func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
78 | return data.count
79 | }
80 |
81 | func numberOfSectionsInTableView(tableView: UITableView) -> Int {
82 | return 1
83 | }
84 |
85 | func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
86 | var cell: UITableViewCell! = tableView.dequeueReusableCellWithIdentifier("Cell") as? UITableViewCell
87 | cell.textLabel?.text = data[indexPath.row]
88 | steppers[indexPath.row].addTarget(self, action: "valueChanged:", forControlEvents: UIControlEvents.ValueChanged)
89 | cell.accessoryView = steppers[indexPath.row]
90 | return cell
91 | }
92 |
93 | func valueChanged(stepper: UIStepper) {
94 | if stepper == steppers[0] {
95 | for icon in icons {
96 | icon.animationDuration = stepper.value
97 | }
98 | data[0] = "Duration: \(stepper.value)"
99 | }
100 | if stepper == steppers[1] {
101 | for icon in icons {
102 | icon.numberOfRotations = stepper.value
103 | }
104 | data[1] = "Rotations: \(Int(stepper.value))"
105 | }
106 | tableView.reloadData()
107 | }
108 |
109 | @IBAction func click() {
110 | println(__FUNCTION__)
111 | }
112 | }
--------------------------------------------------------------------------------
/Icomations.xcodeproj/xcuserdata/paoloboschini.xcuserdatad/xcschemes/Icomations.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
94 |
100 |
101 |
102 |
103 |
105 |
106 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/Icomations/Icomation.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Icomation.swift
3 | // Icomations
4 | //
5 | // Created by Paolo Boschini on 28/04/15.
6 | // Copyright (c) 2015 Paolo Boschini. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension CAAnimation {
12 | func setUp(duration: Double) {
13 | self.fillMode = kCAFillModeForwards
14 | self.removedOnCompletion = false
15 | self.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
16 | self.duration = CFTimeInterval(duration)
17 | }
18 | }
19 |
20 | enum IconType {
21 | case ArrowUp, ArrowLeft, ArrowDown, ArrowRight, SmallArrowUp, SmallArrowLeft, SmallArrowDown, SmallArrowRight, Close, SmallClose
22 | }
23 |
24 | class Icomation: UIButton {
25 |
26 | private enum IconState {
27 | case Hamburger, Arrow, Close
28 | }
29 |
30 | private var toggleState = true
31 | private var topAnimation, middleAnimation, bottomAnimation: CAAnimation!
32 | private var halfSideOfTriangle: CGFloat!
33 | private var w, h, lineWidth: CGFloat!
34 |
35 | var topShape, middleShape, bottomShape: CAShapeLayer!
36 | var animationDuration = 1.0
37 | var numberOfRotations: Double = 0
38 | var type: IconType!
39 |
40 | override init(frame: CGRect) {
41 | super.init(frame: frame)
42 | create()
43 | }
44 |
45 | required init(coder aDecoder: NSCoder) {
46 | super.init(coder: aDecoder)
47 | create()
48 | }
49 |
50 | private func create() {
51 | type = IconType.self.SmallArrowLeft
52 |
53 | titleLabel?.text = ""
54 | backgroundColor = UIColor.clearColor()
55 | let strokeColor = UIColor.whiteColor()
56 |
57 | w = bounds.width
58 | h = bounds.height
59 | lineWidth = 3
60 |
61 | let hypotenuse = w/2
62 | halfSideOfTriangle = (hypotenuse / sqrt(2)) / 2
63 |
64 | var path = UIBezierPath()
65 | path.moveToPoint(CGPoint(x: 0, y: 0))
66 | path.addLineToPoint(CGPoint(x: w, y: 0))
67 |
68 | topShape = shapeLayer(path.CGPath, position: CGPoint(x: w/2, y: h/4), color: strokeColor)
69 | topShape.bounds = CGPathGetBoundingBox(topShape.path)
70 |
71 | middleShape = shapeLayer(path.CGPath, position: CGPoint(x: w/2, y: h/2), color: strokeColor)
72 | middleShape.bounds = CGPathGetBoundingBox(middleShape.path)
73 |
74 | bottomShape = shapeLayer(path.CGPath, position: CGPoint(x: w/2, y: h-h/4), color: strokeColor)
75 | bottomShape.bounds = CGPathGetBoundingBox(bottomShape.path)
76 |
77 | layer.addSublayer(topShape)
78 | layer.addSublayer(middleShape)
79 | layer.addSublayer(bottomShape)
80 | }
81 |
82 | // MARK: - Shapes
83 |
84 | private func shapeLayer(path: CGPath, position: CGPoint, color: UIColor) -> CAShapeLayer{
85 | let s = CAShapeLayer()
86 | s.lineWidth = lineWidth
87 | s.lineCap = kCALineCapRound
88 | s.strokeColor = color.CGColor
89 | s.path = path
90 | s.position = position
91 | return s
92 | }
93 |
94 | // MARK: - Animations
95 |
96 | private func basicAnimation(keyPath: String, from: CGFloat = -1, to: CGFloat = -1, byValue: CGFloat = -1) -> CABasicAnimation {
97 | let a = CABasicAnimation(keyPath: keyPath)
98 | if from != -1 { a.fromValue = from }
99 | if to != -1 { a.toValue = to }
100 | if byValue != -1 { a.byValue = byValue }
101 | return a
102 | }
103 |
104 | private func groupAnimation(type: IconState, x: CGFloat = 0, y: CGFloat = 0, r: CGFloat = 0, s: CGFloat = 0.5) -> CAAnimation {
105 |
106 | var xa, ya, ra, sa: CABasicAnimation!
107 |
108 | if type == IconState.Arrow || type == IconState.Close {
109 | xa = basicAnimation("transform.translation.x", from: 0, to: x)
110 | ya = basicAnimation("transform.translation.y", from: 0, to: y)
111 | ra = basicAnimation("transform.rotation.z", from: 0, to: r)
112 | sa = basicAnimation("transform.scale.x", byValue: -s)
113 | }
114 |
115 | if type == IconState.Hamburger {
116 | xa = basicAnimation("transform.translation.x", from: x, to: 0)
117 | ya = basicAnimation("transform.translation.y", from: y, to: 0)
118 | ra = basicAnimation("transform.rotation.z", from: r, to: 0)
119 | sa = basicAnimation("transform.scale.x", byValue: s)
120 | }
121 |
122 | let group = CAAnimationGroup()
123 | group.setUp(animationDuration)
124 | group.animations = [xa, ya, ra, sa]
125 | return group
126 | }
127 |
128 | private func rotate(type: IconState, to: CGFloat) -> CAAnimation {
129 | var r: CABasicAnimation!
130 | if type == IconState.Arrow {
131 | r = basicAnimation("transform.rotation.z", from: 0, to: to)
132 | }
133 | if type == IconState.Hamburger {
134 | r = basicAnimation("transform.rotation.z", from: to, to: 0)
135 | }
136 | r.setUp(animationDuration)
137 | return r
138 | }
139 |
140 | private func shrinkToDisappear(type: IconState) -> CAAnimation {
141 | let value: CGFloat = type == IconState.Close ? -0.999 : 1.0
142 | let s = basicAnimation("transform.scale.x", byValue: value)
143 | s.setUp(animationDuration)
144 | return s
145 | }
146 |
147 | private func addAnimations() {
148 | topShape.addAnimation(topAnimation, forKey:"")
149 | middleShape.addAnimation(middleAnimation, forKey:"")
150 | bottomShape.addAnimation(bottomAnimation, forKey:"")
151 | }
152 |
153 | // MARK: - Toggles
154 |
155 | private func arrowLeft() {
156 | let buttonType = toggleState ? IconState.Arrow : IconState.Hamburger
157 |
158 | let topRotation = CGFloat(-M_PI * (3/4 + numberOfRotations))
159 | topAnimation = groupAnimation(buttonType, x: halfSideOfTriangle - w/2, y: halfSideOfTriangle + h/4, r: topRotation)
160 |
161 | let middleRotation = CGFloat(-M_PI * (numberOfRotations + 1))
162 | middleAnimation = rotate(buttonType, to: middleRotation)
163 |
164 | let bottomRotation = CGFloat(-M_PI * (5/4 + numberOfRotations))
165 | bottomAnimation = groupAnimation(buttonType, x: halfSideOfTriangle - w/2, y: -h/4 - halfSideOfTriangle, r: bottomRotation)
166 |
167 | addAnimations()
168 | toggleState = !toggleState
169 | }
170 |
171 | private func smallArrowLeft() {
172 | let buttonType = toggleState ? IconState.Arrow : IconState.Hamburger
173 |
174 | let topRotation = CGFloat(-M_PI * (3/4 + numberOfRotations))
175 | topAnimation = groupAnimation(buttonType, x: -halfSideOfTriangle + 1, y: (halfSideOfTriangle/2) + h/4, r: topRotation, s: 3/4)
176 |
177 | let middleRotation = CGFloat(-M_PI * (numberOfRotations + 1))
178 | middleAnimation = groupAnimation(buttonType, r: middleRotation)
179 |
180 | let bottomRotation = CGFloat(-M_PI * (5/4 + numberOfRotations))
181 | bottomAnimation = groupAnimation(buttonType, x: -halfSideOfTriangle + 1, y: -h/4 - (halfSideOfTriangle/2), r: bottomRotation, s: 3/4)
182 |
183 | addAnimations()
184 | toggleState = !toggleState
185 | }
186 |
187 | private func arrowUp() {
188 | let buttonType = toggleState ? IconState.Arrow : IconState.Hamburger
189 |
190 | let topRotation = CGFloat(-M_PI * (3/4 + numberOfRotations))
191 | topAnimation = groupAnimation(buttonType, x: halfSideOfTriangle, y: 0 - halfSideOfTriangle/2, r: topRotation)
192 |
193 | var add: CGFloat!
194 | if numberOfRotations == 0 {
195 | add = 0
196 | } else if numberOfRotations % 2 == 0 {
197 | add = CGFloat(-M_PI)
198 | } else {
199 | add = CGFloat(-M_PI/2)
200 | }
201 | let middleRotation = CGFloat(add - CGFloat(M_PI/2) * CGFloat(numberOfRotations + 1))
202 | middleAnimation = rotate(buttonType, to: middleRotation)
203 |
204 | let bottomRotation = CGFloat(-M_PI * (1/4 + numberOfRotations))
205 | bottomAnimation = groupAnimation(buttonType, x: -halfSideOfTriangle, y: -h/2 - halfSideOfTriangle/2, r: bottomRotation)
206 |
207 | addAnimations()
208 | toggleState = !toggleState
209 | }
210 |
211 | private func smallArrowUp() {
212 | let buttonType = toggleState ? IconState.Arrow : IconState.Hamburger
213 |
214 | let topRotation = CGFloat(-M_PI * (3/4 + numberOfRotations))
215 | topAnimation = groupAnimation(buttonType, x: halfSideOfTriangle/2, y: halfSideOfTriangle/2 - 1, r: topRotation, s: 3/4)
216 |
217 | var add: CGFloat!
218 | if numberOfRotations == 0 {
219 | add = 0
220 | } else if numberOfRotations % 2 == 0 {
221 | add = CGFloat(-M_PI)
222 | } else {
223 | add = CGFloat(-M_PI/2)
224 | }
225 | let middleRotation = CGFloat(add - CGFloat(M_PI/2) * CGFloat(numberOfRotations + 1))
226 | middleAnimation = groupAnimation(buttonType, r: middleRotation)
227 |
228 | let bottomRotation = CGFloat(-M_PI * (1/4 + numberOfRotations))
229 | bottomAnimation = groupAnimation(buttonType, x: -halfSideOfTriangle/2, y: -w/2 + halfSideOfTriangle/2 - 1, r: bottomRotation, s: 3/4)
230 |
231 | addAnimations()
232 | toggleState = !toggleState
233 | }
234 |
235 | private func arrowDown() {
236 | let buttonType = toggleState ? IconState.Arrow : IconState.Hamburger
237 |
238 | let topRotation = CGFloat(M_PI * (3/4 + numberOfRotations))
239 | topAnimation = groupAnimation(buttonType, x: halfSideOfTriangle, y: h/2 + halfSideOfTriangle/2 - 1, r: topRotation)
240 |
241 | var add: CGFloat!
242 | if numberOfRotations == 0 {
243 | add = 0
244 | } else if numberOfRotations % 2 == 0 {
245 | add = CGFloat(M_PI)
246 | } else {
247 | add = CGFloat(M_PI/2)
248 | }
249 | let middleRotation = CGFloat(add + CGFloat(M_PI/2) * CGFloat(numberOfRotations + 1))
250 | middleAnimation = rotate(buttonType, to: middleRotation)
251 |
252 | let bottomRotation = CGFloat(M_PI * (1/4 + numberOfRotations))
253 | bottomAnimation = groupAnimation(buttonType, x: -halfSideOfTriangle, y: halfSideOfTriangle/2 - 1, r: bottomRotation)
254 |
255 | addAnimations()
256 | toggleState = !toggleState
257 | }
258 |
259 | private func smallArrowDown() {
260 | let buttonType = toggleState ? IconState.Arrow : IconState.Hamburger
261 |
262 | let topRotation = CGFloat(M_PI * (1/4 + numberOfRotations))
263 | topAnimation = groupAnimation(buttonType, x: -halfSideOfTriangle/2, y: w/2 - halfSideOfTriangle/2, r: topRotation, s: 3/4)
264 |
265 | var add: CGFloat!
266 | if numberOfRotations == 0 {
267 | add = 0
268 | } else if numberOfRotations % 2 == 0 {
269 | add = CGFloat(M_PI)
270 | } else {
271 | add = CGFloat(M_PI/2)
272 | }
273 | let middleRotation = CGFloat(add + CGFloat(M_PI/2) * CGFloat(numberOfRotations + 1))
274 | middleAnimation = groupAnimation(buttonType, r: middleRotation)
275 |
276 | let bottomRotation = CGFloat(M_PI * (3/4 + numberOfRotations))
277 | bottomAnimation = groupAnimation(buttonType, x: halfSideOfTriangle/2, y: -halfSideOfTriangle/2, r: bottomRotation, s: 3/4)
278 |
279 | addAnimations()
280 | toggleState = !toggleState
281 | }
282 |
283 | private func arrowRight() {
284 | let buttonType = toggleState ? IconState.Arrow : IconState.Hamburger
285 |
286 | let topRotation = CGFloat(M_PI * (3/4 + numberOfRotations))
287 | topAnimation = groupAnimation(buttonType, x: w/2 - halfSideOfTriangle, y: halfSideOfTriangle + h/4, r: topRotation)
288 |
289 | let middleRotation = CGFloat(M_PI * (numberOfRotations + 1))
290 | middleAnimation = rotate(buttonType, to: middleRotation)
291 |
292 | let bottomRotation = CGFloat(M_PI * (5/4 + numberOfRotations))
293 | bottomAnimation = groupAnimation(buttonType, x: w/2 - halfSideOfTriangle, y: -h/4 - halfSideOfTriangle, r: bottomRotation)
294 |
295 | addAnimations()
296 | toggleState = !toggleState
297 | }
298 |
299 | private func smallArrowRight() {
300 | let buttonType = toggleState ? IconState.Arrow : IconState.Hamburger
301 |
302 | let topRotation = CGFloat(M_PI * (3/4 + numberOfRotations))
303 | topAnimation = groupAnimation(buttonType, x: halfSideOfTriangle - 1, y: (halfSideOfTriangle/2) + h/4, r: topRotation, s: 3/4)
304 |
305 | let middleRotation = CGFloat(M_PI * (numberOfRotations + 1))
306 | middleAnimation = groupAnimation(buttonType, r: middleRotation)
307 |
308 | let bottomRotation = CGFloat(M_PI * (5/4 + numberOfRotations))
309 | bottomAnimation = groupAnimation(buttonType, x: halfSideOfTriangle - 1, y: (-halfSideOfTriangle/2) - h/4, r: bottomRotation, s: 3/4)
310 |
311 | addAnimations()
312 | toggleState = !toggleState
313 | }
314 |
315 | private func close() {
316 | let buttonType = toggleState ? IconState.Close : IconState.Hamburger
317 |
318 | topAnimation = groupAnimation(buttonType, y: h/4, r: CGFloat(M_PI * (3/4 + numberOfRotations)), s: 0)
319 | middleAnimation = shrinkToDisappear(buttonType)
320 | bottomAnimation = groupAnimation(buttonType, y: -h/4, r: CGFloat(M_PI * (5/4 + numberOfRotations)), s: 0)
321 |
322 | addAnimations()
323 | toggleState = !toggleState
324 | }
325 |
326 | private func smallClose() {
327 | let buttonType = toggleState ? IconState.Close : IconState.Hamburger
328 |
329 | topAnimation = groupAnimation(buttonType, y: h/4, r: CGFloat(M_PI * (3/4 + numberOfRotations)))
330 | middleAnimation = shrinkToDisappear(buttonType)
331 | bottomAnimation = groupAnimation(buttonType, y: -h/4, r: CGFloat(M_PI * (5/4 + numberOfRotations)))
332 |
333 | addAnimations()
334 | toggleState = !toggleState
335 | }
336 |
337 | // MARK: - Touch Gestures
338 |
339 | override func touchesBegan(touches: Set, withEvent event: UIEvent) {
340 | super.touchesBegan(touches, withEvent: event)
341 | UIView.animateWithDuration(0.1, animations: { () -> Void in
342 | self.transform = CGAffineTransformMakeScale(0.8, 0.8)
343 | })
344 | }
345 |
346 | override func touchesEnded(touches: Set, withEvent event: UIEvent) {
347 | super.touchesEnded(touches, withEvent: event)
348 | UIView.animateWithDuration(0.1, animations: { () -> Void in
349 | self.transform = CGAffineTransformMakeScale(1.0, 1.0)
350 | switch self.type {
351 | case IconType.self.ArrowUp: self.arrowUp()
352 | case IconType.self.ArrowLeft: self.arrowLeft()
353 | case IconType.self.ArrowDown: self.arrowDown()
354 | case IconType.self.ArrowRight: self.arrowRight()
355 | case IconType.self.Close: self.close()
356 | case IconType.self.SmallArrowUp: self.smallArrowUp()
357 | case IconType.self.SmallArrowLeft: self.smallArrowLeft()
358 | case IconType.self.SmallArrowDown: self.smallArrowDown()
359 | case IconType.self.SmallArrowRight: self.smallArrowRight()
360 | case IconType.self.SmallClose: self.smallClose()
361 | default: self.close()
362 | }
363 | })
364 | }
365 | }
--------------------------------------------------------------------------------
/Icomations.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 87026E5E1AF00802005EAD44 /* Icomation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87026E5D1AF00802005EAD44 /* Icomation.swift */; };
11 | 8705F97F1A81809B006EFFA3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8705F97E1A81809B006EFFA3 /* AppDelegate.swift */; };
12 | 8705F9811A81809B006EFFA3 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8705F9801A81809B006EFFA3 /* ViewController.swift */; };
13 | 8705F9861A81809B006EFFA3 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8705F9851A81809B006EFFA3 /* Images.xcassets */; };
14 | 8705F9891A81809B006EFFA3 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8705F9871A81809B006EFFA3 /* LaunchScreen.xib */; };
15 | 8705F9951A81809B006EFFA3 /* IcomationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8705F9941A81809B006EFFA3 /* IcomationsTests.swift */; };
16 | 8705F99F1A818139006EFFA3 /* View.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8705F99E1A818139006EFFA3 /* View.xib */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXContainerItemProxy section */
20 | 8705F98F1A81809B006EFFA3 /* PBXContainerItemProxy */ = {
21 | isa = PBXContainerItemProxy;
22 | containerPortal = 8705F9711A81809B006EFFA3 /* Project object */;
23 | proxyType = 1;
24 | remoteGlobalIDString = 8705F9781A81809B006EFFA3;
25 | remoteInfo = Icomations;
26 | };
27 | /* End PBXContainerItemProxy section */
28 |
29 | /* Begin PBXFileReference section */
30 | 87026E5D1AF00802005EAD44 /* Icomation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Icomation.swift; sourceTree = ""; };
31 | 8705F9791A81809B006EFFA3 /* Icomations.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Icomations.app; sourceTree = BUILT_PRODUCTS_DIR; };
32 | 8705F97D1A81809B006EFFA3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
33 | 8705F97E1A81809B006EFFA3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
34 | 8705F9801A81809B006EFFA3 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
35 | 8705F9851A81809B006EFFA3 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
36 | 8705F9881A81809B006EFFA3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
37 | 8705F98E1A81809B006EFFA3 /* IcomationsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IcomationsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
38 | 8705F9931A81809B006EFFA3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
39 | 8705F9941A81809B006EFFA3 /* IcomationsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IcomationsTests.swift; sourceTree = ""; };
40 | 8705F99E1A818139006EFFA3 /* View.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = View.xib; sourceTree = ""; };
41 | /* End PBXFileReference section */
42 |
43 | /* Begin PBXFrameworksBuildPhase section */
44 | 8705F9761A81809B006EFFA3 /* Frameworks */ = {
45 | isa = PBXFrameworksBuildPhase;
46 | buildActionMask = 2147483647;
47 | files = (
48 | );
49 | runOnlyForDeploymentPostprocessing = 0;
50 | };
51 | 8705F98B1A81809B006EFFA3 /* Frameworks */ = {
52 | isa = PBXFrameworksBuildPhase;
53 | buildActionMask = 2147483647;
54 | files = (
55 | );
56 | runOnlyForDeploymentPostprocessing = 0;
57 | };
58 | /* End PBXFrameworksBuildPhase section */
59 |
60 | /* Begin PBXGroup section */
61 | 8705F9701A81809B006EFFA3 = {
62 | isa = PBXGroup;
63 | children = (
64 | 8705F97B1A81809B006EFFA3 /* Icomations */,
65 | 8705F9911A81809B006EFFA3 /* IcomationsTests */,
66 | 8705F97A1A81809B006EFFA3 /* Products */,
67 | );
68 | sourceTree = "";
69 | };
70 | 8705F97A1A81809B006EFFA3 /* Products */ = {
71 | isa = PBXGroup;
72 | children = (
73 | 8705F9791A81809B006EFFA3 /* Icomations.app */,
74 | 8705F98E1A81809B006EFFA3 /* IcomationsTests.xctest */,
75 | );
76 | name = Products;
77 | sourceTree = "";
78 | };
79 | 8705F97B1A81809B006EFFA3 /* Icomations */ = {
80 | isa = PBXGroup;
81 | children = (
82 | 8705F97E1A81809B006EFFA3 /* AppDelegate.swift */,
83 | 8705F9801A81809B006EFFA3 /* ViewController.swift */,
84 | 8705F99E1A818139006EFFA3 /* View.xib */,
85 | 87026E5D1AF00802005EAD44 /* Icomation.swift */,
86 | 8705F9851A81809B006EFFA3 /* Images.xcassets */,
87 | 8705F9871A81809B006EFFA3 /* LaunchScreen.xib */,
88 | 8705F97C1A81809B006EFFA3 /* Supporting Files */,
89 | );
90 | path = Icomations;
91 | sourceTree = "";
92 | };
93 | 8705F97C1A81809B006EFFA3 /* Supporting Files */ = {
94 | isa = PBXGroup;
95 | children = (
96 | 8705F97D1A81809B006EFFA3 /* Info.plist */,
97 | );
98 | name = "Supporting Files";
99 | sourceTree = "";
100 | };
101 | 8705F9911A81809B006EFFA3 /* IcomationsTests */ = {
102 | isa = PBXGroup;
103 | children = (
104 | 8705F9941A81809B006EFFA3 /* IcomationsTests.swift */,
105 | 8705F9921A81809B006EFFA3 /* Supporting Files */,
106 | );
107 | path = IcomationsTests;
108 | sourceTree = "";
109 | };
110 | 8705F9921A81809B006EFFA3 /* Supporting Files */ = {
111 | isa = PBXGroup;
112 | children = (
113 | 8705F9931A81809B006EFFA3 /* Info.plist */,
114 | );
115 | name = "Supporting Files";
116 | sourceTree = "";
117 | };
118 | /* End PBXGroup section */
119 |
120 | /* Begin PBXNativeTarget section */
121 | 8705F9781A81809B006EFFA3 /* Icomations */ = {
122 | isa = PBXNativeTarget;
123 | buildConfigurationList = 8705F9981A81809B006EFFA3 /* Build configuration list for PBXNativeTarget "Icomations" */;
124 | buildPhases = (
125 | 8705F9751A81809B006EFFA3 /* Sources */,
126 | 8705F9761A81809B006EFFA3 /* Frameworks */,
127 | 8705F9771A81809B006EFFA3 /* Resources */,
128 | );
129 | buildRules = (
130 | );
131 | dependencies = (
132 | );
133 | name = Icomations;
134 | productName = Icomations;
135 | productReference = 8705F9791A81809B006EFFA3 /* Icomations.app */;
136 | productType = "com.apple.product-type.application";
137 | };
138 | 8705F98D1A81809B006EFFA3 /* IcomationsTests */ = {
139 | isa = PBXNativeTarget;
140 | buildConfigurationList = 8705F99B1A81809B006EFFA3 /* Build configuration list for PBXNativeTarget "IcomationsTests" */;
141 | buildPhases = (
142 | 8705F98A1A81809B006EFFA3 /* Sources */,
143 | 8705F98B1A81809B006EFFA3 /* Frameworks */,
144 | 8705F98C1A81809B006EFFA3 /* Resources */,
145 | );
146 | buildRules = (
147 | );
148 | dependencies = (
149 | 8705F9901A81809B006EFFA3 /* PBXTargetDependency */,
150 | );
151 | name = IcomationsTests;
152 | productName = IcomationsTests;
153 | productReference = 8705F98E1A81809B006EFFA3 /* IcomationsTests.xctest */;
154 | productType = "com.apple.product-type.bundle.unit-test";
155 | };
156 | /* End PBXNativeTarget section */
157 |
158 | /* Begin PBXProject section */
159 | 8705F9711A81809B006EFFA3 /* Project object */ = {
160 | isa = PBXProject;
161 | attributes = {
162 | LastUpgradeCheck = 0610;
163 | ORGANIZATIONNAME = "Paolo Boschini";
164 | TargetAttributes = {
165 | 8705F9781A81809B006EFFA3 = {
166 | CreatedOnToolsVersion = 6.1.1;
167 | };
168 | 8705F98D1A81809B006EFFA3 = {
169 | CreatedOnToolsVersion = 6.1.1;
170 | TestTargetID = 8705F9781A81809B006EFFA3;
171 | };
172 | };
173 | };
174 | buildConfigurationList = 8705F9741A81809B006EFFA3 /* Build configuration list for PBXProject "Icomations" */;
175 | compatibilityVersion = "Xcode 3.2";
176 | developmentRegion = English;
177 | hasScannedForEncodings = 0;
178 | knownRegions = (
179 | en,
180 | Base,
181 | );
182 | mainGroup = 8705F9701A81809B006EFFA3;
183 | productRefGroup = 8705F97A1A81809B006EFFA3 /* Products */;
184 | projectDirPath = "";
185 | projectRoot = "";
186 | targets = (
187 | 8705F9781A81809B006EFFA3 /* Icomations */,
188 | 8705F98D1A81809B006EFFA3 /* IcomationsTests */,
189 | );
190 | };
191 | /* End PBXProject section */
192 |
193 | /* Begin PBXResourcesBuildPhase section */
194 | 8705F9771A81809B006EFFA3 /* Resources */ = {
195 | isa = PBXResourcesBuildPhase;
196 | buildActionMask = 2147483647;
197 | files = (
198 | 8705F9891A81809B006EFFA3 /* LaunchScreen.xib in Resources */,
199 | 8705F99F1A818139006EFFA3 /* View.xib in Resources */,
200 | 8705F9861A81809B006EFFA3 /* Images.xcassets in Resources */,
201 | );
202 | runOnlyForDeploymentPostprocessing = 0;
203 | };
204 | 8705F98C1A81809B006EFFA3 /* Resources */ = {
205 | isa = PBXResourcesBuildPhase;
206 | buildActionMask = 2147483647;
207 | files = (
208 | );
209 | runOnlyForDeploymentPostprocessing = 0;
210 | };
211 | /* End PBXResourcesBuildPhase section */
212 |
213 | /* Begin PBXSourcesBuildPhase section */
214 | 8705F9751A81809B006EFFA3 /* Sources */ = {
215 | isa = PBXSourcesBuildPhase;
216 | buildActionMask = 2147483647;
217 | files = (
218 | 8705F9811A81809B006EFFA3 /* ViewController.swift in Sources */,
219 | 87026E5E1AF00802005EAD44 /* Icomation.swift in Sources */,
220 | 8705F97F1A81809B006EFFA3 /* AppDelegate.swift in Sources */,
221 | );
222 | runOnlyForDeploymentPostprocessing = 0;
223 | };
224 | 8705F98A1A81809B006EFFA3 /* Sources */ = {
225 | isa = PBXSourcesBuildPhase;
226 | buildActionMask = 2147483647;
227 | files = (
228 | 8705F9951A81809B006EFFA3 /* IcomationsTests.swift in Sources */,
229 | );
230 | runOnlyForDeploymentPostprocessing = 0;
231 | };
232 | /* End PBXSourcesBuildPhase section */
233 |
234 | /* Begin PBXTargetDependency section */
235 | 8705F9901A81809B006EFFA3 /* PBXTargetDependency */ = {
236 | isa = PBXTargetDependency;
237 | target = 8705F9781A81809B006EFFA3 /* Icomations */;
238 | targetProxy = 8705F98F1A81809B006EFFA3 /* PBXContainerItemProxy */;
239 | };
240 | /* End PBXTargetDependency section */
241 |
242 | /* Begin PBXVariantGroup section */
243 | 8705F9871A81809B006EFFA3 /* LaunchScreen.xib */ = {
244 | isa = PBXVariantGroup;
245 | children = (
246 | 8705F9881A81809B006EFFA3 /* Base */,
247 | );
248 | name = LaunchScreen.xib;
249 | sourceTree = "";
250 | };
251 | /* End PBXVariantGroup section */
252 |
253 | /* Begin XCBuildConfiguration section */
254 | 8705F9961A81809B006EFFA3 /* Debug */ = {
255 | isa = XCBuildConfiguration;
256 | buildSettings = {
257 | ALWAYS_SEARCH_USER_PATHS = NO;
258 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
259 | CLANG_CXX_LIBRARY = "libc++";
260 | CLANG_ENABLE_MODULES = YES;
261 | CLANG_ENABLE_OBJC_ARC = YES;
262 | CLANG_WARN_BOOL_CONVERSION = YES;
263 | CLANG_WARN_CONSTANT_CONVERSION = YES;
264 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
265 | CLANG_WARN_EMPTY_BODY = YES;
266 | CLANG_WARN_ENUM_CONVERSION = YES;
267 | CLANG_WARN_INT_CONVERSION = YES;
268 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
269 | CLANG_WARN_UNREACHABLE_CODE = YES;
270 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
271 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
272 | COPY_PHASE_STRIP = NO;
273 | ENABLE_STRICT_OBJC_MSGSEND = YES;
274 | GCC_C_LANGUAGE_STANDARD = gnu99;
275 | GCC_DYNAMIC_NO_PIC = NO;
276 | GCC_OPTIMIZATION_LEVEL = 0;
277 | GCC_PREPROCESSOR_DEFINITIONS = (
278 | "DEBUG=1",
279 | "$(inherited)",
280 | );
281 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
282 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
283 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
284 | GCC_WARN_UNDECLARED_SELECTOR = YES;
285 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
286 | GCC_WARN_UNUSED_FUNCTION = YES;
287 | GCC_WARN_UNUSED_VARIABLE = YES;
288 | IPHONEOS_DEPLOYMENT_TARGET = 8.1;
289 | MTL_ENABLE_DEBUG_INFO = YES;
290 | ONLY_ACTIVE_ARCH = YES;
291 | SDKROOT = iphoneos;
292 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
293 | };
294 | name = Debug;
295 | };
296 | 8705F9971A81809B006EFFA3 /* Release */ = {
297 | isa = XCBuildConfiguration;
298 | buildSettings = {
299 | ALWAYS_SEARCH_USER_PATHS = NO;
300 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
301 | CLANG_CXX_LIBRARY = "libc++";
302 | CLANG_ENABLE_MODULES = YES;
303 | CLANG_ENABLE_OBJC_ARC = YES;
304 | CLANG_WARN_BOOL_CONVERSION = YES;
305 | CLANG_WARN_CONSTANT_CONVERSION = YES;
306 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
307 | CLANG_WARN_EMPTY_BODY = YES;
308 | CLANG_WARN_ENUM_CONVERSION = YES;
309 | CLANG_WARN_INT_CONVERSION = YES;
310 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
311 | CLANG_WARN_UNREACHABLE_CODE = YES;
312 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
313 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
314 | COPY_PHASE_STRIP = YES;
315 | ENABLE_NS_ASSERTIONS = NO;
316 | ENABLE_STRICT_OBJC_MSGSEND = YES;
317 | GCC_C_LANGUAGE_STANDARD = gnu99;
318 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
319 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
320 | GCC_WARN_UNDECLARED_SELECTOR = YES;
321 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
322 | GCC_WARN_UNUSED_FUNCTION = YES;
323 | GCC_WARN_UNUSED_VARIABLE = YES;
324 | IPHONEOS_DEPLOYMENT_TARGET = 8.1;
325 | MTL_ENABLE_DEBUG_INFO = NO;
326 | SDKROOT = iphoneos;
327 | VALIDATE_PRODUCT = YES;
328 | };
329 | name = Release;
330 | };
331 | 8705F9991A81809B006EFFA3 /* Debug */ = {
332 | isa = XCBuildConfiguration;
333 | buildSettings = {
334 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
335 | INFOPLIST_FILE = Icomations/Info.plist;
336 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
337 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
338 | PRODUCT_NAME = "$(TARGET_NAME)";
339 | };
340 | name = Debug;
341 | };
342 | 8705F99A1A81809B006EFFA3 /* Release */ = {
343 | isa = XCBuildConfiguration;
344 | buildSettings = {
345 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
346 | INFOPLIST_FILE = Icomations/Info.plist;
347 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
348 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
349 | PRODUCT_NAME = "$(TARGET_NAME)";
350 | };
351 | name = Release;
352 | };
353 | 8705F99C1A81809B006EFFA3 /* Debug */ = {
354 | isa = XCBuildConfiguration;
355 | buildSettings = {
356 | BUNDLE_LOADER = "$(TEST_HOST)";
357 | FRAMEWORK_SEARCH_PATHS = (
358 | "$(SDKROOT)/Developer/Library/Frameworks",
359 | "$(inherited)",
360 | );
361 | GCC_PREPROCESSOR_DEFINITIONS = (
362 | "DEBUG=1",
363 | "$(inherited)",
364 | );
365 | INFOPLIST_FILE = IcomationsTests/Info.plist;
366 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
367 | PRODUCT_NAME = "$(TARGET_NAME)";
368 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Icomations.app/Icomations";
369 | };
370 | name = Debug;
371 | };
372 | 8705F99D1A81809B006EFFA3 /* Release */ = {
373 | isa = XCBuildConfiguration;
374 | buildSettings = {
375 | BUNDLE_LOADER = "$(TEST_HOST)";
376 | FRAMEWORK_SEARCH_PATHS = (
377 | "$(SDKROOT)/Developer/Library/Frameworks",
378 | "$(inherited)",
379 | );
380 | INFOPLIST_FILE = IcomationsTests/Info.plist;
381 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
382 | PRODUCT_NAME = "$(TARGET_NAME)";
383 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Icomations.app/Icomations";
384 | };
385 | name = Release;
386 | };
387 | /* End XCBuildConfiguration section */
388 |
389 | /* Begin XCConfigurationList section */
390 | 8705F9741A81809B006EFFA3 /* Build configuration list for PBXProject "Icomations" */ = {
391 | isa = XCConfigurationList;
392 | buildConfigurations = (
393 | 8705F9961A81809B006EFFA3 /* Debug */,
394 | 8705F9971A81809B006EFFA3 /* Release */,
395 | );
396 | defaultConfigurationIsVisible = 0;
397 | defaultConfigurationName = Release;
398 | };
399 | 8705F9981A81809B006EFFA3 /* Build configuration list for PBXNativeTarget "Icomations" */ = {
400 | isa = XCConfigurationList;
401 | buildConfigurations = (
402 | 8705F9991A81809B006EFFA3 /* Debug */,
403 | 8705F99A1A81809B006EFFA3 /* Release */,
404 | );
405 | defaultConfigurationIsVisible = 0;
406 | defaultConfigurationName = Release;
407 | };
408 | 8705F99B1A81809B006EFFA3 /* Build configuration list for PBXNativeTarget "IcomationsTests" */ = {
409 | isa = XCConfigurationList;
410 | buildConfigurations = (
411 | 8705F99C1A81809B006EFFA3 /* Debug */,
412 | 8705F99D1A81809B006EFFA3 /* Release */,
413 | );
414 | defaultConfigurationIsVisible = 0;
415 | defaultConfigurationName = Release;
416 | };
417 | /* End XCConfigurationList section */
418 | };
419 | rootObject = 8705F9711A81809B006EFFA3 /* Project object */;
420 | }
421 |
--------------------------------------------------------------------------------
/Icomations/View.xib:
--------------------------------------------------------------------------------
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 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
50 |
64 |
78 |
92 |
106 |
120 |
134 |
148 |
162 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
--------------------------------------------------------------------------------