├── DemoGif.gif ├── BackMenu ├── BackMenu │ ├── Images.xcassets │ │ ├── star.imageset │ │ │ ├── star.png │ │ │ ├── star-100.png │ │ │ └── Contents.json │ │ ├── user.imageset │ │ │ ├── user.png │ │ │ ├── user-100.png │ │ │ └── Contents.json │ │ ├── setting.imageset │ │ │ ├── setting.png │ │ │ ├── settings-100.png │ │ │ └── Contents.json │ │ ├── mainView.imageset │ │ │ ├── mainView-1.png │ │ │ └── Contents.json │ │ ├── create_new_post.imageset │ │ │ ├── edit_property-50.png │ │ │ ├── edit_property-100.png │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ └── Source │ │ └── WindowExtension.swift ├── BackMenu.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── xcuserdata │ │ └── guykahlon.xcuserdatad │ │ │ └── xcschemes │ │ │ └── BackMenu.xcscheme │ └── project.pbxproj └── BackMenuTests │ ├── Info.plist │ └── BackMenuTests.swift ├── .gitignore ├── LICENSE.md └── README.md /DemoGif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuyKahlon/BackMenu/HEAD/DemoGif.gif -------------------------------------------------------------------------------- /BackMenu/BackMenu/Images.xcassets/star.imageset/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuyKahlon/BackMenu/HEAD/BackMenu/BackMenu/Images.xcassets/star.imageset/star.png -------------------------------------------------------------------------------- /BackMenu/BackMenu/Images.xcassets/user.imageset/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuyKahlon/BackMenu/HEAD/BackMenu/BackMenu/Images.xcassets/user.imageset/user.png -------------------------------------------------------------------------------- /BackMenu/BackMenu/Images.xcassets/setting.imageset/setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuyKahlon/BackMenu/HEAD/BackMenu/BackMenu/Images.xcassets/setting.imageset/setting.png -------------------------------------------------------------------------------- /BackMenu/BackMenu/Images.xcassets/star.imageset/star-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuyKahlon/BackMenu/HEAD/BackMenu/BackMenu/Images.xcassets/star.imageset/star-100.png -------------------------------------------------------------------------------- /BackMenu/BackMenu/Images.xcassets/user.imageset/user-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuyKahlon/BackMenu/HEAD/BackMenu/BackMenu/Images.xcassets/user.imageset/user-100.png -------------------------------------------------------------------------------- /BackMenu/BackMenu/Images.xcassets/mainView.imageset/mainView-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuyKahlon/BackMenu/HEAD/BackMenu/BackMenu/Images.xcassets/mainView.imageset/mainView-1.png -------------------------------------------------------------------------------- /BackMenu/BackMenu/Images.xcassets/setting.imageset/settings-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuyKahlon/BackMenu/HEAD/BackMenu/BackMenu/Images.xcassets/setting.imageset/settings-100.png -------------------------------------------------------------------------------- /BackMenu/BackMenu/Images.xcassets/create_new_post.imageset/edit_property-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuyKahlon/BackMenu/HEAD/BackMenu/BackMenu/Images.xcassets/create_new_post.imageset/edit_property-50.png -------------------------------------------------------------------------------- /BackMenu/BackMenu/Images.xcassets/create_new_post.imageset/edit_property-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuyKahlon/BackMenu/HEAD/BackMenu/BackMenu/Images.xcassets/create_new_post.imageset/edit_property-100.png -------------------------------------------------------------------------------- /BackMenu/BackMenu.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BackMenu/BackMenu/Images.xcassets/mainView.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "mainView-1.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode", 20 | "template-rendering-intent" : "original" 21 | } 22 | } -------------------------------------------------------------------------------- /BackMenu/BackMenu/Images.xcassets/star.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "star.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "star-100.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode", 21 | "template-rendering-intent" : "template" 22 | } 23 | } -------------------------------------------------------------------------------- /BackMenu/BackMenu/Images.xcassets/user.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "user.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "user-100.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode", 21 | "template-rendering-intent" : "template" 22 | } 23 | } -------------------------------------------------------------------------------- /BackMenu/BackMenu/Images.xcassets/setting.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "setting.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "settings-100.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode", 21 | "template-rendering-intent" : "template" 22 | } 23 | } -------------------------------------------------------------------------------- /BackMenu/BackMenu/Images.xcassets/create_new_post.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "edit_property-50.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "edit_property-100.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode", 21 | "template-rendering-intent" : "template" 22 | } 23 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 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 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | # Pods/ 27 | -------------------------------------------------------------------------------- /BackMenu/BackMenu/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 | } -------------------------------------------------------------------------------- /BackMenu/BackMenuTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.BackMenu.$(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 | -------------------------------------------------------------------------------- /BackMenu/BackMenuTests/BackMenuTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BackMenuTests.swift 3 | // BackMenuTests 4 | // 5 | // Created by Guy Kahlon on 1/25/15. 6 | // Copyright (c) 2015 GuyKahlon. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class BackMenuTests: 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 danielebogo 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. 10 | -------------------------------------------------------------------------------- /BackMenu/BackMenu/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.BackMenu.$(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 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UIViewControllerBasedStatusBarAppearance 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /BackMenu/BackMenu/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // BackMenu 4 | // 5 | // Created by Guy Kahlon on 1/25/15. 6 | // Copyright (c) 2015 GuyKahlon. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | var frontWindow: UIWindow? 16 | 17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 18 | 19 | let storyboard = UIStoryboard(name: "Main", bundle: nil) 20 | 21 | let front:UIViewController = storyboard.instantiateViewControllerWithIdentifier("frontViewController") as UIViewController 22 | frontWindow = UIWindow(frame: UIScreen.mainScreen().bounds) 23 | frontWindow?.rootViewController = front; 24 | frontWindow?.windowLevel = UIWindowLevelStatusBar 25 | frontWindow?.startSwipeToOpenMenu() 26 | frontWindow?.makeKeyAndVisible(); 27 | 28 | // frontWindow?.layer.masksToBounds = true 29 | // let maskPath = UIBezierPath(roundedRect: UIScreen.mainScreen().bounds, byRoundingCorners: (.TopLeft | .TopRight), cornerRadii: CGSizeMake(2.0, 2.0)) 30 | // let maskLayer = CAShapeLayer() 31 | // maskLayer.frame = UIScreen.mainScreen().bounds 32 | // maskLayer.path = maskPath.CGPath; 33 | // frontWindow?.layer.mask = maskLayer; 34 | 35 | 36 | 37 | application.setStatusBarStyle(.LightContent, animated:false) 38 | return true 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BackMenu 2 | This is a simple iOS menu control inspired by Creative Labs applications of Facebook (Paper, Slingshot, Groups). 3 | 4 | ![alt tag](https://github.com/GuyKahlon/BackMenu/blob/master/DemoGif.gif) 5 | 6 | 7 | # How To Get Started 8 | * Download BackMenu and try out the iPhone example apps. 9 | 10 | # Usage 11 | Copy the ExtensionWindow file. 12 | You should create two optional value of UIWindows in the appDelegate class. 13 | 14 | ```swift 15 | var window: UIWindow? 16 | var frontWindow: UIWindow? 17 | ``` 18 | 19 | 20 | 21 | The 'Storyboatd Entry Point' is the Back window (You can also initialize the window manually if you want). 22 | 23 | The secound window is the front window, and we initialize it menualy. 24 | For example: 25 | 26 | ```swift 27 | let front:UIViewController = storyboard.instantiateViewControllerWithIdentifier("frontViewController") as UIViewController 28 | frontWindow = UIWindow(frame: UIScreen.mainScreen().bounds) 29 | frontWindow?.rootViewController = front; 30 | ``` 31 | 32 | 33 | 34 | Three more important things: 35 | 1. Change the window Level 36 | 2. Call to: startSwipeToOpenMenu() 37 | 3. Call to: makeKeyAndVisible(); 38 | 39 | ```swift 40 | frontWindow?.windowLevel = UIWindowLevelStatusBar 41 | frontWindow?.startSwipeToOpenMenu() 42 | frontWindow?.makeKeyAndVisible(); 43 | ``` 44 | 45 | 46 | 47 | Please note: There is also the method: stopSwipeToOpenMenu() in extension UIWindow class, Call to this method when you want to disable the menu. 48 | 49 | # Contact 50 | Follow me on Twitter (@guykahlon) 51 | 52 | # License 53 | BackMenu is available under the MIT license. See the LICENSE file for more info. 54 | -------------------------------------------------------------------------------- /BackMenu/BackMenu/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 | -------------------------------------------------------------------------------- /BackMenu/BackMenu.xcodeproj/xcuserdata/guykahlon.xcuserdatad/xcschemes/BackMenu.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 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /BackMenu/BackMenu/Source/WindowExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WindowExtension.swift 3 | // BackMenu 4 | // 5 | // Created by Guy Kahlon on 1/25/15. 6 | // Copyright (c) 2015 GuyKahlon. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | private var beganOrigin = CGPoint() 12 | 13 | private let kHeaderHeight: CGFloat = 64 14 | private let kTransform: CGFloat = 0.9 15 | private let kAlphe: CGFloat = 0.4 16 | private let kAnimationDuration: NSTimeInterval = 0.3 17 | private let kstatusBarStyle = UIStatusBarStyle.LightContent 18 | 19 | var tapGesture : UITapGestureRecognizer? 20 | var panGesture : UIPanGestureRecognizer? 21 | let backWindow:UIWindow? = UIApplication.sharedApplication().delegate?.window! 22 | 23 | extension UIWindow{ 24 | 25 | func stopSwipeToOpenMenu(){ 26 | 27 | if let pan = panGesture{ 28 | removeGestureRecognizer(pan) 29 | } 30 | if let tap = tapGesture{ 31 | removeGestureRecognizer(tap) 32 | } 33 | 34 | NSNotificationCenter.defaultCenter().removeObserver(self) 35 | } 36 | 37 | func startSwipeToOpenMenu(){ 38 | 39 | panGesture = UIPanGestureRecognizer(target: self, action: "handlePanGesture:") 40 | addGestureRecognizer(panGesture!); 41 | 42 | NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil) 43 | 44 | NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil) 45 | } 46 | 47 | func handlePanGesture(panGesture : UIPanGestureRecognizer){ 48 | 49 | let translation:CGPoint = panGesture.translationInView(self); 50 | let velocity:CGPoint = panGesture.velocityInView(self) 51 | 52 | switch (panGesture.state){ 53 | 54 | case .Began: 55 | beganOrigin = frame.origin; 56 | break; 57 | case .Changed: 58 | 59 | let val = (frame.origin.y * ((1 - kTransform) / UIScreen.mainScreen().bounds.height)) + kTransform; 60 | let t1 = CATransform3DScale(CATransform3DIdentity, val , val , 1); 61 | 62 | let valAlphe = (frame.origin.y * ((1 - kAlphe) / UIScreen.mainScreen().bounds.height)) + kAlphe; 63 | 64 | if beganOrigin.y + translation.y >= -kHeaderHeight{ 65 | 66 | self.transform = CGAffineTransformMakeTranslation(0, translation.y); 67 | backWindow?.rootViewController?.view.layer.transform = t1; 68 | backWindow?.rootViewController?.view.alpha = valAlphe; 69 | } 70 | case .Ended, .Cancelled: 71 | 72 | var finalOrigin:CGPoint = CGPointZero; 73 | var finalTransform: CATransform3D = CATransform3DIdentity 74 | var alpha: CGFloat = 1.0; 75 | var statusBarStyle = kstatusBarStyle 76 | if velocity.y >= 0 { 77 | finalOrigin.y = CGRectGetHeight(UIScreen.mainScreen().bounds) - kHeaderHeight; 78 | addTapGestureToClose() 79 | } 80 | else{ 81 | finalTransform = CATransform3DScale(finalTransform, kTransform , kTransform , 1); 82 | alpha = kAlphe 83 | statusBarStyle = UIStatusBarStyle.Default 84 | removeTapGestureToClose() 85 | } 86 | 87 | var finalFrame = frame; 88 | finalFrame.origin = finalOrigin; 89 | 90 | UIView.animateWithDuration(kAnimationDuration, delay: 0.0, options: .CurveEaseOut, animations: { () -> Void in 91 | 92 | backWindow?.rootViewController?.view.layer.transform = finalTransform; 93 | backWindow?.rootViewController?.view.alpha = alpha; 94 | 95 | self.transform = CGAffineTransformIdentity; 96 | self.frame = finalFrame; 97 | UIApplication.sharedApplication().setStatusBarStyle(statusBarStyle, animated:true) 98 | }, completion: { (finished: Bool) -> Void in 99 | }) 100 | default: 101 | print("Unknown panGesture state") 102 | } 103 | } 104 | 105 | func handleTapGesture(panGesture : UIPanGestureRecognizer){ 106 | close() 107 | } 108 | 109 | func keyboardWillShow(notification: NSNotification){ 110 | hidden = true 111 | } 112 | 113 | func keyboardWillHide(notification: NSNotification){ 114 | hidden = false 115 | } 116 | 117 | // MARK: Private methids 118 | private func close(){ 119 | 120 | UIView.animateWithDuration(kAnimationDuration + 0.1, delay: 0.0, options: .CurveEaseOut, animations: { () -> Void in 121 | 122 | backWindow?.rootViewController?.view.layer.transform = CATransform3DScale(CATransform3DIdentity, kTransform , kTransform , 1); 123 | backWindow?.rootViewController?.view.alpha = kAlphe 124 | 125 | self.transform = CGAffineTransformIdentity; 126 | 127 | self.frame = UIScreen.mainScreen().bounds; 128 | }, completion: { (finished: Bool) -> Void in 129 | self.removeTapGestureToClose() 130 | }) 131 | } 132 | 133 | // MARK: Tap Gesture 134 | private func addTapGestureToClose(){ 135 | 136 | if let tap = tapGesture{ 137 | addGestureRecognizer(tap) 138 | } 139 | else{ 140 | tapGesture = UITapGestureRecognizer(target: self, action: "handleTapGesture:") 141 | addGestureRecognizer(tapGesture!) 142 | } 143 | } 144 | 145 | private func removeTapGestureToClose(){ 146 | 147 | if let tap = tapGesture{ 148 | removeGestureRecognizer(tap) 149 | } 150 | } 151 | } -------------------------------------------------------------------------------- /BackMenu/BackMenu.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 50E29E131A756BFF003AAE57 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E29E121A756BFF003AAE57 /* AppDelegate.swift */; }; 11 | 50E29E181A756BFF003AAE57 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 50E29E161A756BFF003AAE57 /* Main.storyboard */; }; 12 | 50E29E1A1A756BFF003AAE57 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 50E29E191A756BFF003AAE57 /* Images.xcassets */; }; 13 | 50E29E1D1A756BFF003AAE57 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 50E29E1B1A756BFF003AAE57 /* LaunchScreen.xib */; }; 14 | 50E29E291A756C00003AAE57 /* BackMenuTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E29E281A756C00003AAE57 /* BackMenuTests.swift */; }; 15 | 50E29E331A756D4F003AAE57 /* WindowExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E29E321A756D4F003AAE57 /* WindowExtension.swift */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXContainerItemProxy section */ 19 | 50E29E231A756C00003AAE57 /* PBXContainerItemProxy */ = { 20 | isa = PBXContainerItemProxy; 21 | containerPortal = 50E29E051A756BFF003AAE57 /* Project object */; 22 | proxyType = 1; 23 | remoteGlobalIDString = 50E29E0C1A756BFF003AAE57; 24 | remoteInfo = BackMenu; 25 | }; 26 | /* End PBXContainerItemProxy section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | 50E29E0D1A756BFF003AAE57 /* BackMenu.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BackMenu.app; sourceTree = BUILT_PRODUCTS_DIR; }; 30 | 50E29E111A756BFF003AAE57 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 31 | 50E29E121A756BFF003AAE57 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 32 | 50E29E171A756BFF003AAE57 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 33 | 50E29E191A756BFF003AAE57 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 34 | 50E29E1C1A756BFF003AAE57 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 35 | 50E29E221A756C00003AAE57 /* BackMenuTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BackMenuTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 36 | 50E29E271A756C00003AAE57 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 37 | 50E29E281A756C00003AAE57 /* BackMenuTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackMenuTests.swift; sourceTree = ""; }; 38 | 50E29E321A756D4F003AAE57 /* WindowExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WindowExtension.swift; path = BackMenu/Source/WindowExtension.swift; sourceTree = ""; }; 39 | /* End PBXFileReference section */ 40 | 41 | /* Begin PBXFrameworksBuildPhase section */ 42 | 50E29E0A1A756BFF003AAE57 /* Frameworks */ = { 43 | isa = PBXFrameworksBuildPhase; 44 | buildActionMask = 2147483647; 45 | files = ( 46 | ); 47 | runOnlyForDeploymentPostprocessing = 0; 48 | }; 49 | 50E29E1F1A756C00003AAE57 /* Frameworks */ = { 50 | isa = PBXFrameworksBuildPhase; 51 | buildActionMask = 2147483647; 52 | files = ( 53 | ); 54 | runOnlyForDeploymentPostprocessing = 0; 55 | }; 56 | /* End PBXFrameworksBuildPhase section */ 57 | 58 | /* Begin PBXGroup section */ 59 | 50E29E041A756BFF003AAE57 = { 60 | isa = PBXGroup; 61 | children = ( 62 | 50E29E321A756D4F003AAE57 /* WindowExtension.swift */, 63 | 50E29E0F1A756BFF003AAE57 /* BackMenu */, 64 | 50E29E251A756C00003AAE57 /* BackMenuTests */, 65 | 50E29E0E1A756BFF003AAE57 /* Products */, 66 | ); 67 | sourceTree = ""; 68 | }; 69 | 50E29E0E1A756BFF003AAE57 /* Products */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | 50E29E0D1A756BFF003AAE57 /* BackMenu.app */, 73 | 50E29E221A756C00003AAE57 /* BackMenuTests.xctest */, 74 | ); 75 | name = Products; 76 | sourceTree = ""; 77 | }; 78 | 50E29E0F1A756BFF003AAE57 /* BackMenu */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 50E29E121A756BFF003AAE57 /* AppDelegate.swift */, 82 | 50E29E161A756BFF003AAE57 /* Main.storyboard */, 83 | 50E29E191A756BFF003AAE57 /* Images.xcassets */, 84 | 50E29E1B1A756BFF003AAE57 /* LaunchScreen.xib */, 85 | 50E29E101A756BFF003AAE57 /* Supporting Files */, 86 | ); 87 | path = BackMenu; 88 | sourceTree = ""; 89 | }; 90 | 50E29E101A756BFF003AAE57 /* Supporting Files */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 50E29E111A756BFF003AAE57 /* Info.plist */, 94 | ); 95 | name = "Supporting Files"; 96 | sourceTree = ""; 97 | }; 98 | 50E29E251A756C00003AAE57 /* BackMenuTests */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 50E29E281A756C00003AAE57 /* BackMenuTests.swift */, 102 | 50E29E261A756C00003AAE57 /* Supporting Files */, 103 | ); 104 | path = BackMenuTests; 105 | sourceTree = ""; 106 | }; 107 | 50E29E261A756C00003AAE57 /* Supporting Files */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 50E29E271A756C00003AAE57 /* Info.plist */, 111 | ); 112 | name = "Supporting Files"; 113 | sourceTree = ""; 114 | }; 115 | /* End PBXGroup section */ 116 | 117 | /* Begin PBXNativeTarget section */ 118 | 50E29E0C1A756BFF003AAE57 /* BackMenu */ = { 119 | isa = PBXNativeTarget; 120 | buildConfigurationList = 50E29E2C1A756C00003AAE57 /* Build configuration list for PBXNativeTarget "BackMenu" */; 121 | buildPhases = ( 122 | 50E29E091A756BFF003AAE57 /* Sources */, 123 | 50E29E0A1A756BFF003AAE57 /* Frameworks */, 124 | 50E29E0B1A756BFF003AAE57 /* Resources */, 125 | ); 126 | buildRules = ( 127 | ); 128 | dependencies = ( 129 | ); 130 | name = BackMenu; 131 | productName = BackMenu; 132 | productReference = 50E29E0D1A756BFF003AAE57 /* BackMenu.app */; 133 | productType = "com.apple.product-type.application"; 134 | }; 135 | 50E29E211A756C00003AAE57 /* BackMenuTests */ = { 136 | isa = PBXNativeTarget; 137 | buildConfigurationList = 50E29E2F1A756C00003AAE57 /* Build configuration list for PBXNativeTarget "BackMenuTests" */; 138 | buildPhases = ( 139 | 50E29E1E1A756C00003AAE57 /* Sources */, 140 | 50E29E1F1A756C00003AAE57 /* Frameworks */, 141 | 50E29E201A756C00003AAE57 /* Resources */, 142 | ); 143 | buildRules = ( 144 | ); 145 | dependencies = ( 146 | 50E29E241A756C00003AAE57 /* PBXTargetDependency */, 147 | ); 148 | name = BackMenuTests; 149 | productName = BackMenuTests; 150 | productReference = 50E29E221A756C00003AAE57 /* BackMenuTests.xctest */; 151 | productType = "com.apple.product-type.bundle.unit-test"; 152 | }; 153 | /* End PBXNativeTarget section */ 154 | 155 | /* Begin PBXProject section */ 156 | 50E29E051A756BFF003AAE57 /* Project object */ = { 157 | isa = PBXProject; 158 | attributes = { 159 | LastSwiftMigration = 0700; 160 | LastSwiftUpdateCheck = 0700; 161 | LastUpgradeCheck = 0620; 162 | ORGANIZATIONNAME = GuyKahlon; 163 | TargetAttributes = { 164 | 50E29E0C1A756BFF003AAE57 = { 165 | CreatedOnToolsVersion = 6.2; 166 | }; 167 | 50E29E211A756C00003AAE57 = { 168 | CreatedOnToolsVersion = 6.2; 169 | TestTargetID = 50E29E0C1A756BFF003AAE57; 170 | }; 171 | }; 172 | }; 173 | buildConfigurationList = 50E29E081A756BFF003AAE57 /* Build configuration list for PBXProject "BackMenu" */; 174 | compatibilityVersion = "Xcode 3.2"; 175 | developmentRegion = English; 176 | hasScannedForEncodings = 0; 177 | knownRegions = ( 178 | en, 179 | Base, 180 | ); 181 | mainGroup = 50E29E041A756BFF003AAE57; 182 | productRefGroup = 50E29E0E1A756BFF003AAE57 /* Products */; 183 | projectDirPath = ""; 184 | projectRoot = ""; 185 | targets = ( 186 | 50E29E0C1A756BFF003AAE57 /* BackMenu */, 187 | 50E29E211A756C00003AAE57 /* BackMenuTests */, 188 | ); 189 | }; 190 | /* End PBXProject section */ 191 | 192 | /* Begin PBXResourcesBuildPhase section */ 193 | 50E29E0B1A756BFF003AAE57 /* Resources */ = { 194 | isa = PBXResourcesBuildPhase; 195 | buildActionMask = 2147483647; 196 | files = ( 197 | 50E29E181A756BFF003AAE57 /* Main.storyboard in Resources */, 198 | 50E29E1D1A756BFF003AAE57 /* LaunchScreen.xib in Resources */, 199 | 50E29E1A1A756BFF003AAE57 /* Images.xcassets in Resources */, 200 | ); 201 | runOnlyForDeploymentPostprocessing = 0; 202 | }; 203 | 50E29E201A756C00003AAE57 /* Resources */ = { 204 | isa = PBXResourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | ); 208 | runOnlyForDeploymentPostprocessing = 0; 209 | }; 210 | /* End PBXResourcesBuildPhase section */ 211 | 212 | /* Begin PBXSourcesBuildPhase section */ 213 | 50E29E091A756BFF003AAE57 /* Sources */ = { 214 | isa = PBXSourcesBuildPhase; 215 | buildActionMask = 2147483647; 216 | files = ( 217 | 50E29E131A756BFF003AAE57 /* AppDelegate.swift in Sources */, 218 | 50E29E331A756D4F003AAE57 /* WindowExtension.swift in Sources */, 219 | ); 220 | runOnlyForDeploymentPostprocessing = 0; 221 | }; 222 | 50E29E1E1A756C00003AAE57 /* Sources */ = { 223 | isa = PBXSourcesBuildPhase; 224 | buildActionMask = 2147483647; 225 | files = ( 226 | 50E29E291A756C00003AAE57 /* BackMenuTests.swift in Sources */, 227 | ); 228 | runOnlyForDeploymentPostprocessing = 0; 229 | }; 230 | /* End PBXSourcesBuildPhase section */ 231 | 232 | /* Begin PBXTargetDependency section */ 233 | 50E29E241A756C00003AAE57 /* PBXTargetDependency */ = { 234 | isa = PBXTargetDependency; 235 | target = 50E29E0C1A756BFF003AAE57 /* BackMenu */; 236 | targetProxy = 50E29E231A756C00003AAE57 /* PBXContainerItemProxy */; 237 | }; 238 | /* End PBXTargetDependency section */ 239 | 240 | /* Begin PBXVariantGroup section */ 241 | 50E29E161A756BFF003AAE57 /* Main.storyboard */ = { 242 | isa = PBXVariantGroup; 243 | children = ( 244 | 50E29E171A756BFF003AAE57 /* Base */, 245 | ); 246 | name = Main.storyboard; 247 | sourceTree = ""; 248 | }; 249 | 50E29E1B1A756BFF003AAE57 /* LaunchScreen.xib */ = { 250 | isa = PBXVariantGroup; 251 | children = ( 252 | 50E29E1C1A756BFF003AAE57 /* Base */, 253 | ); 254 | name = LaunchScreen.xib; 255 | sourceTree = ""; 256 | }; 257 | /* End PBXVariantGroup section */ 258 | 259 | /* Begin XCBuildConfiguration section */ 260 | 50E29E2A1A756C00003AAE57 /* Debug */ = { 261 | isa = XCBuildConfiguration; 262 | buildSettings = { 263 | ALWAYS_SEARCH_USER_PATHS = NO; 264 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 265 | CLANG_CXX_LIBRARY = "libc++"; 266 | CLANG_ENABLE_MODULES = YES; 267 | CLANG_ENABLE_OBJC_ARC = YES; 268 | CLANG_WARN_BOOL_CONVERSION = YES; 269 | CLANG_WARN_CONSTANT_CONVERSION = YES; 270 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 271 | CLANG_WARN_EMPTY_BODY = YES; 272 | CLANG_WARN_ENUM_CONVERSION = YES; 273 | CLANG_WARN_INT_CONVERSION = YES; 274 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 275 | CLANG_WARN_UNREACHABLE_CODE = YES; 276 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 277 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 278 | COPY_PHASE_STRIP = NO; 279 | ENABLE_STRICT_OBJC_MSGSEND = YES; 280 | GCC_C_LANGUAGE_STANDARD = gnu99; 281 | GCC_DYNAMIC_NO_PIC = NO; 282 | GCC_OPTIMIZATION_LEVEL = 0; 283 | GCC_PREPROCESSOR_DEFINITIONS = ( 284 | "DEBUG=1", 285 | "$(inherited)", 286 | ); 287 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 288 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 289 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 290 | GCC_WARN_UNDECLARED_SELECTOR = YES; 291 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 292 | GCC_WARN_UNUSED_FUNCTION = YES; 293 | GCC_WARN_UNUSED_VARIABLE = YES; 294 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 295 | MTL_ENABLE_DEBUG_INFO = YES; 296 | ONLY_ACTIVE_ARCH = YES; 297 | SDKROOT = iphoneos; 298 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 299 | }; 300 | name = Debug; 301 | }; 302 | 50E29E2B1A756C00003AAE57 /* Release */ = { 303 | isa = XCBuildConfiguration; 304 | buildSettings = { 305 | ALWAYS_SEARCH_USER_PATHS = NO; 306 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 307 | CLANG_CXX_LIBRARY = "libc++"; 308 | CLANG_ENABLE_MODULES = YES; 309 | CLANG_ENABLE_OBJC_ARC = YES; 310 | CLANG_WARN_BOOL_CONVERSION = YES; 311 | CLANG_WARN_CONSTANT_CONVERSION = YES; 312 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 313 | CLANG_WARN_EMPTY_BODY = YES; 314 | CLANG_WARN_ENUM_CONVERSION = YES; 315 | CLANG_WARN_INT_CONVERSION = YES; 316 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 317 | CLANG_WARN_UNREACHABLE_CODE = YES; 318 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 319 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 320 | COPY_PHASE_STRIP = NO; 321 | ENABLE_NS_ASSERTIONS = NO; 322 | ENABLE_STRICT_OBJC_MSGSEND = YES; 323 | GCC_C_LANGUAGE_STANDARD = gnu99; 324 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 325 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 326 | GCC_WARN_UNDECLARED_SELECTOR = YES; 327 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 328 | GCC_WARN_UNUSED_FUNCTION = YES; 329 | GCC_WARN_UNUSED_VARIABLE = YES; 330 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 331 | MTL_ENABLE_DEBUG_INFO = NO; 332 | SDKROOT = iphoneos; 333 | VALIDATE_PRODUCT = YES; 334 | }; 335 | name = Release; 336 | }; 337 | 50E29E2D1A756C00003AAE57 /* Debug */ = { 338 | isa = XCBuildConfiguration; 339 | buildSettings = { 340 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 341 | INFOPLIST_FILE = BackMenu/Info.plist; 342 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 343 | PRODUCT_NAME = "$(TARGET_NAME)"; 344 | }; 345 | name = Debug; 346 | }; 347 | 50E29E2E1A756C00003AAE57 /* Release */ = { 348 | isa = XCBuildConfiguration; 349 | buildSettings = { 350 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 351 | INFOPLIST_FILE = BackMenu/Info.plist; 352 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 353 | PRODUCT_NAME = "$(TARGET_NAME)"; 354 | }; 355 | name = Release; 356 | }; 357 | 50E29E301A756C00003AAE57 /* Debug */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | BUNDLE_LOADER = "$(TEST_HOST)"; 361 | FRAMEWORK_SEARCH_PATHS = ( 362 | "$(SDKROOT)/Developer/Library/Frameworks", 363 | "$(inherited)", 364 | ); 365 | GCC_PREPROCESSOR_DEFINITIONS = ( 366 | "DEBUG=1", 367 | "$(inherited)", 368 | ); 369 | INFOPLIST_FILE = BackMenuTests/Info.plist; 370 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 371 | PRODUCT_NAME = "$(TARGET_NAME)"; 372 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BackMenu.app/BackMenu"; 373 | }; 374 | name = Debug; 375 | }; 376 | 50E29E311A756C00003AAE57 /* Release */ = { 377 | isa = XCBuildConfiguration; 378 | buildSettings = { 379 | BUNDLE_LOADER = "$(TEST_HOST)"; 380 | FRAMEWORK_SEARCH_PATHS = ( 381 | "$(SDKROOT)/Developer/Library/Frameworks", 382 | "$(inherited)", 383 | ); 384 | INFOPLIST_FILE = BackMenuTests/Info.plist; 385 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 386 | PRODUCT_NAME = "$(TARGET_NAME)"; 387 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BackMenu.app/BackMenu"; 388 | }; 389 | name = Release; 390 | }; 391 | /* End XCBuildConfiguration section */ 392 | 393 | /* Begin XCConfigurationList section */ 394 | 50E29E081A756BFF003AAE57 /* Build configuration list for PBXProject "BackMenu" */ = { 395 | isa = XCConfigurationList; 396 | buildConfigurations = ( 397 | 50E29E2A1A756C00003AAE57 /* Debug */, 398 | 50E29E2B1A756C00003AAE57 /* Release */, 399 | ); 400 | defaultConfigurationIsVisible = 0; 401 | defaultConfigurationName = Release; 402 | }; 403 | 50E29E2C1A756C00003AAE57 /* Build configuration list for PBXNativeTarget "BackMenu" */ = { 404 | isa = XCConfigurationList; 405 | buildConfigurations = ( 406 | 50E29E2D1A756C00003AAE57 /* Debug */, 407 | 50E29E2E1A756C00003AAE57 /* Release */, 408 | ); 409 | defaultConfigurationIsVisible = 0; 410 | defaultConfigurationName = Release; 411 | }; 412 | 50E29E2F1A756C00003AAE57 /* Build configuration list for PBXNativeTarget "BackMenuTests" */ = { 413 | isa = XCConfigurationList; 414 | buildConfigurations = ( 415 | 50E29E301A756C00003AAE57 /* Debug */, 416 | 50E29E311A756C00003AAE57 /* Release */, 417 | ); 418 | defaultConfigurationIsVisible = 0; 419 | defaultConfigurationName = Release; 420 | }; 421 | /* End XCConfigurationList section */ 422 | }; 423 | rootObject = 50E29E051A756BFF003AAE57 /* Project object */; 424 | } 425 | -------------------------------------------------------------------------------- /BackMenu/BackMenu/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 | 45 | 46 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | --------------------------------------------------------------------------------