├── assets
├── icon@2x.png
├── icon@3x.png
├── appstore.png
├── icon-ipad.png
├── appstore@2x.png
├── icon-ipad@2x.png
├── icon-ipad-pro@2x.png
├── icon-settings@2x.png
├── icon-settings@3x.png
├── icon-spotlight@2x.png
├── icon-spotlight@3x.png
├── icon-ipad-settings.png
├── icon-ipad-spotlight.png
├── icon-ipad-settings@2x.png
└── icon-ipad-spotlight@2x.png
├── himbo
├── Images.xcassets
│ ├── AppIcon.appiconset
│ │ ├── appstore.png
│ │ ├── icon@2x.png
│ │ ├── icon@3x.png
│ │ ├── icon-ipad.png
│ │ ├── icon-ipad@2x.png
│ │ ├── icon-ipad-pro@2x.png
│ │ ├── icon-ipad-settings.png
│ │ ├── icon-settings@2x.png
│ │ ├── icon-settings@3x.png
│ │ ├── icon-spotlight@2x.png
│ │ ├── icon-spotlight@3x.png
│ │ ├── icon-ipad-spotlight.png
│ │ ├── icon-ipad-settings@2x.png
│ │ ├── icon-ipad-spotlight@2x.png
│ │ └── Contents.json
│ ├── icon-close.imageset
│ │ ├── icon-close@2x.png
│ │ └── Contents.json
│ ├── icon-email.imageset
│ │ ├── icon-email@2x.png
│ │ └── Contents.json
│ ├── icon-share.imageset
│ │ ├── icon-share@2x.png
│ │ └── Contents.json
│ ├── icon-gallery.imageset
│ │ ├── icon-gallery@2x.png
│ │ └── Contents.json
│ ├── icon-twitter.imageset
│ │ ├── icon-twitter@2x.png
│ │ └── Contents.json
│ └── icon-facebook.imageset
│ │ ├── icon-facebook@2x.png
│ │ └── Contents.json
├── himbo.entitlements
├── Colors.swift
├── Base.lproj
│ ├── LaunchScreen.xib
│ └── Main.storyboard
├── ShakeView.swift
├── Info.plist
├── AppDelegate.swift
├── Exporter.swift
├── PulsingLayer.swift
├── InfoView.swift
├── ViewController.swift
├── Tutorial.swift
└── SphereMenu.swift
├── himbo.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
├── xcuserdata
│ └── mkida.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
└── project.pbxproj
├── .gitignore
├── README.md
├── himboTests
├── Info.plist
└── ColorigTests.swift
└── LICENSE.md
/assets/icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/assets/icon@2x.png
--------------------------------------------------------------------------------
/assets/icon@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/assets/icon@3x.png
--------------------------------------------------------------------------------
/assets/appstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/assets/appstore.png
--------------------------------------------------------------------------------
/assets/icon-ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/assets/icon-ipad.png
--------------------------------------------------------------------------------
/assets/appstore@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/assets/appstore@2x.png
--------------------------------------------------------------------------------
/assets/icon-ipad@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/assets/icon-ipad@2x.png
--------------------------------------------------------------------------------
/assets/icon-ipad-pro@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/assets/icon-ipad-pro@2x.png
--------------------------------------------------------------------------------
/assets/icon-settings@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/assets/icon-settings@2x.png
--------------------------------------------------------------------------------
/assets/icon-settings@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/assets/icon-settings@3x.png
--------------------------------------------------------------------------------
/assets/icon-spotlight@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/assets/icon-spotlight@2x.png
--------------------------------------------------------------------------------
/assets/icon-spotlight@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/assets/icon-spotlight@3x.png
--------------------------------------------------------------------------------
/assets/icon-ipad-settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/assets/icon-ipad-settings.png
--------------------------------------------------------------------------------
/assets/icon-ipad-spotlight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/assets/icon-ipad-spotlight.png
--------------------------------------------------------------------------------
/assets/icon-ipad-settings@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/assets/icon-ipad-settings@2x.png
--------------------------------------------------------------------------------
/assets/icon-ipad-spotlight@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/assets/icon-ipad-spotlight@2x.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/AppIcon.appiconset/appstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/AppIcon.appiconset/appstore.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/AppIcon.appiconset/icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/AppIcon.appiconset/icon@2x.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/AppIcon.appiconset/icon@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/AppIcon.appiconset/icon@3x.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/AppIcon.appiconset/icon-ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/AppIcon.appiconset/icon-ipad.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/AppIcon.appiconset/icon-ipad@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/AppIcon.appiconset/icon-ipad@2x.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/icon-close.imageset/icon-close@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/icon-close.imageset/icon-close@2x.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/icon-email.imageset/icon-email@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/icon-email.imageset/icon-email@2x.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/icon-share.imageset/icon-share@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/icon-share.imageset/icon-share@2x.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/AppIcon.appiconset/icon-ipad-pro@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/AppIcon.appiconset/icon-ipad-pro@2x.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/AppIcon.appiconset/icon-ipad-settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/AppIcon.appiconset/icon-ipad-settings.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/AppIcon.appiconset/icon-settings@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/AppIcon.appiconset/icon-settings@2x.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/AppIcon.appiconset/icon-settings@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/AppIcon.appiconset/icon-settings@3x.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/AppIcon.appiconset/icon-spotlight@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/AppIcon.appiconset/icon-spotlight@2x.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/AppIcon.appiconset/icon-spotlight@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/AppIcon.appiconset/icon-spotlight@3x.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/icon-gallery.imageset/icon-gallery@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/icon-gallery.imageset/icon-gallery@2x.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/icon-twitter.imageset/icon-twitter@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/icon-twitter.imageset/icon-twitter@2x.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/AppIcon.appiconset/icon-ipad-spotlight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/AppIcon.appiconset/icon-ipad-spotlight.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/icon-facebook.imageset/icon-facebook@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/icon-facebook.imageset/icon-facebook@2x.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/AppIcon.appiconset/icon-ipad-settings@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/AppIcon.appiconset/icon-ipad-settings@2x.png
--------------------------------------------------------------------------------
/himbo/Images.xcassets/AppIcon.appiconset/icon-ipad-spotlight@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kimar/Himbo/HEAD/himbo/Images.xcassets/AppIcon.appiconset/icon-ipad-spotlight@2x.png
--------------------------------------------------------------------------------
/himbo/himbo.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/himbo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | */build/*
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | profile
14 | *.moved-aside
15 | DerivedData
16 | .idea/
17 | *.hmap
18 | *.xccheckout
19 |
20 | #CocoaPods
21 | Pods
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Himbo
2 |
3 | ```text
4 | In need for a new Wallpaper?
5 | Tired of all the overloaded, distracting ones?
6 |
7 | Make yourself a new, single-color one in seconds.
8 | ```
9 |
10 | Get it in the [App Store](https://itunes.apple.com/us/app/himbo/id946738439?ls=1&mt=8) and check it out.
11 |
12 | * Written in Swift 1.x and migrated to Swift 2.x, Swift 3.x and Swift 4
13 | * Supports 3D Touch (if available)
14 | * MIT License
15 |
--------------------------------------------------------------------------------
/himbo/Images.xcassets/icon-close.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "icon-close@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/himbo/Images.xcassets/icon-email.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "icon-email@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/himbo/Images.xcassets/icon-share.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "icon-share@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/himbo/Images.xcassets/icon-facebook.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "icon-facebook@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/himbo/Images.xcassets/icon-gallery.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "icon-gallery@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/himbo/Images.xcassets/icon-twitter.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x",
10 | "filename" : "icon-twitter@2x.png"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/himbo/Colors.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Colors.swift
3 | // himbo
4 | //
5 | // Created by Marcus Kida on 30/11/2014.
6 | // Copyright (c) 2014 Marcus Kida. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIColor {
12 | class func himboRed() -> UIColor {
13 | // return UIColor(hue: 0.95, saturation: 0.9, brightness: 0.8, alpha: 1.0)
14 | return UIColor(red: 234.0/255.0, green: 84.0/255.0, blue: 122.0/255.0, alpha: 1.0)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/himbo.xcodeproj/xcuserdata/mkida.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | himbo.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | EC1AEC621A1C6B4A00D1FA48
16 |
17 | primary
18 |
19 |
20 | EC1AEC771A1C6B4A00D1FA48
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/himboTests/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 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/himboTests/ColorigTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ColorigTests.swift
3 | // ColorigTests
4 | //
5 | // Created by Marcus Kida on 19/11/2014.
6 | // Copyright (c) 2014 Marcus Kida. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import XCTest
11 |
12 | class ColorigTests: 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.md:
--------------------------------------------------------------------------------
1 | **The MIT License (MIT)**
2 |
3 | Copyright (c) 2014 - 2015 by Marcus Kida
4 |
5 | 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:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | 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.
--------------------------------------------------------------------------------
/himbo/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/himbo/ShakeView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ShakeView.swift
3 | // himbo
4 | //
5 | // Created by Marcus Kida on 29/11/2014.
6 | // Copyright (c) 2014 Marcus Kida. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | enum ShakeDirection {
12 | case Horizontal, Vertical
13 | }
14 |
15 | extension UIView {
16 | func shake(times: Int, direction: ShakeDirection) {
17 | shake(times: times, iteration: 0, direction: 1, shakeDirection: direction, delta: 10, speed: 0.08)
18 | }
19 | private func shake(times: Int, iteration: Int, direction: CGFloat, shakeDirection: ShakeDirection, delta: CGFloat, speed: TimeInterval) {
20 | UIView.animate(withDuration: speed, animations: { () -> Void in
21 | self.layer.setAffineTransform((shakeDirection == ShakeDirection.Horizontal) ? CGAffineTransform(translationX: delta * direction, y: 0) : CGAffineTransform(translationX: 0, y: delta * direction))
22 | }) { (finished: Bool) -> Void in
23 | if iteration >= times {
24 | UIView.animate(withDuration: speed, animations: { () -> Void in
25 | self.layer.setAffineTransform(CGAffineTransform.identity)
26 | })
27 | return
28 | }
29 | self.shake(times: (times - 1), iteration: (iteration + 1), direction: (direction * -1), shakeDirection: shakeDirection, delta: delta, speed: speed)
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/himbo/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.2.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 7
23 | LSRequiresIPhoneOS
24 |
25 | NSPhotoLibraryAddUsageDescription
26 | Himbo needs access to your Photo Library to store the Wallpaper there. None of your exiting photos are being accessed.
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | UIStatusBarHidden
36 |
37 | UISupportedInterfaceOrientations
38 |
39 | UIInterfaceOrientationPortrait
40 |
41 | UISupportedInterfaceOrientations~ipad
42 |
43 | UIInterfaceOrientationPortrait
44 | UIInterfaceOrientationPortraitUpsideDown
45 | UIInterfaceOrientationLandscapeLeft
46 | UIInterfaceOrientationLandscapeRight
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/himbo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Colorig
4 | //
5 | // Created by Marcus Kida on 19/11/2014.
6 | // Copyright (c) 2014 Marcus Kida. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | private func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // 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.
24 | // 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.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // 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.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // 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.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // 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.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/himbo/Images.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 | "size" : "29x29",
15 | "idiom" : "iphone",
16 | "filename" : "icon-settings@2x.png",
17 | "scale" : "2x"
18 | },
19 | {
20 | "size" : "29x29",
21 | "idiom" : "iphone",
22 | "filename" : "icon-settings@3x.png",
23 | "scale" : "3x"
24 | },
25 | {
26 | "size" : "40x40",
27 | "idiom" : "iphone",
28 | "filename" : "icon-spotlight@2x.png",
29 | "scale" : "2x"
30 | },
31 | {
32 | "size" : "40x40",
33 | "idiom" : "iphone",
34 | "filename" : "icon-spotlight@3x.png",
35 | "scale" : "3x"
36 | },
37 | {
38 | "size" : "60x60",
39 | "idiom" : "iphone",
40 | "filename" : "icon@2x.png",
41 | "scale" : "2x"
42 | },
43 | {
44 | "size" : "60x60",
45 | "idiom" : "iphone",
46 | "filename" : "icon@3x.png",
47 | "scale" : "3x"
48 | },
49 | {
50 | "idiom" : "ipad",
51 | "size" : "20x20",
52 | "scale" : "1x"
53 | },
54 | {
55 | "idiom" : "ipad",
56 | "size" : "20x20",
57 | "scale" : "2x"
58 | },
59 | {
60 | "size" : "29x29",
61 | "idiom" : "ipad",
62 | "filename" : "icon-ipad-settings.png",
63 | "scale" : "1x"
64 | },
65 | {
66 | "size" : "29x29",
67 | "idiom" : "ipad",
68 | "filename" : "icon-ipad-settings@2x.png",
69 | "scale" : "2x"
70 | },
71 | {
72 | "size" : "40x40",
73 | "idiom" : "ipad",
74 | "filename" : "icon-ipad-spotlight.png",
75 | "scale" : "1x"
76 | },
77 | {
78 | "size" : "40x40",
79 | "idiom" : "ipad",
80 | "filename" : "icon-ipad-spotlight@2x.png",
81 | "scale" : "2x"
82 | },
83 | {
84 | "size" : "76x76",
85 | "idiom" : "ipad",
86 | "filename" : "icon-ipad.png",
87 | "scale" : "1x"
88 | },
89 | {
90 | "size" : "76x76",
91 | "idiom" : "ipad",
92 | "filename" : "icon-ipad@2x.png",
93 | "scale" : "2x"
94 | },
95 | {
96 | "size" : "83.5x83.5",
97 | "idiom" : "ipad",
98 | "filename" : "icon-ipad-pro@2x.png",
99 | "scale" : "2x"
100 | },
101 | {
102 | "size" : "1024x1024",
103 | "idiom" : "ios-marketing",
104 | "filename" : "appstore.png",
105 | "scale" : "1x"
106 | }
107 | ],
108 | "info" : {
109 | "version" : 1,
110 | "author" : "xcode"
111 | }
112 | }
--------------------------------------------------------------------------------
/himbo/Exporter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Exporter.swift
3 | // himbo
4 | //
5 | // Created by Marcus Kida on 27/09/2015.
6 | // Copyright © 2015 Marcus Kida. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import AssetsLibrary
11 |
12 | public struct Exporter {
13 |
14 | let view: UIView
15 | let flashView: UIView
16 |
17 | init(view: UIView, flashView: UIView) {
18 | self.view = view
19 | self.flashView = flashView
20 | }
21 |
22 | func temporaryBackground() -> URL? {
23 | let image = self.renderedImage()
24 | let url = try? FileManager.default.url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("himbo.png")
25 | guard let imageData = UIImagePNGRepresentation(image),
26 | let aUrl = url
27 | else {
28 | return nil
29 | }
30 | try? imageData.write(to: aUrl)
31 | return aUrl
32 | }
33 |
34 | func checkAssetsAuthorization() -> Bool {
35 | let status = ALAssetsLibrary.authorizationStatus()
36 | if status == ALAuthorizationStatus.denied {
37 | self.view.shake(times: 10, direction: ShakeDirection.Horizontal)
38 | return false
39 | }
40 | return true
41 | }
42 |
43 | public func flashView(closure: @escaping () -> Void) {
44 | self.flashView.alpha = 1.0
45 | UIView.animate(withDuration: 0.3, animations: { () -> Void in
46 | self.flashView.alpha = 0.0
47 | }, completion: { (completed: Bool) -> Void in
48 | closure()
49 | })
50 | }
51 |
52 | public func saveToLibrary() {
53 | self.flashView { () -> Void in
54 | let image = self.renderedImage()
55 | ALAssetsLibrary().writeImage(toSavedPhotosAlbum: image.cgImage, orientation: .up, completionBlock: { (url, error) in
56 | if error != nil {
57 | UIAlertView(title: "Error", message: "The Photo could not be saved.", delegate: nil, cancelButtonTitle: "OK").show()
58 | }
59 | })
60 | }
61 | }
62 |
63 | func renderedImage() -> UIImage {
64 | let bounds = UIScreen.main.bounds
65 | let scale = UIScreen.main.scale
66 | let size = CGSize(width: bounds.width * scale, height: bounds.height * scale)
67 | let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
68 | return self.imageWithColor(rect: rect, color: self.view.backgroundColor!)
69 | }
70 |
71 | func imageWithColor(rect: CGRect, color: UIColor) -> UIImage {
72 | UIGraphicsBeginImageContext(rect.size)
73 | let ctx = UIGraphicsGetCurrentContext()
74 | ctx!.setFillColor(color.cgColor)
75 | ctx!.fill(rect)
76 | let image = UIGraphicsGetImageFromCurrentImageContext()
77 | UIGraphicsEndImageContext()
78 | return image!
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/himbo/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/himbo/PulsingLayer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PulsingLayer.swift
3 | // himbo
4 | //
5 | // Created by Marcus Kida on 30/11/2014.
6 | // Copyright (c) 2014 Marcus Kida. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import QuartzCore
11 |
12 |
13 | class PulsingLayer: CALayer {
14 |
15 | var radius: CGFloat {
16 | set(r) {
17 | setupRadius(radius: r)
18 | }
19 | get {
20 | return cornerRadius
21 | }
22 | }
23 |
24 | var animationDuration: TimeInterval = 10.0
25 | var pulseInterval: TimeInterval = 3.0
26 | var pulseColor: UIColor = UIColor(red: 0.0, green: 0.478, blue: 1.0, alpha: 1.0)
27 |
28 | private var animationGroup: CAAnimationGroup!
29 |
30 | override init() {
31 | super.init()
32 |
33 | self.contentsScale = UIScreen.main.scale
34 | self.opacity = 0
35 |
36 | self.radius = 60.0
37 | self.backgroundColor = pulseColor.cgColor
38 |
39 | DispatchQueue.global().async {
40 | self.setupAnimationGroup()
41 | if self.pulseInterval != Double.infinity {
42 | DispatchQueue.main.async {
43 | self.add(self.animationGroup, forKey: "pulse")
44 | }
45 | }
46 | }
47 | }
48 |
49 | convenience init(pulseColor: UIColor) {
50 | self.init()
51 | self.pulseColor = pulseColor
52 | self.backgroundColor = self.pulseColor.cgColor
53 | }
54 |
55 | required init(coder aDecoder: NSCoder) {
56 | fatalError("init(coder:) has not been implemented")
57 | }
58 |
59 | private func setupRadius(radius: CGFloat) {
60 |
61 | let tempPos = self.position
62 | let diameter = radius * 2
63 |
64 | self.bounds = CGRect(x: 0, y: 0, width: diameter, height: diameter)
65 | self.cornerRadius = radius
66 | self.position = tempPos
67 | }
68 |
69 |
70 | private func setupAnimationGroup() {
71 | let defaultCurve = CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)
72 | self.animationGroup = CAAnimationGroup() as CAAnimationGroup
73 | self.animationGroup.duration = self.animationDuration + self.pulseInterval
74 | self.animationGroup.repeatCount = Float.infinity
75 | self.animationGroup.isRemovedOnCompletion = false
76 | self.animationGroup.timingFunction = defaultCurve
77 | self.animationGroup.animations = [scaleAnimation(), opacityAnimation()]
78 | }
79 |
80 | private func scaleAnimation() -> CABasicAnimation {
81 | let scaleAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
82 | scaleAnimation.fromValue = 0.0
83 | scaleAnimation.toValue = 1.0
84 | scaleAnimation.duration = self.animationDuration
85 | return scaleAnimation
86 | }
87 |
88 | private func opacityAnimation() -> CAKeyframeAnimation {
89 | let opacityAnimation = CAKeyframeAnimation(keyPath: "opacity")
90 | opacityAnimation.duration = self.animationDuration
91 | opacityAnimation.values = [0.45, 0.45, 0]
92 | opacityAnimation.keyTimes = [0, 0.2, 1]
93 | opacityAnimation.isRemovedOnCompletion = false
94 | return opacityAnimation;
95 | }
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/himbo/InfoView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InfoView.swift
3 | // himbo
4 | //
5 | // Created by Marcus Kida on 30/11/2014.
6 | // Copyright (c) 2014 Marcus Kida. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class InfoView: UIView {
12 |
13 | private let kPadding: CGFloat = 50.0
14 | private let kInfoPadding: CGFloat = 10.0
15 |
16 | private var parentView: UIView!
17 | private var infoView: UIView!
18 | private var infoLabel: UILabel!
19 |
20 | private var onHide: (() -> Void)?
21 | private var tapGesture: UITapGestureRecognizer?
22 |
23 | private var haloLayer: PulsingLayer!
24 |
25 | // UIKitDynamics
26 | var gravity: UIGravityBehavior!
27 | var animator: UIDynamicAnimator!
28 |
29 | convenience init(text: String, parentView: UIView) {
30 | self.init(frame: parentView.frame)
31 |
32 | self.parentView = parentView
33 |
34 | self.backgroundColor = UIColor.himboRed()
35 | self.alpha = 0.0
36 |
37 | let width = parentView.frame.width - (kPadding * 2)
38 | let center = CGPoint(x: self.parentView.frame.width/2, y: self.parentView.frame.height/2)
39 |
40 | self.infoView = UIView(frame: CGRect(x: kPadding, y: kPadding, width: width, height: width))
41 | self.infoView.backgroundColor = UIColor.white
42 | self.infoView.layer.cornerRadius = self.infoView.frame.height / 2
43 | self.infoView.center = center
44 |
45 | self.infoLabel = UILabel(frame: CGRect(x: kInfoPadding, y: kInfoPadding, width: self.infoView.frame.width - (kInfoPadding * 2), height: self.infoView.frame.height - (kInfoPadding * 2)))
46 | self.infoLabel.text = text
47 | self.infoLabel.textColor = UIColor.himboRed()
48 | self.infoLabel.numberOfLines = 0
49 | self.infoLabel.textAlignment = NSTextAlignment.center
50 | self.infoLabel.font = UIFont.boldSystemFont(ofSize: 32.0)
51 | self.infoView.addSubview(self.infoLabel)
52 |
53 | self.animator = UIDynamicAnimator(referenceView: self)
54 | self.gravity = UIGravityBehavior(items: [self.infoView])
55 |
56 | // Halo
57 | haloLayer = PulsingLayer(pulseColor: UIColor(white: 1.0, alpha: 1.0))
58 | haloLayer.radius = self.infoView.frame.size.width
59 | haloLayer.animationDuration = 5
60 | haloLayer.pulseInterval = 0
61 | haloLayer.position = CGPoint(x: self.infoView.frame.width/2, y: self.infoView.frame.height/2)
62 | self.infoView.layer.addSublayer(haloLayer)
63 |
64 | self.tapGesture = UITapGestureRecognizer(target: self, action: #selector(InfoView.tap(tapGestureRecognizer:)))
65 | self.addGestureRecognizer(self.tapGesture!)
66 |
67 | self.addSubview(infoView)
68 | }
69 |
70 | override init(frame: CGRect) {
71 | super.init(frame: frame)
72 | }
73 |
74 | required init?(coder aDecoder: NSCoder) {
75 | fatalError("init(coder:) has not been implemented")
76 | }
77 |
78 | func show(onHide: @escaping () -> Void) {
79 | self.onHide = onHide;
80 | self.parentView.addSubview(self)
81 | UIView.animate(withDuration: 0.3, animations: { () -> Void in
82 | self.alpha = 1.0
83 | })
84 | }
85 |
86 | func hide() {
87 | self.animator.addBehavior(self.gravity)
88 | UIView.animate(withDuration: 0.8, animations: { () -> Void in
89 | self.alpha = 0.0
90 | }, completion: { (finished: Bool) -> Void in
91 | self.removeFromSuperview()
92 | self.onHide?();
93 | })
94 | }
95 |
96 | @objc func tap(tapGestureRecognizer: UITapGestureRecognizer) {
97 | self.hide()
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/himbo/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // Colorig
4 | //
5 | // Created by Marcus Kida on 19/11/2014.
6 | // Copyright (c) 2014 Marcus Kida. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | typealias computedValues = (hue: CGFloat, saturation: CGFloat, brightness: CGFloat)
12 |
13 | class ViewController: UIViewController, SphereMenuDelegate {
14 |
15 | @IBOutlet weak var flashView: UIView!
16 |
17 | let defaults = UserDefaults.standard
18 |
19 | var doubleTap: UITapGestureRecognizer?
20 | var lastHue: CGFloat = 0.0
21 | var lastSaturation: CGFloat = 0.0
22 | var lastBrightness: CGFloat = 1.0
23 | var lastTouchPoint: CGPoint?
24 |
25 | var infoVisible: Bool = false
26 | var tutorialRunning: Bool = false
27 |
28 | var theTutorial: Tutorial?
29 | var sphereMenu: SphereMenu?
30 | var infoView: InfoView?
31 | var exporter: Exporter?
32 |
33 | override func viewDidLoad() {
34 | super.viewDidLoad()
35 | exporter = Exporter(view: self.view, flashView: self.flashView)
36 |
37 | doubleTap = UITapGestureRecognizer(target: self, action: #selector(ViewController.doubleTap(gestureRecognizer:)))
38 | doubleTap!.numberOfTapsRequired = 2
39 | self.view.addGestureRecognizer(doubleTap!)
40 |
41 | let images: [UIImage] = [UIImage(named: "icon-share")!, UIImage(named: "icon-facebook")!, UIImage(named: "icon-twitter")!, UIImage(named: "icon-email")!, UIImage(named: "icon-gallery")!]
42 | sphereMenu = SphereMenu(startPoint: CGPoint(x: self.view.frame.width / 2, y: self.view.frame.height / 2), submenuImages: images)
43 | sphereMenu?.delegate = self
44 | self.view.addSubview(sphereMenu!)
45 | }
46 |
47 | override func viewDidAppear(_ animated: Bool) {
48 | super.viewDidAppear(animated)
49 | if self.defaults.bool(forKey: "tutorial_shown") {
50 | self.updateColor(vals: (hue: 0.95, saturation: 0.8, brightness: 0.9))
51 | return;
52 | }
53 | self.showInfo();
54 | }
55 |
56 | private func showInfo() {
57 | self.infoVisible = true
58 | self.infoView = nil;
59 | self.infoView = InfoView(text: "Start\nTutorial", parentView: self.view)
60 | self.infoView?.show(onHide: { () -> Void in
61 | self.defaults.set(true, forKey: "tutorial_shown")
62 | self.infoVisible = false
63 | self.tutorialRunning = true
64 | self.tutorial()
65 | })
66 | }
67 |
68 | override func didReceiveMemoryWarning() {
69 | super.didReceiveMemoryWarning()
70 | // Dispose of any resources that can be recreated.
71 | }
72 |
73 | override var prefersStatusBarHidden: Bool {
74 | return true
75 | }
76 |
77 | override func touchesBegan(_ touches: Set, with event: UIEvent?) {
78 | if lastTouchPoint == nil {
79 | lastTouchPoint = touches.first?.location(in: self.view)
80 | }
81 | }
82 |
83 | override func touchesMoved(_ touches: Set, with event: UIEvent?) {
84 | if !infoVisible {
85 | updateColor(vals: colorComponents(touches: touches))
86 | lastTouchPoint = touches.first?.location(in: self.view)
87 | }
88 | }
89 |
90 | func updateColor(vals: computedValues) {
91 | self.view.backgroundColor = UIColor(hue: vals.hue, saturation: vals.saturation, brightness: vals.brightness, alpha: 1.0)
92 | }
93 |
94 | private func colorComponents (touches: Set) -> computedValues {
95 | let touch = touches.first
96 | guard let location = touch?.location(in: self.view) else {
97 | return computedValues(0,0,0)
98 | }
99 |
100 | let viewHeight = self.view.frame.height
101 | let viewWidth = self.view.frame.width
102 |
103 | func computeAttribute () -> CGFloat {
104 | return ultimateFormula(x: viewWidth, y: location.x)
105 | }
106 |
107 | // Detect significant change in up/down movement (and set hue accordingly)
108 | if let last = lastTouchPoint {
109 | if fabs(location.y - last.y) > 5 && fabs(location.y - last.y) < 100 {
110 | lastHue = ultimateFormula(x: viewHeight, y: location.y)
111 | }
112 | }
113 |
114 | // calculate S/B
115 | var classic = true
116 | var force: CGFloat = 0.0
117 | if #available(iOS 9.0, *) {
118 | if traitCollection.forceTouchCapability == .available {
119 | classic = false
120 | force = (touches.first?.force)!
121 | }
122 | }
123 |
124 | if classic {
125 | if location.y <= viewHeight / 2 {
126 | lastSaturation = computeAttribute()
127 | } else {
128 | lastBrightness = computeAttribute()
129 | }
130 | } else {
131 | lastSaturation = computeAttribute()
132 | lastBrightness = ultimateFormula(x: viewWidth, y: force * 100)
133 | }
134 |
135 | return (lastHue, lastSaturation, lastBrightness)
136 | }
137 |
138 | private func lastComponents() -> computedValues {
139 | return (lastHue, lastSaturation, lastBrightness)
140 | }
141 |
142 | private func ultimateFormula(x: CGFloat, y: CGFloat) -> CGFloat {
143 | return (1 / x) * (x - y)
144 | }
145 |
146 | @objc func doubleTap(gestureRecognizer: UITapGestureRecognizer) {
147 | guard let exporter = exporter else {
148 | //fixme: handle non existing exporter
149 | return
150 | }
151 | exporter.flashView { () -> Void in
152 | if let url = exporter.temporaryBackground() {
153 | let activity = UIActivityViewController(activityItems: [url], applicationActivities: nil)
154 | self.present(activity, animated: true, completion: nil)
155 | }
156 | }
157 | }
158 |
159 | private func toggleMenu() {
160 | if let menu = self.sphereMenu {
161 | menu.toggle()
162 | }
163 | }
164 |
165 | private func tutorial() {
166 | theTutorial = Tutorial(view: self.view)
167 | theTutorial?.start(closure: { (hue, saturation, brightness) -> Void in
168 | self.updateColor(vals: (hue: hue, saturation: saturation, brightness: brightness))
169 | }, menuToggle: { () -> Void in
170 | self.toggleMenu()
171 | }, finished: { () -> Void in
172 | self.tutorialRunning = false
173 | })
174 | }
175 |
176 | func sphereDidSelected(index: Int) {
177 | if index == 4 {
178 | guard let exporter = exporter else {
179 | // fixme: handle non existing exporter
180 | return
181 | }
182 | if !exporter.checkAssetsAuthorization() {
183 | UIAlertView(title: "Error", message: "Please go into your Device's Settings and allow Album Access for himbo. This App will only save the current Wallpaper to your Albums. No Access to this or other Photos is gained.", delegate: nil, cancelButtonTitle: "OK").show()
184 | return
185 | }
186 | exporter.saveToLibrary();
187 | }
188 | }
189 |
190 | override var canBecomeFirstResponder: Bool {
191 | return true
192 | }
193 |
194 | override func motionEnded(_ motion: UIEventSubtype, with event: UIEvent?) {
195 | if let event = event, event.subtype == UIEventSubtype.motionShake {
196 | if !infoVisible && !tutorialRunning {
197 | self.showInfo()
198 | }
199 | }
200 | }
201 | }
202 |
203 |
--------------------------------------------------------------------------------
/himbo/Tutorial.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Tutorial.swift
3 | // himbo
4 | //
5 | // Created by Marcus Kida on 30/11/2014.
6 | // Copyright (c) 2014 Marcus Kida. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | typealias aClosure = (_ hue: CGFloat, _ saturation: CGFloat, _ brightness: CGFloat) -> Void
12 |
13 | // fixme: make this a struct
14 | class Tutorial: NSObject {
15 |
16 | private var parentView: UIView!
17 | private var haloView: UIView!
18 | private var haloLayer: PulsingLayer!
19 |
20 | private let kMovementDuration = 1.5
21 | private let kTapDuration = 0.3
22 |
23 | private var menuToggle: (() -> Void)?
24 | private var finished: (() -> Void)?
25 |
26 | private var kHue: CGFloat = 0.0
27 | private var kSat: CGFloat = 0.0
28 | private var kBri: CGFloat = 0.0
29 |
30 | init(view: UIView) {
31 | super.init()
32 | self.parentView = view
33 | UIColor.himboRed().getHue(&kHue, saturation: &kSat, brightness: &kBri, alpha: nil)
34 | }
35 |
36 | func hasForceTouch () -> Bool {
37 | if #available(iOS 9, *) {
38 | if parentView.traitCollection.forceTouchCapability == .available {
39 | return true
40 | }
41 | }
42 | return false
43 | }
44 |
45 | func conditionalHue () -> CGFloat {
46 | if hasForceTouch() {
47 | return kHue
48 | }
49 | return 0.6
50 | }
51 |
52 | func start(closure: @escaping aClosure, menuToggle: @escaping () -> Void, finished: @escaping () -> Void) {
53 |
54 | self.menuToggle = menuToggle
55 | self.finished = finished
56 |
57 | haloLayer = PulsingLayer(pulseColor: UIColor(white: 1.0, alpha: 1.0))
58 | haloLayer.radius = 90.0
59 | haloLayer.animationDuration = 1
60 | haloLayer.pulseInterval = 0
61 |
62 | haloView = UIView(frame: CGRect(x: 65, y: 65, width: 50, height: 50))
63 | haloLayer.position = CGPoint(x: haloView.frame.height/2, y: haloView.frame.width/2)
64 | haloView.layer.addSublayer(haloLayer)
65 |
66 | haloView.backgroundColor = .white
67 | haloView.layer.cornerRadius = haloView.frame.height / 2
68 |
69 | parentView.addSubview(haloView)
70 |
71 | // down / up
72 | UIView.animate(withDuration: kMovementDuration, animations: { () -> Void in
73 | self.haloView.transform = CGAffineTransform(translationX: 0, y: self.parentView.frame.size.height - 130)
74 | closure(0.6, self.kSat, self.kBri)
75 | }, completion: { (finished: Bool) -> Void in
76 | if self.hasForceTouch() {
77 | return self.forceTouch(closure: closure)
78 | }
79 | self.step1(closure: closure)
80 | })
81 | }
82 |
83 | // right
84 | func step1(closure: @escaping aClosure) {
85 | UIView.animate(withDuration: kMovementDuration, animations: { () -> Void in
86 | self.haloView.transform = CGAffineTransform(translationX: self.parentView.frame.size.width - 130, y: self.parentView.frame.size.height - 130)
87 | closure(self.conditionalHue(), self.kSat, 0.1)
88 | }, completion: { (finished: Bool) -> Void in
89 | self.step2(closure: closure)
90 |
91 | })
92 | }
93 |
94 | // left
95 | func step2(closure: @escaping aClosure) {
96 | UIView.animate(withDuration: kMovementDuration, animations: { () -> Void in
97 | self.haloView.transform = CGAffineTransform(translationX: 0, y: self.parentView.frame.size.height - 130)
98 | closure(self.conditionalHue(), self.kSat, self.kBri)
99 | }, completion: { (finished: Bool) -> Void in
100 | self.step3(closure: closure)
101 | })
102 | }
103 |
104 | // right (saturation)
105 | func step3(closure: @escaping aClosure) {
106 | self.haloView.transform = CGAffineTransform.identity
107 | UIView.animate(withDuration: kMovementDuration, animations: { () -> Void in
108 | self.haloView.transform = CGAffineTransform(translationX: self.parentView.frame.size.width - 130, y: 0)
109 | closure(self.conditionalHue(), 0.1, self.kBri)
110 | }, completion: { (finished: Bool) -> Void in
111 | self.step4(closure: closure)
112 | })
113 | }
114 |
115 | // left (saturation)
116 | func step4(closure: @escaping aClosure) {
117 | UIView.animate(withDuration: kMovementDuration, animations: { () -> Void in
118 | self.haloView.transform = CGAffineTransform.identity
119 | closure(self.conditionalHue(), self.kSat, self.kBri)
120 | }, completion: { (finished: Bool) -> Void in
121 | self.step5(closure: closure)
122 | })
123 | }
124 |
125 | func forceTouch(closure: @escaping aClosure) {
126 | UIView.animate(withDuration: kMovementDuration, animations: { () -> Void in
127 | self.haloView.transform = CGAffineTransform.identity
128 | closure(self.kHue, self.kSat, self.kBri)
129 | }, completion: { (finished: Bool) -> Void in
130 | UIView.animate(withDuration: self.kMovementDuration, animations: { () -> Void in
131 | self.haloView.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
132 | closure(self.kHue, self.kSat, 0.1)
133 | }, completion: { (finished: Bool) -> Void in
134 | UIView.animate(withDuration: self.kMovementDuration, animations: { () -> Void in
135 | self.haloView.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
136 | closure(self.kHue, self.kSat, self.kBri)
137 | }, completion: { (finished: Bool) -> Void in
138 | self.step3(closure: closure)
139 | })
140 | })
141 |
142 | })
143 | }
144 |
145 | // Move to center and do double tap
146 | func step5(closure: @escaping aClosure) {
147 | self.haloView.center = CGPoint(x: self.parentView.frame.width / 2, y: self.parentView.frame.height / 2)
148 | UIView.animate(withDuration: kMovementDuration) {
149 | self.stepTap(closure: closure, done: { step2 in
150 | self.stepTap(closure: step2, done: { step3 in
151 | self.step7(closure: step3)
152 | })
153 | })
154 | }
155 | }
156 |
157 | // Tap
158 | func stepTap(closure: @escaping aClosure, done: @escaping (_ doneClosure: @escaping aClosure) -> Void) {
159 | UIView.animate(withDuration: kTapDuration, animations: { () -> Void in
160 | self.haloView.transform = CGAffineTransform(scaleX: 2.0, y: 2.0)
161 | }, completion: { (finished: Bool) -> Void in
162 | UIView.animate(withDuration: self.kTapDuration, animations: { () -> Void in
163 | self.haloView.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
164 | }, completion: { (finished: Bool) -> Void in
165 | done(closure)
166 | })
167 | })
168 | }
169 |
170 | func step7(closure: @escaping aClosure) {
171 | self.menuToggle?()
172 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2.5) {
173 | self.stepTap(closure: closure, done: { (doneClosure) -> Void in
174 | self.stepTap(closure: closure, done: { (doneClosure) -> Void in
175 | self.step8(closure: closure)
176 | })
177 | })
178 | }
179 | }
180 |
181 | func step8(closure: aClosure) {
182 | self.menuToggle?()
183 | self.step9(closure: closure)
184 | }
185 |
186 | // Remove haloView, end Tutorial
187 | func step9(closure: aClosure) {
188 | self.haloView.removeFromSuperview()
189 | self.finished?()
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/himbo/SphereMenu.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SphereMenu.swift
3 | // Sphere Menu
4 | //
5 | // Created by Camilo Morales on 10/21/14.
6 | // Copyright (c) 2014 Camilo Morales. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | @objc protocol SphereMenuDelegate{
13 | func sphereDidSelected(index:Int)
14 | @objc optional func sphereDidOpen()
15 | @objc optional func sphereDidClose()
16 | }
17 |
18 | // fixme: make this a struct
19 | class SphereMenu:UIView, UICollisionBehaviorDelegate{
20 |
21 |
22 | let kItemInitTag:Int = 1001
23 | let kAngleOffset:CGFloat = CGFloat(Double.pi / 2) / 2.0
24 | let kSphereLength:CGFloat = 80
25 | let kSphereDamping:Float = 1.0
26 |
27 | var delegate:SphereMenuDelegate?
28 | var count:Int = 0
29 | var images:Array?
30 | var items:Array?
31 | var positions:Array?
32 |
33 | // animator and behaviors
34 | var animator:UIDynamicAnimator?
35 | var collision:UICollisionBehavior?
36 | var itemBehavior:UIDynamicItemBehavior?
37 | var snaps:Array?
38 |
39 | var bumper:UIDynamicItem?
40 | var expanded:Bool?
41 |
42 | required init(startPoint:CGPoint, submenuImages:Array){
43 | self.init()
44 | self.images = submenuImages;
45 | self.count = self.images!.count;
46 | self.center = startPoint;
47 | }
48 |
49 | required init?(coder aDecoder: NSCoder) {
50 | self.count = 0;
51 | self.images = Array()
52 | self.init()
53 | }
54 |
55 | required override init(frame: CGRect) {
56 | self.count = 0;
57 | self.images = Array()
58 | super.init(frame: frame)
59 | }
60 |
61 | override func didMoveToSuperview() {
62 | self.commonSetup()
63 | }
64 |
65 |
66 | func commonSetup()
67 | {
68 | self.items = Array()
69 | self.positions = Array()
70 | self.snaps = Array()
71 |
72 | guard let images = images else { return }
73 |
74 | var i = 0
75 | // setup the items
76 | for image in images {
77 | let item = UIImageView(image: image)
78 | item.tag = kItemInitTag + i;
79 | item.isUserInteractionEnabled = true;
80 | self.superview?.addSubview(item)
81 |
82 | let position = self.centerForSphereAtIndex(index: i)
83 | item.center = self.center;
84 | self.positions?.append(NSValue(cgPoint: position))
85 |
86 | let tap = UITapGestureRecognizer(target: self, action: #selector(SphereMenu.tapped(gesture:)))
87 | item.addGestureRecognizer(tap)
88 |
89 | // let pan = UIPanGestureRecognizer(target: self, action: "panned:")
90 | // item.addGestureRecognizer(pan)
91 |
92 | item.alpha = 0.0
93 | self.items?.append(item)
94 | i += 1
95 | }
96 |
97 | self.superview?.bringSubview(toFront: self)
98 |
99 | // setup animator and behavior
100 | self.animator = UIDynamicAnimator(referenceView: self.superview!)
101 | self.collision = UICollisionBehavior(items: self.items!)
102 | self.collision?.translatesReferenceBoundsIntoBoundary = true;
103 | self.collision?.collisionDelegate = self;
104 |
105 | guard let items = items else { return }
106 | for item in items {
107 | let snap = UISnapBehavior(item: item, snapTo: self.center)
108 | snap.damping = CGFloat(kSphereDamping)
109 | self.snaps?.append(snap)
110 | }
111 |
112 | self.itemBehavior = UIDynamicItemBehavior(items: self.items!)
113 | self.itemBehavior?.allowsRotation = false;
114 | self.itemBehavior?.elasticity = 0.25;
115 | self.itemBehavior?.density = 0.5;
116 | self.itemBehavior?.angularResistance = 4;
117 | self.itemBehavior?.resistance = 10;
118 | self.itemBehavior?.elasticity = 0.8;
119 | self.itemBehavior?.friction = 0.5;
120 | }
121 |
122 | func centerForSphereAtIndex(index:Int) -> CGPoint{
123 | let firstAngle:CGFloat = CGFloat(Double.pi) /*+ (CGFloat(M_PI_2) - kAngleOffset)*/ + CGFloat(index) * kAngleOffset
124 | let startPoint = self.center
125 | let x = startPoint.x + cos(firstAngle) * kSphereLength;
126 | let y = startPoint.y + sin(firstAngle) * kSphereLength;
127 | let position = CGPoint(x: x, y: y);
128 | return position;
129 | }
130 |
131 | func startTapped(gesture:UITapGestureRecognizer){
132 | self.animator?.removeBehavior(self.collision!)
133 | self.animator?.removeBehavior(self.itemBehavior!)
134 | toggle()
135 | }
136 |
137 | func toggle() {
138 | if (self.expanded == true) {
139 | self.shrinkSubmenu()
140 | self.delegate?.sphereDidClose?()
141 | } else {
142 | self.expandSubmenu()
143 | self.delegate?.sphereDidOpen?()
144 | }
145 | }
146 |
147 | @objc func tapped(gesture:UITapGestureRecognizer)
148 | {
149 | var tag = gesture.view?.tag
150 | tag? -= Int(kItemInitTag)
151 | self.delegate?.sphereDidSelected(index: tag!)
152 | self.shrinkSubmenu()
153 | }
154 |
155 | func panned(gesture:UIPanGestureRecognizer)
156 | {
157 | let touchedView = gesture.view;
158 | if (gesture.state == UIGestureRecognizerState.began) {
159 | self.animator?.removeBehavior(self.itemBehavior!)
160 | self.animator?.removeBehavior(self.collision!)
161 | self.removeSnapBehaviors()
162 | } else if (gesture.state == UIGestureRecognizerState.changed) {
163 | touchedView?.center = gesture.location(in: self.superview)
164 | } else if (gesture.state == UIGestureRecognizerState.ended) {
165 | self.bumper = touchedView;
166 | self.animator?.addBehavior(self.collision!)
167 | let index = self.indexOfItemInArray(dataArray: self.items!, item: touchedView!)
168 |
169 | if (index >= 0) {
170 | self.snapToPostionsWithIndex(index: index)
171 | }
172 |
173 | }
174 | }
175 |
176 | func indexOfItemInArray(dataArray:Array, item:AnyObject) -> Int{
177 | var index = -1
178 | var i = 0
179 | for thing in dataArray {
180 | if thing === item {
181 | index = i
182 | break
183 | }
184 | i += 1
185 | }
186 | return index
187 | }
188 |
189 | func shrinkSubmenu(){
190 | self.animator?.removeBehavior(self.collision!)
191 |
192 | for index in 0.. Void in
210 | item.alpha = 0.0
211 | })
212 | let snap = UISnapBehavior(item: item, snapTo: self.center)
213 | snap.damping = CGFloat(kSphereDamping)
214 | let snapToRemove = self.snaps![index];
215 | self.snaps![index] = snap;
216 | self.animator?.removeBehavior(snapToRemove)
217 | self.animator?.addBehavior(snap)
218 | }
219 |
220 | func snapToPostionsWithIndex(index:Int)
221 | {
222 | let positionValue:AnyObject = self.positions![index];
223 | let position = positionValue.cgPointValue
224 | let item = self.items![index]
225 | UIView.animate(withDuration: 0.3, animations: { () -> Void in
226 | item.alpha = 1.0
227 | })
228 | let snap = UISnapBehavior(item: item, snapTo: position!)
229 | snap.damping = CGFloat(kSphereDamping)
230 | let snapToRemove = self.snaps![index];
231 | self.snaps![index] = snap;
232 | self.animator?.removeBehavior(snapToRemove)
233 | self.animator?.addBehavior(snap)
234 | }
235 |
236 | func removeSnapBehaviors()
237 | {
238 | for index in 0...self.snaps!.count {
239 | self.animator?.removeBehavior(self.snaps![index])
240 | }
241 | }
242 |
243 | func collisionBehavior(_ behavior: UICollisionBehavior, endedContactFor item1: UIDynamicItem, with item2: UIDynamicItem) {
244 | self.animator?.addBehavior(self.itemBehavior!)
245 |
246 | if (item1 !== self.bumper){
247 | let index = self.indexOfItemInArray(dataArray: self.items!, item: item1)
248 | if (index >= 0) {
249 | self.snapToPostionsWithIndex(index: index)
250 | }
251 | }
252 |
253 | if (item2 !== self.bumper){
254 | let index = self.indexOfItemInArray(dataArray: self.items!, item: item2)
255 | if (index >= 0) {
256 | self.snapToPostionsWithIndex(index: index)
257 | }
258 | }
259 | }
260 |
261 | }
262 |
263 |
--------------------------------------------------------------------------------
/himbo.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 2A589C9F1BB793C50051FFF3 /* Exporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A589C9E1BB793C50051FFF3 /* Exporter.swift */; };
11 | EC3F24CE1A2AAA9000C58377 /* PulsingLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC3F24CD1A2AAA9000C58377 /* PulsingLayer.swift */; };
12 | EC3F24D01A2AB78E00C58377 /* Tutorial.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC3F24CF1A2AB78E00C58377 /* Tutorial.swift */; };
13 | EC3F24D21A2ABF6600C58377 /* SphereMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC3F24D11A2ABF6600C58377 /* SphereMenu.swift */; };
14 | EC3F24D41A2AEC1900C58377 /* InfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC3F24D31A2AEC1900C58377 /* InfoView.swift */; };
15 | EC3F24D61A2B125700C58377 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC3F24D51A2B125700C58377 /* Colors.swift */; };
16 | EC6165521A295B9800658455 /* AssetsLibrary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EC6165511A295B9800658455 /* AssetsLibrary.framework */; };
17 | EC61658A1A29B76B00658455 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC6165821A29B76B00658455 /* AppDelegate.swift */; };
18 | EC61658B1A29B76B00658455 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = EC6165831A29B76B00658455 /* LaunchScreen.xib */; };
19 | EC61658C1A29B76B00658455 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EC6165851A29B76B00658455 /* Main.storyboard */; };
20 | EC61658D1A29B76B00658455 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EC6165871A29B76B00658455 /* Images.xcassets */; };
21 | EC61658F1A29B76B00658455 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC6165891A29B76B00658455 /* ViewController.swift */; };
22 | EC6165931A29B77000658455 /* ColorigTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC6165911A29B77000658455 /* ColorigTests.swift */; };
23 | EC6165961A29BA6400658455 /* ShakeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC6165951A29BA6400658455 /* ShakeView.swift */; };
24 | /* End PBXBuildFile section */
25 |
26 | /* Begin PBXContainerItemProxy section */
27 | EC1AEC791A1C6B4A00D1FA48 /* PBXContainerItemProxy */ = {
28 | isa = PBXContainerItemProxy;
29 | containerPortal = EC1AEC5B1A1C6B4A00D1FA48 /* Project object */;
30 | proxyType = 1;
31 | remoteGlobalIDString = EC1AEC621A1C6B4A00D1FA48;
32 | remoteInfo = Colorig;
33 | };
34 | /* End PBXContainerItemProxy section */
35 |
36 | /* Begin PBXFileReference section */
37 | 07EC7E731FD89578005F40DA /* himbo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = himbo.entitlements; sourceTree = ""; };
38 | 0E981CFA1105CA64BCEAE9CD /* Pods-himbo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-himbo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-himbo/Pods-himbo.debug.xcconfig"; sourceTree = ""; };
39 | 2A589C9E1BB793C50051FFF3 /* Exporter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Exporter.swift; sourceTree = ""; };
40 | 49FD340327310FF0989AD5A9 /* Pods-himbo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-himbo.release.xcconfig"; path = "Pods/Target Support Files/Pods-himbo/Pods-himbo.release.xcconfig"; sourceTree = ""; };
41 | DF2C223F57198A8D1A0C9A34 /* libPods-himbo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-himbo.a"; sourceTree = BUILT_PRODUCTS_DIR; };
42 | EC1AEC631A1C6B4A00D1FA48 /* himbo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = himbo.app; sourceTree = BUILT_PRODUCTS_DIR; };
43 | EC1AEC781A1C6B4A00D1FA48 /* himboTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = himboTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
44 | EC3F24CD1A2AAA9000C58377 /* PulsingLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PulsingLayer.swift; sourceTree = ""; };
45 | EC3F24CF1A2AB78E00C58377 /* Tutorial.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tutorial.swift; sourceTree = ""; };
46 | EC3F24D11A2ABF6600C58377 /* SphereMenu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SphereMenu.swift; sourceTree = ""; };
47 | EC3F24D31A2AEC1900C58377 /* InfoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InfoView.swift; sourceTree = ""; };
48 | EC3F24D51A2B125700C58377 /* Colors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = ""; };
49 | EC6165511A295B9800658455 /* AssetsLibrary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AssetsLibrary.framework; path = System/Library/Frameworks/AssetsLibrary.framework; sourceTree = SDKROOT; };
50 | EC6165821A29B76B00658455 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
51 | EC6165841A29B76B00658455 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
52 | EC6165861A29B76B00658455 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
53 | EC6165871A29B76B00658455 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
54 | EC6165881A29B76B00658455 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
55 | EC6165891A29B76B00658455 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
56 | EC6165911A29B77000658455 /* ColorigTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorigTests.swift; sourceTree = ""; };
57 | EC6165921A29B77000658455 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
58 | EC6165951A29BA6400658455 /* ShakeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShakeView.swift; sourceTree = ""; };
59 | /* End PBXFileReference section */
60 |
61 | /* Begin PBXFrameworksBuildPhase section */
62 | EC1AEC601A1C6B4A00D1FA48 /* Frameworks */ = {
63 | isa = PBXFrameworksBuildPhase;
64 | buildActionMask = 2147483647;
65 | files = (
66 | EC6165521A295B9800658455 /* AssetsLibrary.framework in Frameworks */,
67 | );
68 | runOnlyForDeploymentPostprocessing = 0;
69 | };
70 | EC1AEC751A1C6B4A00D1FA48 /* Frameworks */ = {
71 | isa = PBXFrameworksBuildPhase;
72 | buildActionMask = 2147483647;
73 | files = (
74 | );
75 | runOnlyForDeploymentPostprocessing = 0;
76 | };
77 | /* End PBXFrameworksBuildPhase section */
78 |
79 | /* Begin PBXGroup section */
80 | 11FEA6B53EAB55CDDDED51AD /* Pods */ = {
81 | isa = PBXGroup;
82 | children = (
83 | 0E981CFA1105CA64BCEAE9CD /* Pods-himbo.debug.xcconfig */,
84 | 49FD340327310FF0989AD5A9 /* Pods-himbo.release.xcconfig */,
85 | );
86 | name = Pods;
87 | sourceTree = "";
88 | };
89 | 16326F37C70C58EECAE3587F /* Frameworks */ = {
90 | isa = PBXGroup;
91 | children = (
92 | EC6165511A295B9800658455 /* AssetsLibrary.framework */,
93 | DF2C223F57198A8D1A0C9A34 /* libPods-himbo.a */,
94 | );
95 | name = Frameworks;
96 | sourceTree = "";
97 | };
98 | EC1AEC5A1A1C6B4A00D1FA48 = {
99 | isa = PBXGroup;
100 | children = (
101 | EC6165811A29B76B00658455 /* himbo */,
102 | EC6165901A29B77000658455 /* himboTests */,
103 | EC1AEC641A1C6B4A00D1FA48 /* Products */,
104 | 11FEA6B53EAB55CDDDED51AD /* Pods */,
105 | 16326F37C70C58EECAE3587F /* Frameworks */,
106 | );
107 | sourceTree = "";
108 | };
109 | EC1AEC641A1C6B4A00D1FA48 /* Products */ = {
110 | isa = PBXGroup;
111 | children = (
112 | EC1AEC631A1C6B4A00D1FA48 /* himbo.app */,
113 | EC1AEC781A1C6B4A00D1FA48 /* himboTests.xctest */,
114 | );
115 | name = Products;
116 | sourceTree = "";
117 | };
118 | EC6165811A29B76B00658455 /* himbo */ = {
119 | isa = PBXGroup;
120 | children = (
121 | 07EC7E731FD89578005F40DA /* himbo.entitlements */,
122 | EC6165821A29B76B00658455 /* AppDelegate.swift */,
123 | EC6165891A29B76B00658455 /* ViewController.swift */,
124 | 2A589C9E1BB793C50051FFF3 /* Exporter.swift */,
125 | EC3F24CF1A2AB78E00C58377 /* Tutorial.swift */,
126 | EC6165951A29BA6400658455 /* ShakeView.swift */,
127 | EC3F24D11A2ABF6600C58377 /* SphereMenu.swift */,
128 | EC3F24CD1A2AAA9000C58377 /* PulsingLayer.swift */,
129 | EC3F24D31A2AEC1900C58377 /* InfoView.swift */,
130 | EC3F24D51A2B125700C58377 /* Colors.swift */,
131 | EC6165831A29B76B00658455 /* LaunchScreen.xib */,
132 | EC6165851A29B76B00658455 /* Main.storyboard */,
133 | EC6165871A29B76B00658455 /* Images.xcassets */,
134 | EC6165881A29B76B00658455 /* Info.plist */,
135 | );
136 | path = himbo;
137 | sourceTree = "";
138 | };
139 | EC6165901A29B77000658455 /* himboTests */ = {
140 | isa = PBXGroup;
141 | children = (
142 | EC6165911A29B77000658455 /* ColorigTests.swift */,
143 | EC6165921A29B77000658455 /* Info.plist */,
144 | );
145 | path = himboTests;
146 | sourceTree = "";
147 | };
148 | /* End PBXGroup section */
149 |
150 | /* Begin PBXNativeTarget section */
151 | EC1AEC621A1C6B4A00D1FA48 /* himbo */ = {
152 | isa = PBXNativeTarget;
153 | buildConfigurationList = EC1AEC821A1C6B4A00D1FA48 /* Build configuration list for PBXNativeTarget "himbo" */;
154 | buildPhases = (
155 | EC1AEC5F1A1C6B4A00D1FA48 /* Sources */,
156 | 07CB32C21FD8985A001647EE /* Bump Build Number */,
157 | EC1AEC601A1C6B4A00D1FA48 /* Frameworks */,
158 | EC1AEC611A1C6B4A00D1FA48 /* Resources */,
159 | );
160 | buildRules = (
161 | );
162 | dependencies = (
163 | );
164 | name = himbo;
165 | productName = Colorig;
166 | productReference = EC1AEC631A1C6B4A00D1FA48 /* himbo.app */;
167 | productType = "com.apple.product-type.application";
168 | };
169 | EC1AEC771A1C6B4A00D1FA48 /* himboTests */ = {
170 | isa = PBXNativeTarget;
171 | buildConfigurationList = EC1AEC851A1C6B4A00D1FA48 /* Build configuration list for PBXNativeTarget "himboTests" */;
172 | buildPhases = (
173 | EC1AEC741A1C6B4A00D1FA48 /* Sources */,
174 | EC1AEC751A1C6B4A00D1FA48 /* Frameworks */,
175 | EC1AEC761A1C6B4A00D1FA48 /* Resources */,
176 | );
177 | buildRules = (
178 | );
179 | dependencies = (
180 | EC1AEC7A1A1C6B4A00D1FA48 /* PBXTargetDependency */,
181 | );
182 | name = himboTests;
183 | productName = ColorigTests;
184 | productReference = EC1AEC781A1C6B4A00D1FA48 /* himboTests.xctest */;
185 | productType = "com.apple.product-type.bundle.unit-test";
186 | };
187 | /* End PBXNativeTarget section */
188 |
189 | /* Begin PBXProject section */
190 | EC1AEC5B1A1C6B4A00D1FA48 /* Project object */ = {
191 | isa = PBXProject;
192 | attributes = {
193 | LastSwiftMigration = 0700;
194 | LastSwiftUpdateCheck = 0700;
195 | LastUpgradeCheck = 0920;
196 | ORGANIZATIONNAME = "Marcus Kida";
197 | TargetAttributes = {
198 | EC1AEC621A1C6B4A00D1FA48 = {
199 | CreatedOnToolsVersion = 6.1;
200 | DevelopmentTeam = 857XYUU5FE;
201 | SystemCapabilities = {
202 | com.apple.iCloud = {
203 | enabled = 0;
204 | };
205 | };
206 | };
207 | EC1AEC771A1C6B4A00D1FA48 = {
208 | CreatedOnToolsVersion = 6.1;
209 | DevelopmentTeam = 857XYUU5FE;
210 | TestTargetID = EC1AEC621A1C6B4A00D1FA48;
211 | };
212 | };
213 | };
214 | buildConfigurationList = EC1AEC5E1A1C6B4A00D1FA48 /* Build configuration list for PBXProject "himbo" */;
215 | compatibilityVersion = "Xcode 3.2";
216 | developmentRegion = English;
217 | hasScannedForEncodings = 0;
218 | knownRegions = (
219 | en,
220 | Base,
221 | );
222 | mainGroup = EC1AEC5A1A1C6B4A00D1FA48;
223 | productRefGroup = EC1AEC641A1C6B4A00D1FA48 /* Products */;
224 | projectDirPath = "";
225 | projectRoot = "";
226 | targets = (
227 | EC1AEC621A1C6B4A00D1FA48 /* himbo */,
228 | EC1AEC771A1C6B4A00D1FA48 /* himboTests */,
229 | );
230 | };
231 | /* End PBXProject section */
232 |
233 | /* Begin PBXResourcesBuildPhase section */
234 | EC1AEC611A1C6B4A00D1FA48 /* Resources */ = {
235 | isa = PBXResourcesBuildPhase;
236 | buildActionMask = 2147483647;
237 | files = (
238 | EC61658D1A29B76B00658455 /* Images.xcassets in Resources */,
239 | EC61658B1A29B76B00658455 /* LaunchScreen.xib in Resources */,
240 | EC61658C1A29B76B00658455 /* Main.storyboard in Resources */,
241 | );
242 | runOnlyForDeploymentPostprocessing = 0;
243 | };
244 | EC1AEC761A1C6B4A00D1FA48 /* Resources */ = {
245 | isa = PBXResourcesBuildPhase;
246 | buildActionMask = 2147483647;
247 | files = (
248 | );
249 | runOnlyForDeploymentPostprocessing = 0;
250 | };
251 | /* End PBXResourcesBuildPhase section */
252 |
253 | /* Begin PBXShellScriptBuildPhase section */
254 | 07CB32C21FD8985A001647EE /* Bump Build Number */ = {
255 | isa = PBXShellScriptBuildPhase;
256 | buildActionMask = 2147483647;
257 | files = (
258 | );
259 | inputPaths = (
260 | );
261 | name = "Bump Build Number";
262 | outputPaths = (
263 | );
264 | runOnlyForDeploymentPostprocessing = 0;
265 | shellPath = /bin/sh;
266 | shellScript = "if [ $CONFIGURATION == Release ] || [ $CONFIGURATION == TestFlight ]; then\n echo \"Bumping build number...\"\n plist=${PROJECT_DIR}/${INFOPLIST_FILE}\n\n # increment the build number (ie 115 to 116)\n buildnum=$(/usr/libexec/PlistBuddy -c \"Print CFBundleVersion\" \"${plist}\")\n if [[ \"${buildnum}\" == \"\" ]]; then\n echo \"No build number in $plist\"\n exit 2\n fi\n\n buildnum=$(expr $buildnum + 1)\n /usr/libexec/Plistbuddy -c \"Set CFBundleVersion $buildnum\" \"${plist}\"\n echo \"Bumped build number to $buildnum\"\nelse\n echo $CONFIGURATION \" build - Not bumping build number.\"\nfi";
267 | };
268 | /* End PBXShellScriptBuildPhase section */
269 |
270 | /* Begin PBXSourcesBuildPhase section */
271 | EC1AEC5F1A1C6B4A00D1FA48 /* Sources */ = {
272 | isa = PBXSourcesBuildPhase;
273 | buildActionMask = 2147483647;
274 | files = (
275 | EC3F24CE1A2AAA9000C58377 /* PulsingLayer.swift in Sources */,
276 | 2A589C9F1BB793C50051FFF3 /* Exporter.swift in Sources */,
277 | EC3F24D61A2B125700C58377 /* Colors.swift in Sources */,
278 | EC61658F1A29B76B00658455 /* ViewController.swift in Sources */,
279 | EC61658A1A29B76B00658455 /* AppDelegate.swift in Sources */,
280 | EC6165961A29BA6400658455 /* ShakeView.swift in Sources */,
281 | EC3F24D01A2AB78E00C58377 /* Tutorial.swift in Sources */,
282 | EC3F24D21A2ABF6600C58377 /* SphereMenu.swift in Sources */,
283 | EC3F24D41A2AEC1900C58377 /* InfoView.swift in Sources */,
284 | );
285 | runOnlyForDeploymentPostprocessing = 0;
286 | };
287 | EC1AEC741A1C6B4A00D1FA48 /* Sources */ = {
288 | isa = PBXSourcesBuildPhase;
289 | buildActionMask = 2147483647;
290 | files = (
291 | EC6165931A29B77000658455 /* ColorigTests.swift in Sources */,
292 | );
293 | runOnlyForDeploymentPostprocessing = 0;
294 | };
295 | /* End PBXSourcesBuildPhase section */
296 |
297 | /* Begin PBXTargetDependency section */
298 | EC1AEC7A1A1C6B4A00D1FA48 /* PBXTargetDependency */ = {
299 | isa = PBXTargetDependency;
300 | target = EC1AEC621A1C6B4A00D1FA48 /* himbo */;
301 | targetProxy = EC1AEC791A1C6B4A00D1FA48 /* PBXContainerItemProxy */;
302 | };
303 | /* End PBXTargetDependency section */
304 |
305 | /* Begin PBXVariantGroup section */
306 | EC6165831A29B76B00658455 /* LaunchScreen.xib */ = {
307 | isa = PBXVariantGroup;
308 | children = (
309 | EC6165841A29B76B00658455 /* Base */,
310 | );
311 | name = LaunchScreen.xib;
312 | sourceTree = "";
313 | };
314 | EC6165851A29B76B00658455 /* Main.storyboard */ = {
315 | isa = PBXVariantGroup;
316 | children = (
317 | EC6165861A29B76B00658455 /* Base */,
318 | );
319 | name = Main.storyboard;
320 | sourceTree = "";
321 | };
322 | /* End PBXVariantGroup section */
323 |
324 | /* Begin XCBuildConfiguration section */
325 | EC1AEC801A1C6B4A00D1FA48 /* Debug */ = {
326 | isa = XCBuildConfiguration;
327 | buildSettings = {
328 | ALWAYS_SEARCH_USER_PATHS = NO;
329 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
330 | CLANG_CXX_LIBRARY = "libc++";
331 | CLANG_ENABLE_MODULES = YES;
332 | CLANG_ENABLE_OBJC_ARC = YES;
333 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
334 | CLANG_WARN_BOOL_CONVERSION = YES;
335 | CLANG_WARN_COMMA = YES;
336 | CLANG_WARN_CONSTANT_CONVERSION = YES;
337 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
338 | CLANG_WARN_EMPTY_BODY = YES;
339 | CLANG_WARN_ENUM_CONVERSION = YES;
340 | CLANG_WARN_INFINITE_RECURSION = YES;
341 | CLANG_WARN_INT_CONVERSION = YES;
342 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
343 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
344 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
345 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
346 | CLANG_WARN_STRICT_PROTOTYPES = YES;
347 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
348 | CLANG_WARN_UNREACHABLE_CODE = YES;
349 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
350 | CODE_SIGN_IDENTITY = "iPhone Developer";
351 | COPY_PHASE_STRIP = NO;
352 | DEVELOPMENT_TEAM = 857XYUU5FE;
353 | ENABLE_STRICT_OBJC_MSGSEND = YES;
354 | ENABLE_TESTABILITY = YES;
355 | GCC_C_LANGUAGE_STANDARD = gnu99;
356 | GCC_DYNAMIC_NO_PIC = NO;
357 | GCC_NO_COMMON_BLOCKS = YES;
358 | GCC_OPTIMIZATION_LEVEL = 0;
359 | GCC_PREPROCESSOR_DEFINITIONS = (
360 | "DEBUG=1",
361 | "$(inherited)",
362 | );
363 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
364 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
365 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
366 | GCC_WARN_UNDECLARED_SELECTOR = YES;
367 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
368 | GCC_WARN_UNUSED_FUNCTION = YES;
369 | GCC_WARN_UNUSED_VARIABLE = YES;
370 | MTL_ENABLE_DEBUG_INFO = YES;
371 | ONLY_ACTIVE_ARCH = YES;
372 | SDKROOT = iphoneos;
373 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
374 | SWIFT_VERSION = 4.0;
375 | TARGETED_DEVICE_FAMILY = "1,2";
376 | };
377 | name = Debug;
378 | };
379 | EC1AEC811A1C6B4A00D1FA48 /* Release */ = {
380 | isa = XCBuildConfiguration;
381 | buildSettings = {
382 | ALWAYS_SEARCH_USER_PATHS = NO;
383 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
384 | CLANG_CXX_LIBRARY = "libc++";
385 | CLANG_ENABLE_MODULES = YES;
386 | CLANG_ENABLE_OBJC_ARC = YES;
387 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
388 | CLANG_WARN_BOOL_CONVERSION = YES;
389 | CLANG_WARN_COMMA = YES;
390 | CLANG_WARN_CONSTANT_CONVERSION = YES;
391 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
392 | CLANG_WARN_EMPTY_BODY = YES;
393 | CLANG_WARN_ENUM_CONVERSION = YES;
394 | CLANG_WARN_INFINITE_RECURSION = YES;
395 | CLANG_WARN_INT_CONVERSION = YES;
396 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
397 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
398 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
399 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
400 | CLANG_WARN_STRICT_PROTOTYPES = YES;
401 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
402 | CLANG_WARN_UNREACHABLE_CODE = YES;
403 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
404 | CODE_SIGN_IDENTITY = "iPhone Developer";
405 | COPY_PHASE_STRIP = YES;
406 | DEVELOPMENT_TEAM = 857XYUU5FE;
407 | ENABLE_NS_ASSERTIONS = NO;
408 | ENABLE_STRICT_OBJC_MSGSEND = YES;
409 | GCC_C_LANGUAGE_STANDARD = gnu99;
410 | GCC_NO_COMMON_BLOCKS = YES;
411 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
412 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
413 | GCC_WARN_UNDECLARED_SELECTOR = YES;
414 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
415 | GCC_WARN_UNUSED_FUNCTION = YES;
416 | GCC_WARN_UNUSED_VARIABLE = YES;
417 | MTL_ENABLE_DEBUG_INFO = NO;
418 | SDKROOT = iphoneos;
419 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
420 | SWIFT_VERSION = 4.0;
421 | TARGETED_DEVICE_FAMILY = "1,2";
422 | VALIDATE_PRODUCT = YES;
423 | };
424 | name = Release;
425 | };
426 | EC1AEC831A1C6B4A00D1FA48 /* Debug */ = {
427 | isa = XCBuildConfiguration;
428 | buildSettings = {
429 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
430 | DEVELOPMENT_TEAM = 857XYUU5FE;
431 | INFOPLIST_FILE = himbo/Info.plist;
432 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
433 | PRODUCT_BUNDLE_IDENTIFIER = "io.kida.$(PRODUCT_NAME:rfc1034identifier)";
434 | PRODUCT_NAME = himbo;
435 | };
436 | name = Debug;
437 | };
438 | EC1AEC841A1C6B4A00D1FA48 /* Release */ = {
439 | isa = XCBuildConfiguration;
440 | buildSettings = {
441 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
442 | DEVELOPMENT_TEAM = 857XYUU5FE;
443 | INFOPLIST_FILE = himbo/Info.plist;
444 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
445 | PRODUCT_BUNDLE_IDENTIFIER = "io.kida.$(PRODUCT_NAME:rfc1034identifier)";
446 | PRODUCT_NAME = himbo;
447 | };
448 | name = Release;
449 | };
450 | EC1AEC861A1C6B4A00D1FA48 /* Debug */ = {
451 | isa = XCBuildConfiguration;
452 | buildSettings = {
453 | FRAMEWORK_SEARCH_PATHS = (
454 | "$(SDKROOT)/Developer/Library/Frameworks",
455 | "$(inherited)",
456 | );
457 | GCC_PREPROCESSOR_DEFINITIONS = (
458 | "DEBUG=1",
459 | "$(inherited)",
460 | );
461 | INFOPLIST_FILE = himboTests/Info.plist;
462 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
463 | PRODUCT_BUNDLE_IDENTIFIER = "io.kida.$(PRODUCT_NAME:rfc1034identifier)";
464 | PRODUCT_NAME = himboTests;
465 | };
466 | name = Debug;
467 | };
468 | EC1AEC871A1C6B4A00D1FA48 /* Release */ = {
469 | isa = XCBuildConfiguration;
470 | buildSettings = {
471 | FRAMEWORK_SEARCH_PATHS = (
472 | "$(SDKROOT)/Developer/Library/Frameworks",
473 | "$(inherited)",
474 | );
475 | INFOPLIST_FILE = himboTests/Info.plist;
476 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
477 | PRODUCT_BUNDLE_IDENTIFIER = "io.kida.$(PRODUCT_NAME:rfc1034identifier)";
478 | PRODUCT_NAME = himboTests;
479 | };
480 | name = Release;
481 | };
482 | /* End XCBuildConfiguration section */
483 |
484 | /* Begin XCConfigurationList section */
485 | EC1AEC5E1A1C6B4A00D1FA48 /* Build configuration list for PBXProject "himbo" */ = {
486 | isa = XCConfigurationList;
487 | buildConfigurations = (
488 | EC1AEC801A1C6B4A00D1FA48 /* Debug */,
489 | EC1AEC811A1C6B4A00D1FA48 /* Release */,
490 | );
491 | defaultConfigurationIsVisible = 0;
492 | defaultConfigurationName = Release;
493 | };
494 | EC1AEC821A1C6B4A00D1FA48 /* Build configuration list for PBXNativeTarget "himbo" */ = {
495 | isa = XCConfigurationList;
496 | buildConfigurations = (
497 | EC1AEC831A1C6B4A00D1FA48 /* Debug */,
498 | EC1AEC841A1C6B4A00D1FA48 /* Release */,
499 | );
500 | defaultConfigurationIsVisible = 0;
501 | defaultConfigurationName = Release;
502 | };
503 | EC1AEC851A1C6B4A00D1FA48 /* Build configuration list for PBXNativeTarget "himboTests" */ = {
504 | isa = XCConfigurationList;
505 | buildConfigurations = (
506 | EC1AEC861A1C6B4A00D1FA48 /* Debug */,
507 | EC1AEC871A1C6B4A00D1FA48 /* Release */,
508 | );
509 | defaultConfigurationIsVisible = 0;
510 | defaultConfigurationName = Release;
511 | };
512 | /* End XCConfigurationList section */
513 | };
514 | rootObject = EC1AEC5B1A1C6B4A00D1FA48 /* Project object */;
515 | }
516 |
--------------------------------------------------------------------------------