├── demo.gif ├── Example ├── Example │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── home.imageset │ │ │ ├── 31.png │ │ │ ├── 31@2x.png │ │ │ ├── 31@3x.png │ │ │ └── Contents.json │ │ ├── shadow.imageset │ │ │ ├── oval4.png │ │ │ ├── oval4@2x.png │ │ │ ├── oval4@3x.png │ │ │ └── Contents.json │ │ ├── profile_icon.imageset │ │ │ ├── icn4.png │ │ │ ├── icn4@2x.png │ │ │ ├── icn4@3x.png │ │ │ └── Contents.json │ │ ├── recipe_icon.imageset │ │ │ ├── icn1.png │ │ │ ├── icn1@2x.png │ │ │ ├── icn1@3x.png │ │ │ └── Contents.json │ │ ├── close_icon.imageset │ │ │ ├── closeIcn.png │ │ │ ├── closeIcn@2x.png │ │ │ ├── closeIcn@3x.png │ │ │ └── Contents.json │ │ ├── favorite_icon.imageset │ │ │ ├── icn2.png │ │ │ ├── icn2@2x.png │ │ │ ├── icn2@3x.png │ │ │ └── Contents.json │ │ ├── shoplist_icon.imageset │ │ │ ├── icn3.png │ │ │ ├── icn3@2x.png │ │ │ ├── icn3@3x.png │ │ │ └── Contents.json │ │ ├── whitecircle.imageset │ │ │ ├── icnBase.png │ │ │ ├── icnBase@2x.png │ │ │ ├── icnBase@3x.png │ │ │ └── Contents.json │ │ ├── twitter_icon.imageset │ │ │ ├── twitterIcon.png │ │ │ ├── twitterIcon@2x.png │ │ │ ├── twitterIcon@3x.png │ │ │ └── Contents.json │ │ ├── facebook_icon.imageset │ │ │ ├── facebookIcon.png │ │ │ ├── facebookIcon@2x.png │ │ │ ├── facebookIcon@3x.png │ │ │ └── Contents.json │ │ ├── hamburger_icon.imageset │ │ │ ├── menu_icn_2x.png │ │ │ ├── menu_icn_3x.png │ │ │ └── Contents.json │ │ ├── instagram_icon.imageset │ │ │ ├── instagramIcon.png │ │ │ ├── instagramIcon@2x.png │ │ │ ├── instagramIcon@3x.png │ │ │ └── Contents.json │ │ ├── tubik.imageset │ │ │ ├── tumblr_ovay9mdCdX1r2e7m2o1_500.png │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── AppDelegate.swift │ ├── Info.plist │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── ViewController.swift │ └── MenuTitleView.xib ├── Pods │ ├── UPMenu │ │ ├── UPMenu │ │ │ └── UPMenu │ │ │ │ ├── Assets.xcassets │ │ │ │ ├── Contents.json │ │ │ │ ├── menu.imageset │ │ │ │ │ ├── btnBg.pdf │ │ │ │ │ └── Contents.json │ │ │ │ ├── menuIcn.imageset │ │ │ │ │ ├── menuIcn.png │ │ │ │ │ ├── menuIcn@2x.png │ │ │ │ │ ├── menuIcn@3x.png │ │ │ │ │ └── Contents.json │ │ │ │ ├── closeBtn.imageset │ │ │ │ │ ├── closeBtn.png │ │ │ │ │ ├── closeBtn@2x.png │ │ │ │ │ ├── closeBtn@3x.png │ │ │ │ │ └── Contents.json │ │ │ │ └── closeIcn.imageset │ │ │ │ │ ├── closeIcn.png │ │ │ │ │ ├── closeIcn@2x.png │ │ │ │ │ ├── closeIcn@3x.png │ │ │ │ │ └── Contents.json │ │ │ │ └── Source │ │ │ │ ├── UPMenuItem.swift │ │ │ │ ├── UPMenuTableViewCell.swift │ │ │ │ ├── UPMenuTableViewCell.xib │ │ │ │ ├── UPMenu.xib │ │ │ │ └── UPMenu.swift │ │ ├── LICENSE │ │ └── README.md │ ├── Target Support Files │ │ ├── UPMenu │ │ │ ├── UPMenu.modulemap │ │ │ ├── UPMenu-dummy.m │ │ │ ├── UPMenu-prefix.pch │ │ │ ├── UPMenu-umbrella.h │ │ │ ├── UPMenu.xcconfig │ │ │ └── Info.plist │ │ └── Pods-Example │ │ │ ├── Pods-Example.modulemap │ │ │ ├── Pods-Example-dummy.m │ │ │ ├── Pods-Example-umbrella.h │ │ │ ├── Pods-Example.debug.xcconfig │ │ │ ├── Pods-Example.release.xcconfig │ │ │ ├── Info.plist │ │ │ ├── Pods-Example-acknowledgements.markdown │ │ │ ├── Pods-Example-acknowledgements.plist │ │ │ ├── Pods-Example-resources.sh │ │ │ └── Pods-Example-frameworks.sh │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ └── xcuserdata │ │ │ └── artemkalinovsky.xcuserdatad │ │ │ └── xcschemes │ │ │ ├── xcschememanagement.plist │ │ │ ├── UPMenu.xcscheme │ │ │ └── Pods-Example.xcscheme │ └── Local Podspecs │ │ └── UPMenu.podspec.json ├── Podfile ├── Example.xcworkspace │ ├── xcuserdata │ │ └── artemkalinovsky.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ ├── xcschemes │ │ │ └── xcschememanagement.plist │ │ │ └── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ └── contents.xcworkspacedata ├── Example.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── artemkalinovsky.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ ├── xcuserdata │ │ └── artemkalinovsky.xcuserdatad │ │ │ └── xcschemes │ │ │ ├── xcschememanagement.plist │ │ │ └── Example.xcscheme │ └── project.pbxproj └── Podfile.lock ├── UPMenu ├── UPMenu │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── menu.imageset │ │ │ ├── btnBg.pdf │ │ │ └── Contents.json │ │ ├── menuIcn.imageset │ │ │ ├── menuIcn.png │ │ │ ├── menuIcn@2x.png │ │ │ ├── menuIcn@3x.png │ │ │ └── Contents.json │ │ ├── closeBtn.imageset │ │ │ ├── closeBtn.png │ │ │ ├── closeBtn@2x.png │ │ │ ├── closeBtn@3x.png │ │ │ └── Contents.json │ │ └── closeIcn.imageset │ │ │ ├── closeIcn.png │ │ │ ├── closeIcn@2x.png │ │ │ ├── closeIcn@3x.png │ │ │ └── Contents.json │ ├── Source │ │ ├── UPMenuItem.swift │ │ ├── UPMenuTableViewCell.swift │ │ ├── UPMenuTableViewCell.xib │ │ ├── UPMenu.xib │ │ └── UPMenu.swift │ ├── UPMenu.h │ └── Info.plist ├── UPMenu.xcodeproj │ ├── xcuserdata │ │ └── artemkalinovsky.xcuserdatad │ │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ │ └── xcschemes │ │ │ ├── xcschememanagement.plist │ │ │ └── UPMenu.xcscheme │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── artemkalinovsky.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ └── project.pbxproj ├── UPMenu.podspec └── LICENSE ├── .gitignore ├── LICENSE └── README.md /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/demo.gif -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /UPMenu/UPMenu/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/home.imageset/31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/home.imageset/31.png -------------------------------------------------------------------------------- /UPMenu/UPMenu/Assets.xcassets/menu.imageset/btnBg.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/UPMenu/UPMenu/Assets.xcassets/menu.imageset/btnBg.pdf -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/home.imageset/31@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/home.imageset/31@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/home.imageset/31@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/home.imageset/31@3x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/shadow.imageset/oval4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/shadow.imageset/oval4.png -------------------------------------------------------------------------------- /UPMenu/UPMenu/Assets.xcassets/menuIcn.imageset/menuIcn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/UPMenu/UPMenu/Assets.xcassets/menuIcn.imageset/menuIcn.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/profile_icon.imageset/icn4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/profile_icon.imageset/icn4.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/recipe_icon.imageset/icn1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/recipe_icon.imageset/icn1.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/shadow.imageset/oval4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/shadow.imageset/oval4@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/shadow.imageset/oval4@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/shadow.imageset/oval4@3x.png -------------------------------------------------------------------------------- /UPMenu/UPMenu/Assets.xcassets/closeBtn.imageset/closeBtn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/UPMenu/UPMenu/Assets.xcassets/closeBtn.imageset/closeBtn.png -------------------------------------------------------------------------------- /UPMenu/UPMenu/Assets.xcassets/closeIcn.imageset/closeIcn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/UPMenu/UPMenu/Assets.xcassets/closeIcn.imageset/closeIcn.png -------------------------------------------------------------------------------- /UPMenu/UPMenu/Assets.xcassets/menuIcn.imageset/menuIcn@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/UPMenu/UPMenu/Assets.xcassets/menuIcn.imageset/menuIcn@2x.png -------------------------------------------------------------------------------- /UPMenu/UPMenu/Assets.xcassets/menuIcn.imageset/menuIcn@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/UPMenu/UPMenu/Assets.xcassets/menuIcn.imageset/menuIcn@3x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/close_icon.imageset/closeIcn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/close_icon.imageset/closeIcn.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/favorite_icon.imageset/icn2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/favorite_icon.imageset/icn2.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/recipe_icon.imageset/icn1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/recipe_icon.imageset/icn1@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/recipe_icon.imageset/icn1@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/recipe_icon.imageset/icn1@3x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/shoplist_icon.imageset/icn3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/shoplist_icon.imageset/icn3.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/whitecircle.imageset/icnBase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/whitecircle.imageset/icnBase.png -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/UPMenu/UPMenu.modulemap: -------------------------------------------------------------------------------- 1 | framework module UPMenu { 2 | umbrella header "UPMenu-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /UPMenu/UPMenu/Assets.xcassets/closeBtn.imageset/closeBtn@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/UPMenu/UPMenu/Assets.xcassets/closeBtn.imageset/closeBtn@2x.png -------------------------------------------------------------------------------- /UPMenu/UPMenu/Assets.xcassets/closeBtn.imageset/closeBtn@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/UPMenu/UPMenu/Assets.xcassets/closeBtn.imageset/closeBtn@3x.png -------------------------------------------------------------------------------- /UPMenu/UPMenu/Assets.xcassets/closeIcn.imageset/closeIcn@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/UPMenu/UPMenu/Assets.xcassets/closeIcn.imageset/closeIcn@2x.png -------------------------------------------------------------------------------- /UPMenu/UPMenu/Assets.xcassets/closeIcn.imageset/closeIcn@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/UPMenu/UPMenu/Assets.xcassets/closeIcn.imageset/closeIcn@3x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/close_icon.imageset/closeIcn@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/close_icon.imageset/closeIcn@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/close_icon.imageset/closeIcn@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/close_icon.imageset/closeIcn@3x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/favorite_icon.imageset/icn2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/favorite_icon.imageset/icn2@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/favorite_icon.imageset/icn2@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/favorite_icon.imageset/icn2@3x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/profile_icon.imageset/icn4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/profile_icon.imageset/icn4@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/profile_icon.imageset/icn4@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/profile_icon.imageset/icn4@3x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/shoplist_icon.imageset/icn3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/shoplist_icon.imageset/icn3@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/shoplist_icon.imageset/icn3@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/shoplist_icon.imageset/icn3@3x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/whitecircle.imageset/icnBase@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/whitecircle.imageset/icnBase@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/whitecircle.imageset/icnBase@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/whitecircle.imageset/icnBase@3x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/twitter_icon.imageset/twitterIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/twitter_icon.imageset/twitterIcon.png -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/UPMenu/UPMenu-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_UPMenu : NSObject 3 | @end 4 | @implementation PodsDummy_UPMenu 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/facebook_icon.imageset/facebookIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/facebook_icon.imageset/facebookIcon.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/hamburger_icon.imageset/menu_icn_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/hamburger_icon.imageset/menu_icn_2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/hamburger_icon.imageset/menu_icn_3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/hamburger_icon.imageset/menu_icn_3x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/twitter_icon.imageset/twitterIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/twitter_icon.imageset/twitterIcon@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/twitter_icon.imageset/twitterIcon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/twitter_icon.imageset/twitterIcon@3x.png -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | platform :ios, '10.0' 3 | 4 | use_frameworks! 5 | 6 | target 'Example' do 7 | 8 | pod 'UPMenu' 9 | 10 | end 11 | -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/facebook_icon.imageset/facebookIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/facebook_icon.imageset/facebookIcon@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/facebook_icon.imageset/facebookIcon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/facebook_icon.imageset/facebookIcon@3x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/instagram_icon.imageset/instagramIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/instagram_icon.imageset/instagramIcon.png -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/menu.imageset/btnBg.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/menu.imageset/btnBg.pdf -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/instagram_icon.imageset/instagramIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/instagram_icon.imageset/instagramIcon@2x.png -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/instagram_icon.imageset/instagramIcon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/instagram_icon.imageset/instagramIcon@3x.png -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Example/Pods-Example.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Example { 2 | umbrella header "Pods-Example-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/menuIcn.imageset/menuIcn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/menuIcn.imageset/menuIcn.png -------------------------------------------------------------------------------- /UPMenu/UPMenu.xcodeproj/xcuserdata/artemkalinovsky.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/tubik.imageset/tumblr_ovay9mdCdX1r2e7m2o1_500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example/Assets.xcassets/tubik.imageset/tumblr_ovay9mdCdX1r2e7m2o1_500.png -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Example/Pods-Example-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Example : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Example 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/closeBtn.imageset/closeBtn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/closeBtn.imageset/closeBtn.png -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/closeIcn.imageset/closeIcn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/closeIcn.imageset/closeIcn.png -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/menuIcn.imageset/menuIcn@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/menuIcn.imageset/menuIcn@2x.png -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/menuIcn.imageset/menuIcn@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/menuIcn.imageset/menuIcn@3x.png -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/closeBtn.imageset/closeBtn@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/closeBtn.imageset/closeBtn@2x.png -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/closeBtn.imageset/closeBtn@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/closeBtn.imageset/closeBtn@3x.png -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/closeIcn.imageset/closeIcn@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/closeIcn.imageset/closeIcn@2x.png -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/closeIcn.imageset/closeIcn@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/closeIcn.imageset/closeIcn@3x.png -------------------------------------------------------------------------------- /Example/Example.xcworkspace/xcuserdata/artemkalinovsky.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example.xcworkspace/xcuserdata/artemkalinovsky.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /UPMenu/UPMenu.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /UPMenu/UPMenu/Assets.xcassets/menu.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "btnBg.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - UPMenu (0.2.0) 3 | 4 | DEPENDENCIES: 5 | - UPMenu 6 | 7 | SPEC CHECKSUMS: 8 | UPMenu: 5eae261340b1cc57b7d66a39564ac87714f8cdc3 9 | 10 | PODFILE CHECKSUM: 07ece959b4782fa1e67d0aa88713fb67b44bde05 11 | 12 | COCOAPODS: 1.4.0 13 | -------------------------------------------------------------------------------- /UPMenu/UPMenu.xcodeproj/project.xcworkspace/xcuserdata/artemkalinovsky.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/UPMenu/UPMenu.xcodeproj/project.xcworkspace/xcuserdata/artemkalinovsky.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Example/Example.xcodeproj/project.xcworkspace/xcuserdata/artemkalinovsky.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tubikstudio/UPMenu/HEAD/Example/Example.xcodeproj/project.xcworkspace/xcuserdata/artemkalinovsky.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - UPMenu (0.2.0) 3 | 4 | DEPENDENCIES: 5 | - UPMenu 6 | 7 | SPEC CHECKSUMS: 8 | UPMenu: 5eae261340b1cc57b7d66a39564ac87714f8cdc3 9 | 10 | PODFILE CHECKSUM: 07ece959b4782fa1e67d0aa88713fb67b44bde05 11 | 12 | COCOAPODS: 1.4.0 13 | -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/menu.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "btnBg.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/tubik.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "tumblr_ovay9mdCdX1r2e7m2o1_500.png" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Example/Example.xcworkspace/xcuserdata/artemkalinovsky.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/UPMenu/UPMenu-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /UPMenu/UPMenu.xcodeproj/project.xcworkspace/xcuserdata/artemkalinovsky.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Example/Example.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /UPMenu/UPMenu/Source/UPMenuItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UPMenuItem.swift 3 | // UPMenu 4 | // 5 | // Created by Artem Kalinovsky on 3/26/18. 6 | // Copyright © 2018 Tubik Studio. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public protocol UPMenuItem { 12 | var image: UIImage? { get } 13 | var title: String? { get } 14 | } 15 | -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Source/UPMenuItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UPMenuItem.swift 3 | // UPMenu 4 | // 5 | // Created by Artem Kalinovsky on 3/26/18. 6 | // Copyright © 2018 Tubik Studio. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public protocol UPMenuItem { 12 | var image: UIImage? { get } 13 | var title: String? { get } 14 | } 15 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/UPMenu/UPMenu-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double UPMenuVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char UPMenuVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Example/Pods-Example-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_ExampleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_ExampleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | Carthage/ 4 | build/ 5 | *.pbxuser 6 | !default.pbxuser 7 | *.mode1v3 8 | !default.mode1v3 9 | *.mode2v3 10 | !default.mode2v3 11 | *.perspectivev3 12 | !default.perspectivev3 13 | xcuserdata 14 | *.xccheckout 15 | *.moved-aside 16 | DerivedData 17 | *.hmap 18 | *.ipa 19 | *.xcuserstate 20 | 21 | .xcodeproj/* 22 | !*.xcodeproj/*.pbxproj 23 | !*.xcodeproj/xcshareddata 24 | 25 | .xcworkspace/* 26 | !*.xcworkspace/*.xcworkspacedata 27 | 28 | pkg/* 29 | -------------------------------------------------------------------------------- /UPMenu/UPMenu.xcodeproj/xcuserdata/artemkalinovsky.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | UPMenu.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Example/Example.xcodeproj/xcuserdata/artemkalinovsky.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Example.xcscheme 8 | 9 | orderHint 10 | 3 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/hamburger_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "menu_icn_2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "menu_icn_3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/home.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "31.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "31@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "31@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/favorite_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "icn2.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "icn2@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "icn2@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/profile_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "icn4.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "icn4@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "icn4@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/recipe_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "icn1.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "icn1@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "icn1@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/shadow.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "oval4.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "oval4@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "oval4@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/shoplist_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "icn3.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "icn3@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "icn3@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /UPMenu/UPMenu/Assets.xcassets/closeBtn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "closeBtn.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "closeBtn@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "closeBtn@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /UPMenu/UPMenu/Assets.xcassets/closeIcn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "closeIcn.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "closeIcn@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "closeIcn@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /UPMenu/UPMenu/Assets.xcassets/menuIcn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "menuIcn.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "menuIcn@2x.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "menuIcn@3x.png" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "zeplin", 21 | "version" : "1" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/close_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "closeIcn.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "closeIcn@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "closeIcn@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/whitecircle.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "icnBase.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "icnBase@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "icnBase@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/twitter_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "twitterIcon.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "twitterIcon@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "twitterIcon@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/Example/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Example 4 | // 5 | // Created by Tubik Studio on 2/21/18. 6 | // Copyright © 2018 Tubik Studio. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 17 | return true 18 | } 19 | 20 | } 21 | 22 | -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/facebook_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "facebookIcon.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "facebookIcon@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "facebookIcon@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/closeBtn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "closeBtn.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "closeBtn@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "closeBtn@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/closeIcn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "closeIcn.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "closeIcn@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "closeIcn@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Assets.xcassets/menuIcn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "menuIcn.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "menuIcn@2x.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "menuIcn@3x.png" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "zeplin", 21 | "version" : "1" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/instagram_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "instagramIcon.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "instagramIcon@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "instagramIcon@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /UPMenu/UPMenu/UPMenu.h: -------------------------------------------------------------------------------- 1 | // 2 | // UPMenu.h 3 | // UPMenu 4 | // 5 | // Created by Artem Kalinovsky on 2/21/18. 6 | // Copyright © 2018 Tubik Studio. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for UPMenu. 12 | FOUNDATION_EXPORT double UPMenuVersionNumber; 13 | 14 | //! Project version string for UPMenu. 15 | FOUNDATION_EXPORT const unsigned char UPMenuVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Example/Example.xcworkspace/xcuserdata/artemkalinovsky.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcuserdata/artemkalinovsky.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Pods-Example.xcscheme 8 | 9 | isShown 10 | 11 | 12 | UPMenu.xcscheme 13 | 14 | isShown 15 | 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/UPMenu/UPMenu.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/UPMenu 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 4 | OTHER_LDFLAGS = -framework "UIKit" 5 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/UPMenu 10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 11 | SKIP_INSTALL = YES 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Example/Pods-Example.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/UPMenu" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/UPMenu/UPMenu.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "UPMenu" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Example/Pods-Example.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/UPMenu" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/UPMenu/UPMenu.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "UPMenu" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/UPMenu.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "UPMenu", 3 | "platforms": { 4 | "ios": "10.0" 5 | }, 6 | "summary": "UpperApp-like floating menu.", 7 | "requires_arc": true, 8 | "swift_version": "4.0", 9 | "version": "0.1.0", 10 | "license": { 11 | "type": "MIT", 12 | "file": "LICENSE" 13 | }, 14 | "authors": { 15 | "Tubik Studio": "ios@tubikstudio.com" 16 | }, 17 | "social_media_url": "https://twitter.com/tubikstudio", 18 | "homepage": "https://github.com/tubikstudio/UPMenu", 19 | "source": { 20 | "git": "https://github.com/tubikstudio/UPMenu.git", 21 | "tag": "0.1.0" 22 | }, 23 | "frameworks": "UIKit", 24 | "source_files": "UPMenu/**/*.{swift}", 25 | "resources": "UPMenu/**/*.{png,jpeg,jpg,storyboard,xib,xcassets}" 26 | } 27 | -------------------------------------------------------------------------------- /UPMenu/UPMenu.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.platform = :ios 4 | s.ios.deployment_target = '10.0' 5 | s.name = "UPMenu" 6 | s.summary = "UpperApp-like floating menu." 7 | s.requires_arc = true 8 | s.swift_version = '4.0' 9 | 10 | s.version = "0.2.0" 11 | 12 | s.license = { :type => "MIT", :file => "LICENSE" } 13 | 14 | s.author = { "Tubik Studio" => "ios@tubikstudio.com" } 15 | s.social_media_url = 'https://twitter.com/tubikstudio' 16 | 17 | s.homepage = "https://github.com/tubikstudio/UPMenu" 18 | 19 | s.source = { :git => "https://github.com/tubikstudio/UPMenu.git", :tag => "#{s.version}" } 20 | 21 | s.framework = "UIKit" 22 | 23 | s.source_files = "UPMenu/**/*.{swift}" 24 | 25 | s.resources = "UPMenu/**/*.{png,jpeg,jpg,storyboard,xib,xcassets}" 26 | 27 | end 28 | -------------------------------------------------------------------------------- /UPMenu/UPMenu/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /UPMenu/UPMenu.xcodeproj/xcuserdata/artemkalinovsky.xcuserdatad/xcschemes/UPMenu.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/UPMenu/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 | FMWK 17 | CFBundleShortVersionString 18 | 0.2.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Example/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 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /UPMenu/UPMenu/Source/UPMenuTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UPMenuTableViewCell.swift 3 | // UPMenu 4 | // 5 | // Created by Tubik Studio on 16/3/18. 6 | // Copyright © 2018 Tubik Studio. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public class UPMenuTableViewCell: UITableViewCell { 12 | 13 | //MARK: - Properties 14 | 15 | static var reuseIdentifier: String { 16 | get { 17 | return String(describing: self.self) 18 | } 19 | } 20 | 21 | @IBOutlet private weak var menuItemImageView: UIImageView! 22 | @IBOutlet private weak var menuItemTitleLabel: UILabel! 23 | 24 | //MARK: - Methods 25 | 26 | func configure(menuItemImage: UIImage?, menuItemTitle: String?, menuAppearance: UPMenu.Appearance) { 27 | backgroundColor = menuAppearance.menuItemCellBackgroundColor 28 | menuItemTitleLabel.textColor = menuAppearance.menuItemCellTitleColor 29 | menuItemTitleLabel.font = menuAppearance.menuItemCellTitleFont 30 | menuItemTitleLabel.text = menuItemTitle 31 | menuItemImageView.image = menuItemImage 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Source/UPMenuTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UPMenuTableViewCell.swift 3 | // UPMenu 4 | // 5 | // Created by Tubik Studio on 16/3/18. 6 | // Copyright © 2018 Tubik Studio. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public class UPMenuTableViewCell: UITableViewCell { 12 | 13 | //MARK: - Properties 14 | 15 | static var reuseIdentifier: String { 16 | get { 17 | return String(describing: self.self) 18 | } 19 | } 20 | 21 | @IBOutlet private weak var menuItemImageView: UIImageView! 22 | @IBOutlet private weak var menuItemTitleLabel: UILabel! 23 | 24 | //MARK: - Methods 25 | 26 | func configure(menuItemImage: UIImage?, menuItemTitle: String?, menuAppearance: UPMenu.Appearance) { 27 | backgroundColor = menuAppearance.menuItemCellBackgroundColor 28 | menuItemTitleLabel.textColor = menuAppearance.menuItemCellTitleColor 29 | menuItemTitleLabel.font = menuAppearance.menuItemCellTitleFont 30 | menuItemTitleLabel.text = menuItemTitle 31 | menuItemImageView.image = menuItemImage 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Tubik Studio 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /UPMenu/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 tubikstudio 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Example/Pods/UPMenu/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Tubik Studio 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Example/Example.xcodeproj/xcuserdata/artemkalinovsky.xcuserdatad/xcschemes/Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Example/Pods-Example-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## UPMenu 5 | 6 | MIT License 7 | 8 | Copyright (c) 2018 Tubik Studio 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | Generated by CocoaPods - https://cocoapods.org 29 | -------------------------------------------------------------------------------- /Example/Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Example/Example/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Example/Pods-Example-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | MIT License 18 | 19 | Copyright (c) 2018 Tubik Studio 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | License 40 | MIT 41 | Title 42 | UPMenu 43 | Type 44 | PSGroupSpecifier 45 | 46 | 47 | FooterText 48 | Generated by CocoaPods - https://cocoapods.org 49 | Title 50 | 51 | Type 52 | PSGroupSpecifier 53 | 54 | 55 | StringsTable 56 | Acknowledgements 57 | Title 58 | Acknowledgements 59 | 60 | 61 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcuserdata/artemkalinovsky.xcuserdatad/xcschemes/UPMenu.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcuserdata/artemkalinovsky.xcuserdatad/xcschemes/Pods-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Example/Example/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Example 4 | // 5 | // Created by Tubik Studio on 2/21/18. 6 | // Copyright © 2018 Tubik Studio. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import UPMenu 11 | 12 | struct RecipeAppMenuItem: UPMenuItem { 13 | var image: UIImage? 14 | var title: String? 15 | } 16 | 17 | class ViewController: UIViewController { 18 | 19 | @IBOutlet private weak var shadowImage: UIImageView! 20 | @IBOutlet private weak var upMenuFromStoryboard: UPMenu! 21 | 22 | private let menuItems = [RecipeAppMenuItem(image: UIImage(named: "recipe_icon"), title: "Recipes"), 23 | RecipeAppMenuItem(image: UIImage(named: "favorite_icon"), title: "Favorite"), 24 | RecipeAppMenuItem(image: UIImage(named: "shoplist_icon"), title: "Shoplist"), 25 | RecipeAppMenuItem(image: UIImage(named: "profile_icon"), title: "Profile")] 26 | 27 | // MARK: - UIViewController 28 | 29 | override func viewDidAppear(_ animated: Bool) { 30 | super.viewDidAppear(animated) 31 | 32 | upMenuFromStoryboard.delegate = self 33 | upMenuFromStoryboard.appearance.menuImage = UIImage(named: "hamburger_icon") 34 | upMenuFromStoryboard.appearance.closedMenuColor = UIColor(red: 212/255.0, green: 57/255.0, blue: 71/255.0, alpha: 1) 35 | upMenuFromStoryboard.appearance.closeMenuImage = UIImage(named: "close_icon") 36 | upMenuFromStoryboard.appearance.menuItemsViewBackgroundColor = UIColor.white 37 | upMenuFromStoryboard.appearance.menuItemCellTitleFont = UIFont(name: "Futura-Medium", size: 23) ?? UIFont.systemFont(ofSize: 23) 38 | upMenuFromStoryboard.appearance.menuItemCellBackgroundColor = UIColor.white 39 | upMenuFromStoryboard.appearance.menuItemCellTitleColor = UIColor.black 40 | upMenuFromStoryboard.menuItemsListHeight = 344 41 | upMenuFromStoryboard.menuItemHeight = 80 42 | upMenuFromStoryboard.updateMenuItems(with: menuItems) 43 | upMenuFromStoryboard.addTitleView(Bundle.main.loadNibNamed("MenuTitleView", owner: self, options: nil)?.first as! UIView) 44 | 45 | } 46 | 47 | } 48 | 49 | // MARK: - UPMenuDelegate 50 | 51 | extension ViewController: UPMenuDelegate { 52 | 53 | func upMenuWillAppear() { 54 | UIView.animate(withDuration: 0.3, animations: { 55 | self.shadowImage.alpha = 0 56 | }) 57 | } 58 | 59 | func upMenuDidClosed() { 60 | UIView.animate(withDuration: 0.3, animations: { 61 | self.shadowImage.alpha = 1 62 | }) 63 | } 64 | 65 | func upMenu(_ upMenu: UPMenu, didSelectMenuItemAt indexPath: IndexPath) { 66 | print("\(upMenu.menuItems[indexPath.row].title ?? "")") 67 | } 68 | 69 | } 70 | 71 | -------------------------------------------------------------------------------- /Example/Pods/UPMenu/README.md: -------------------------------------------------------------------------------- 1 | # UPMenu 2 | 3 | Menu control from [Upper](https://uppertodo.com) 4 | 5 | ![Preview](https://github.com/tubikstudio/UPMenu/blob/master/demo.gif) 6 | 7 | ## Requirements 8 | 9 | - iOS 10.0+ 10 | - Xcode 9 11 | - Swift 4 12 | 13 | ## Installation 14 | 15 | #### [CocoaPods](http://cocoapods.org) 16 | 17 | ```ruby 18 | pod 'UPMenu' 19 | ``` 20 | 21 | #### Manual Installation 22 | 23 | Add Source folder to your project, that's all. 24 | 25 | ### Usage 26 | 27 | * If you install UPMenu from Cocoapods, be sure to import the module into your View Controller: 28 | 29 | ```swift 30 | import UPMenu 31 | ``` 32 | 33 | * [Code] Create menu view, and set point, where it should be located: 34 | 35 | ```swift 36 | let upMenu = UPMenu(frame: view.frame) 37 | upMenu.startPoint = CGPoint(x: view.frame.width - 60, y: view.frame.height - 80) 38 | view.addSubview(upMenu) 39 | ``` 40 | 41 | * [InterfaceBuilder] Add UIView, set it's class to `UPMenu`, create IBOutlet and update start point (look at Example project for more details): 42 | ```swift 43 | @IBOutlet weak var upMenuFromStoryboard: UPMenu! 44 | 45 | override func viewDidAppear(_ animated: Bool) { 46 | super.viewDidAppear(animated) 47 | 48 | upMenuFromStoryboard.startPoint = CGPoint(x: view.frame.width - 60, y: view.frame.height - 80) 49 | } 50 | ``` 51 | 52 | * Set delegate and implement `UPMenuDelegate` protocol to get notified about UPMenu events: 53 | 54 | ```swift 55 | upMenu.delegate = self 56 | 57 | extension ViewController: UPMenuDelegate { 58 | 59 | func upMenu(_ upMenu: UPMenu, didSelectMenuItemAt indexPath: IndexPath) { 60 | print("\(upMenu.menuItemsTitles[indexPath.row])") 61 | } 62 | 63 | } 64 | ``` 65 | 66 | ### Customisation 67 | 68 | * Set menu items titles: 69 | 70 | ```swift 71 | upMenu.updateMenuItemsTitles(with: ["👤 Profile", "🎯 Activity", "⚙️ Settings"]) 72 | ``` 73 | 74 | * Set menu items list height: 75 | 76 | ```swift 77 | upMenu.menuItemsListHeight = 217 78 | ``` 79 | 80 | * Set menu items cells backgorund color and font: 81 | 82 | ```swift 83 | upMenu.appearance.menuItemCellBackgroundColor = UIColor.black 84 | upMenu.appearance.menuItemCellTitleFont = UIFont.systemFont(ofSize: 36) 85 | ``` 86 | 87 | * Set closed menu color: 88 | 89 | ```swift 90 | upMenu.appearance.closedMenuColor = UIColor.white 91 | ``` 92 | 93 | * Set title view background color: 94 | 95 | ```swift 96 | upMenu.appearance.titleViewBackgorundColor = UIColor.white 97 | ``` 98 | 99 | * Set menu items view background color: 100 | 101 | ```swift 102 | upMenu.appearance.menuItemsViewBackgroundColor = UIColor.black 103 | ``` 104 | 105 | * Set custom title view: 106 | 107 | ```swift 108 | let label = UILabel(frame: CGRect(origin: .zero, size: CGSize(width: 150, height: 150))) 109 | label.font = UIFont.systemFont(ofSize: 56) 110 | label.textAlignment = .center 111 | label.text = "🐶" 112 | 113 | upMenu.addTitleView(label) 114 | ``` 115 | 116 | ### Let us know! 117 | 118 | We’d be really happy if you sent us links to your projects where you use our component. Just send an email to ios@tubikstudio.com And do let us know if you have any questions or suggestion regarding the animation. 119 | 120 | ### License 121 | 122 | MIT License 123 | 124 | Copyright (c) 2018 Tubik Studio 125 | 126 | Permission is hereby granted, free of charge, to any person obtaining a copy 127 | of this software and associated documentation files (the "Software"), to deal 128 | in the Software without restriction, including without limitation the rights 129 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 130 | copies of the Software, and to permit persons to whom the Software is 131 | furnished to do so, subject to the following conditions: 132 | 133 | The above copyright notice and this permission notice shall be included in all 134 | copies or substantial portions of the Software. 135 | 136 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 137 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 138 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 139 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 140 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 141 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 142 | SOFTWARE. 143 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UPMenu 2 | 3 | Menu control from [Upper](https://uppertodo.com) 4 | 5 | ![Preview](https://github.com/tubikstudio/UPMenu/blob/master/demo.gif) 6 | 7 | ## Requirements 8 | 9 | - iOS 10.0+ 10 | - Xcode 9 11 | - Swift 4 12 | 13 | ## Installation 14 | 15 | #### [CocoaPods](http://cocoapods.org) 16 | 17 | ```ruby 18 | pod 'UPMenu' 19 | ``` 20 | 21 | #### Manual Installation 22 | 23 | Add Source folder to your project, that's all. 24 | 25 | ### Usage 26 | 27 | * If you install UPMenu from Cocoapods, be sure to import the module into your View Controller: 28 | 29 | ```swift 30 | import UPMenu 31 | ``` 32 | 33 | * [Code] Create menu view, and set point, where it should be located: 34 | 35 | ```swift 36 | let upMenu = UPMenu(frame: view.frame) 37 | upMenu.startPoint = CGPoint(x: view.frame.width - 60, y: view.frame.height - 80) 38 | view.addSubview(upMenu) 39 | ``` 40 | 41 | * [InterfaceBuilder] Add UIView, set it's class to `UPMenu`, create IBOutlet and update start point (look at Example project for more details): 42 | ```swift 43 | @IBOutlet weak var upMenuFromStoryboard: UPMenu! 44 | 45 | override func viewDidAppear(_ animated: Bool) { 46 | super.viewDidAppear(animated) 47 | 48 | upMenuFromStoryboard.startPoint = CGPoint(x: view.frame.width - 60, y: view.frame.height - 80) 49 | } 50 | ``` 51 | 52 | * Set delegate and implement `UPMenuDelegate` protocol to get notified about UPMenu events: 53 | 54 | ```swift 55 | upMenu.delegate = self 56 | 57 | extension ViewController: UPMenuDelegate { 58 | 59 | func upMenu(_ upMenu: UPMenu, didSelectMenuItemAt indexPath: IndexPath) { 60 | print("\(upMenu.menuItems[indexPath.row].title)") 61 | } 62 | 63 | } 64 | ``` 65 | 66 | ### Customisation 67 | 68 | * Set menu items titles: 69 | 70 | ```swift 71 | upMenu.updateMenuItems(with: menuItems) 72 | ``` 73 | `menuItems` should be array of `UPMenuItem` objects 74 | 75 | * Set menu items list height: 76 | 77 | ```swift 78 | upMenu.menuItemsListHeight = 217 79 | ``` 80 | 81 | * Set menu items cells backgorund color, font, text color: 82 | 83 | ```swift 84 | upMenu.appearance.menuItemCellBackgroundColor = UIColor.black 85 | upMenu.appearance.menuItemCellTitleFont = UIFont.systemFont(ofSize: 36) 86 | upMenu.appearance.menuItemCellTitleColor = UIColor.black 87 | ``` 88 | * Set menu items cells height: 89 | 90 | ```swift 91 | upMenu.menuItemHeight = 80 92 | ``` 93 | 94 | * Set closed menu color: 95 | 96 | ```swift 97 | upMenu.appearance.closedMenuColor = UIColor.white 98 | ``` 99 | 100 | * Set title view background color: 101 | 102 | ```swift 103 | upMenu.appearance.titleViewBackgorundColor = UIColor.white 104 | ``` 105 | 106 | * Set menu items view background color: 107 | 108 | ```swift 109 | upMenu.appearance.menuItemsViewBackgroundColor = UIColor.black 110 | ``` 111 | 112 | * Set custom title view: 113 | 114 | ```swift 115 | let label = UILabel(frame: CGRect(origin: .zero, size: CGSize(width: 150, height: 150))) 116 | label.font = UIFont.systemFont(ofSize: 56) 117 | label.textAlignment = .center 118 | label.text = "🐶" 119 | 120 | upMenu.addTitleView(label) 121 | ``` 122 | 123 | ### Let us know! 124 | 125 | We’d be really happy if you sent us links to your projects where you use our component. Just send an email to ios@tubikstudio.com And do let us know if you have any questions or suggestion regarding the animation. 126 | 127 | ### License 128 | 129 | MIT License 130 | 131 | Copyright (c) 2018 Tubik Studio 132 | 133 | Permission is hereby granted, free of charge, to any person obtaining a copy 134 | of this software and associated documentation files (the "Software"), to deal 135 | in the Software without restriction, including without limitation the rights 136 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 137 | copies of the Software, and to permit persons to whom the Software is 138 | furnished to do so, subject to the following conditions: 139 | 140 | The above copyright notice and this permission notice shall be included in all 141 | copies or substantial portions of the Software. 142 | 143 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 144 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 145 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 146 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 147 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 148 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 149 | SOFTWARE. 150 | -------------------------------------------------------------------------------- /UPMenu/UPMenu/Source/UPMenuTableViewCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ArialMT 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Source/UPMenuTableViewCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | ArialMT 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /Example/Example/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 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Example/Pods-Example-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 12 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 13 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 14 | 15 | case "${TARGETED_DEVICE_FAMILY}" in 16 | 1,2) 17 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 18 | ;; 19 | 1) 20 | TARGET_DEVICE_ARGS="--target-device iphone" 21 | ;; 22 | 2) 23 | TARGET_DEVICE_ARGS="--target-device ipad" 24 | ;; 25 | 3) 26 | TARGET_DEVICE_ARGS="--target-device tv" 27 | ;; 28 | 4) 29 | TARGET_DEVICE_ARGS="--target-device watch" 30 | ;; 31 | *) 32 | TARGET_DEVICE_ARGS="--target-device mac" 33 | ;; 34 | esac 35 | 36 | install_resource() 37 | { 38 | if [[ "$1" = /* ]] ; then 39 | RESOURCE_PATH="$1" 40 | else 41 | RESOURCE_PATH="${PODS_ROOT}/$1" 42 | fi 43 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 44 | cat << EOM 45 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 46 | EOM 47 | exit 1 48 | fi 49 | case $RESOURCE_PATH in 50 | *.storyboard) 51 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 52 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 53 | ;; 54 | *.xib) 55 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 56 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 57 | ;; 58 | *.framework) 59 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 60 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 61 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 62 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 63 | ;; 64 | *.xcdatamodel) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 67 | ;; 68 | *.xcdatamodeld) 69 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 70 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 71 | ;; 72 | *.xcmappingmodel) 73 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 74 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 75 | ;; 76 | *.xcassets) 77 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 78 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 79 | ;; 80 | *) 81 | echo "$RESOURCE_PATH" || true 82 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 83 | ;; 84 | esac 85 | } 86 | 87 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 89 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 90 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 91 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 92 | fi 93 | rm -f "$RESOURCES_TO_COPY" 94 | 95 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 96 | then 97 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 98 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 99 | while read line; do 100 | if [[ $line != "${PODS_ROOT}*" ]]; then 101 | XCASSET_FILES+=("$line") 102 | fi 103 | done <<<"$OTHER_XCASSETS" 104 | 105 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 106 | fi 107 | -------------------------------------------------------------------------------- /Example/Example/MenuTitleView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Futura-Bold 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 30 | 38 | 46 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Example/Pods-Example-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | # Used as a return value for each invocation of `strip_invalid_archs` function. 10 | STRIP_BINARY_RETVAL=0 11 | 12 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 13 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 14 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 15 | 16 | # Copies and strips a vendored framework 17 | install_framework() 18 | { 19 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 20 | local source="${BUILT_PRODUCTS_DIR}/$1" 21 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 22 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 23 | elif [ -r "$1" ]; then 24 | local source="$1" 25 | fi 26 | 27 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 28 | 29 | if [ -L "${source}" ]; then 30 | echo "Symlinked..." 31 | source="$(readlink "${source}")" 32 | fi 33 | 34 | # Use filter instead of exclude so missing patterns don't throw errors. 35 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 36 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 37 | 38 | local basename 39 | basename="$(basename -s .framework "$1")" 40 | binary="${destination}/${basename}.framework/${basename}" 41 | if ! [ -r "$binary" ]; then 42 | binary="${destination}/${basename}" 43 | fi 44 | 45 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 46 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 47 | strip_invalid_archs "$binary" 48 | fi 49 | 50 | # Resign the code if required by the build settings to avoid unstable apps 51 | code_sign_if_enabled "${destination}/$(basename "$1")" 52 | 53 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 54 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 55 | local swift_runtime_libs 56 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 57 | for lib in $swift_runtime_libs; do 58 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 59 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 60 | code_sign_if_enabled "${destination}/${lib}" 61 | done 62 | fi 63 | } 64 | 65 | # Copies and strips a vendored dSYM 66 | install_dsym() { 67 | local source="$1" 68 | if [ -r "$source" ]; then 69 | # Copy the dSYM into a the targets temp dir. 70 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 71 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 72 | 73 | local basename 74 | basename="$(basename -s .framework.dSYM "$source")" 75 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" 76 | 77 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 78 | if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then 79 | strip_invalid_archs "$binary" 80 | fi 81 | 82 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then 83 | # Move the stripped file into its final destination. 84 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 85 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 86 | else 87 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 88 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" 89 | fi 90 | fi 91 | } 92 | 93 | # Signs a framework with the provided identity 94 | code_sign_if_enabled() { 95 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 96 | # Use the current code_sign_identitiy 97 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 98 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" 99 | 100 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 101 | code_sign_cmd="$code_sign_cmd &" 102 | fi 103 | echo "$code_sign_cmd" 104 | eval "$code_sign_cmd" 105 | fi 106 | } 107 | 108 | # Strip invalid architectures 109 | strip_invalid_archs() { 110 | binary="$1" 111 | # Get architectures for current target binary 112 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 113 | # Intersect them with the architectures we are building for 114 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 115 | # If there are no archs supported by this binary then warn the user 116 | if [[ -z "$intersected_archs" ]]; then 117 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 118 | STRIP_BINARY_RETVAL=0 119 | return 120 | fi 121 | stripped="" 122 | for arch in $binary_archs; do 123 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 124 | # Strip non-valid architectures in-place 125 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 126 | stripped="$stripped $arch" 127 | fi 128 | done 129 | if [[ "$stripped" ]]; then 130 | echo "Stripped $binary of architectures:$stripped" 131 | fi 132 | STRIP_BINARY_RETVAL=1 133 | } 134 | 135 | 136 | if [[ "$CONFIGURATION" == "Debug" ]]; then 137 | install_framework "${BUILT_PRODUCTS_DIR}/UPMenu/UPMenu.framework" 138 | fi 139 | if [[ "$CONFIGURATION" == "Release" ]]; then 140 | install_framework "${BUILT_PRODUCTS_DIR}/UPMenu/UPMenu.framework" 141 | fi 142 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 143 | wait 144 | fi 145 | -------------------------------------------------------------------------------- /UPMenu/UPMenu/Source/UPMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 67 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Source/UPMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 67 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /UPMenu/UPMenu.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C838344F204417650024A181 /* UPMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C838344D204417650024A181 /* UPMenu.swift */; }; 11 | C8383450204417650024A181 /* UPMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = C838344E204417650024A181 /* UPMenu.xib */; }; 12 | C8383453204417E60024A181 /* UPMenuTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8383451204417E60024A181 /* UPMenuTableViewCell.swift */; }; 13 | C8383454204417E60024A181 /* UPMenuTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C8383452204417E60024A181 /* UPMenuTableViewCell.xib */; }; 14 | C838345620441AA50024A181 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C838345520441AA50024A181 /* Assets.xcassets */; }; 15 | C899FFF32068EF0400C8CF01 /* UPMenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C899FFF22068EF0400C8CF01 /* UPMenuItem.swift */; }; 16 | C8A754DC203DC0BF00C7C234 /* UPMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = C8A754DA203DC0BF00C7C234 /* UPMenu.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | C838344D204417650024A181 /* UPMenu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UPMenu.swift; sourceTree = ""; }; 21 | C838344E204417650024A181 /* UPMenu.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UPMenu.xib; sourceTree = ""; }; 22 | C8383451204417E60024A181 /* UPMenuTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UPMenuTableViewCell.swift; sourceTree = ""; }; 23 | C8383452204417E60024A181 /* UPMenuTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = UPMenuTableViewCell.xib; sourceTree = ""; }; 24 | C838345520441AA50024A181 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 25 | C899FFF22068EF0400C8CF01 /* UPMenuItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UPMenuItem.swift; sourceTree = ""; }; 26 | C8A754D7203DC0BF00C7C234 /* UPMenu.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = UPMenu.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | C8A754DA203DC0BF00C7C234 /* UPMenu.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UPMenu.h; sourceTree = ""; }; 28 | C8A754DB203DC0BF00C7C234 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | C8A754D3203DC0BF00C7C234 /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | ); 37 | runOnlyForDeploymentPostprocessing = 0; 38 | }; 39 | /* End PBXFrameworksBuildPhase section */ 40 | 41 | /* Begin PBXGroup section */ 42 | C838344C204417390024A181 /* Source */ = { 43 | isa = PBXGroup; 44 | children = ( 45 | C8383451204417E60024A181 /* UPMenuTableViewCell.swift */, 46 | C8383452204417E60024A181 /* UPMenuTableViewCell.xib */, 47 | C838344D204417650024A181 /* UPMenu.swift */, 48 | C838344E204417650024A181 /* UPMenu.xib */, 49 | C899FFF22068EF0400C8CF01 /* UPMenuItem.swift */, 50 | ); 51 | path = Source; 52 | sourceTree = ""; 53 | }; 54 | C8A754CD203DC0BF00C7C234 = { 55 | isa = PBXGroup; 56 | children = ( 57 | C8A754D9203DC0BF00C7C234 /* UPMenu */, 58 | C8A754D8203DC0BF00C7C234 /* Products */, 59 | ); 60 | sourceTree = ""; 61 | }; 62 | C8A754D8203DC0BF00C7C234 /* Products */ = { 63 | isa = PBXGroup; 64 | children = ( 65 | C8A754D7203DC0BF00C7C234 /* UPMenu.framework */, 66 | ); 67 | name = Products; 68 | sourceTree = ""; 69 | }; 70 | C8A754D9203DC0BF00C7C234 /* UPMenu */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | C838344C204417390024A181 /* Source */, 74 | C8A754DA203DC0BF00C7C234 /* UPMenu.h */, 75 | C838345520441AA50024A181 /* Assets.xcassets */, 76 | C8A754DB203DC0BF00C7C234 /* Info.plist */, 77 | ); 78 | path = UPMenu; 79 | sourceTree = ""; 80 | }; 81 | /* End PBXGroup section */ 82 | 83 | /* Begin PBXHeadersBuildPhase section */ 84 | C8A754D4203DC0BF00C7C234 /* Headers */ = { 85 | isa = PBXHeadersBuildPhase; 86 | buildActionMask = 2147483647; 87 | files = ( 88 | C8A754DC203DC0BF00C7C234 /* UPMenu.h in Headers */, 89 | ); 90 | runOnlyForDeploymentPostprocessing = 0; 91 | }; 92 | /* End PBXHeadersBuildPhase section */ 93 | 94 | /* Begin PBXNativeTarget section */ 95 | C8A754D6203DC0BF00C7C234 /* UPMenu */ = { 96 | isa = PBXNativeTarget; 97 | buildConfigurationList = C8A754DF203DC0BF00C7C234 /* Build configuration list for PBXNativeTarget "UPMenu" */; 98 | buildPhases = ( 99 | C8A754D2203DC0BF00C7C234 /* Sources */, 100 | C8A754D3203DC0BF00C7C234 /* Frameworks */, 101 | C8A754D4203DC0BF00C7C234 /* Headers */, 102 | C8A754D5203DC0BF00C7C234 /* Resources */, 103 | ); 104 | buildRules = ( 105 | ); 106 | dependencies = ( 107 | ); 108 | name = UPMenu; 109 | productName = UPMenu; 110 | productReference = C8A754D7203DC0BF00C7C234 /* UPMenu.framework */; 111 | productType = "com.apple.product-type.framework"; 112 | }; 113 | /* End PBXNativeTarget section */ 114 | 115 | /* Begin PBXProject section */ 116 | C8A754CE203DC0BF00C7C234 /* Project object */ = { 117 | isa = PBXProject; 118 | attributes = { 119 | LastUpgradeCheck = 0920; 120 | ORGANIZATIONNAME = "Tubik Studio"; 121 | TargetAttributes = { 122 | C8A754D6203DC0BF00C7C234 = { 123 | CreatedOnToolsVersion = 9.2; 124 | LastSwiftMigration = 0920; 125 | ProvisioningStyle = Automatic; 126 | }; 127 | }; 128 | }; 129 | buildConfigurationList = C8A754D1203DC0BF00C7C234 /* Build configuration list for PBXProject "UPMenu" */; 130 | compatibilityVersion = "Xcode 8.0"; 131 | developmentRegion = en; 132 | hasScannedForEncodings = 0; 133 | knownRegions = ( 134 | en, 135 | ); 136 | mainGroup = C8A754CD203DC0BF00C7C234; 137 | productRefGroup = C8A754D8203DC0BF00C7C234 /* Products */; 138 | projectDirPath = ""; 139 | projectRoot = ""; 140 | targets = ( 141 | C8A754D6203DC0BF00C7C234 /* UPMenu */, 142 | ); 143 | }; 144 | /* End PBXProject section */ 145 | 146 | /* Begin PBXResourcesBuildPhase section */ 147 | C8A754D5203DC0BF00C7C234 /* Resources */ = { 148 | isa = PBXResourcesBuildPhase; 149 | buildActionMask = 2147483647; 150 | files = ( 151 | C8383454204417E60024A181 /* UPMenuTableViewCell.xib in Resources */, 152 | C838345620441AA50024A181 /* Assets.xcassets in Resources */, 153 | C8383450204417650024A181 /* UPMenu.xib in Resources */, 154 | ); 155 | runOnlyForDeploymentPostprocessing = 0; 156 | }; 157 | /* End PBXResourcesBuildPhase section */ 158 | 159 | /* Begin PBXSourcesBuildPhase section */ 160 | C8A754D2203DC0BF00C7C234 /* Sources */ = { 161 | isa = PBXSourcesBuildPhase; 162 | buildActionMask = 2147483647; 163 | files = ( 164 | C899FFF32068EF0400C8CF01 /* UPMenuItem.swift in Sources */, 165 | C8383453204417E60024A181 /* UPMenuTableViewCell.swift in Sources */, 166 | C838344F204417650024A181 /* UPMenu.swift in Sources */, 167 | ); 168 | runOnlyForDeploymentPostprocessing = 0; 169 | }; 170 | /* End PBXSourcesBuildPhase section */ 171 | 172 | /* Begin XCBuildConfiguration section */ 173 | C8A754DD203DC0BF00C7C234 /* Debug */ = { 174 | isa = XCBuildConfiguration; 175 | buildSettings = { 176 | ALWAYS_SEARCH_USER_PATHS = NO; 177 | CLANG_ANALYZER_NONNULL = YES; 178 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 179 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 180 | CLANG_CXX_LIBRARY = "libc++"; 181 | CLANG_ENABLE_MODULES = YES; 182 | CLANG_ENABLE_OBJC_ARC = YES; 183 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 184 | CLANG_WARN_BOOL_CONVERSION = YES; 185 | CLANG_WARN_COMMA = YES; 186 | CLANG_WARN_CONSTANT_CONVERSION = YES; 187 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 188 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 189 | CLANG_WARN_EMPTY_BODY = YES; 190 | CLANG_WARN_ENUM_CONVERSION = YES; 191 | CLANG_WARN_INFINITE_RECURSION = YES; 192 | CLANG_WARN_INT_CONVERSION = YES; 193 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 194 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 195 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 196 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 197 | CLANG_WARN_STRICT_PROTOTYPES = YES; 198 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 199 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 200 | CLANG_WARN_UNREACHABLE_CODE = YES; 201 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 202 | CODE_SIGN_IDENTITY = "iPhone Developer"; 203 | COPY_PHASE_STRIP = NO; 204 | CURRENT_PROJECT_VERSION = 1; 205 | DEBUG_INFORMATION_FORMAT = dwarf; 206 | ENABLE_STRICT_OBJC_MSGSEND = YES; 207 | ENABLE_TESTABILITY = YES; 208 | GCC_C_LANGUAGE_STANDARD = gnu11; 209 | GCC_DYNAMIC_NO_PIC = NO; 210 | GCC_NO_COMMON_BLOCKS = YES; 211 | GCC_OPTIMIZATION_LEVEL = 0; 212 | GCC_PREPROCESSOR_DEFINITIONS = ( 213 | "DEBUG=1", 214 | "$(inherited)", 215 | ); 216 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 217 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 218 | GCC_WARN_UNDECLARED_SELECTOR = YES; 219 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 220 | GCC_WARN_UNUSED_FUNCTION = YES; 221 | GCC_WARN_UNUSED_VARIABLE = YES; 222 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 223 | MTL_ENABLE_DEBUG_INFO = YES; 224 | ONLY_ACTIVE_ARCH = YES; 225 | SDKROOT = iphoneos; 226 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 227 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 228 | VERSIONING_SYSTEM = "apple-generic"; 229 | VERSION_INFO_PREFIX = ""; 230 | }; 231 | name = Debug; 232 | }; 233 | C8A754DE203DC0BF00C7C234 /* Release */ = { 234 | isa = XCBuildConfiguration; 235 | buildSettings = { 236 | ALWAYS_SEARCH_USER_PATHS = NO; 237 | CLANG_ANALYZER_NONNULL = YES; 238 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 240 | CLANG_CXX_LIBRARY = "libc++"; 241 | CLANG_ENABLE_MODULES = YES; 242 | CLANG_ENABLE_OBJC_ARC = YES; 243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 244 | CLANG_WARN_BOOL_CONVERSION = YES; 245 | CLANG_WARN_COMMA = YES; 246 | CLANG_WARN_CONSTANT_CONVERSION = YES; 247 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 248 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 249 | CLANG_WARN_EMPTY_BODY = YES; 250 | CLANG_WARN_ENUM_CONVERSION = YES; 251 | CLANG_WARN_INFINITE_RECURSION = YES; 252 | CLANG_WARN_INT_CONVERSION = YES; 253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 254 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 255 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 256 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 257 | CLANG_WARN_STRICT_PROTOTYPES = YES; 258 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 259 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 260 | CLANG_WARN_UNREACHABLE_CODE = YES; 261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 262 | CODE_SIGN_IDENTITY = "iPhone Developer"; 263 | COPY_PHASE_STRIP = NO; 264 | CURRENT_PROJECT_VERSION = 1; 265 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 266 | ENABLE_NS_ASSERTIONS = NO; 267 | ENABLE_STRICT_OBJC_MSGSEND = YES; 268 | GCC_C_LANGUAGE_STANDARD = gnu11; 269 | GCC_NO_COMMON_BLOCKS = YES; 270 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 271 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 272 | GCC_WARN_UNDECLARED_SELECTOR = YES; 273 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 274 | GCC_WARN_UNUSED_FUNCTION = YES; 275 | GCC_WARN_UNUSED_VARIABLE = YES; 276 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 277 | MTL_ENABLE_DEBUG_INFO = NO; 278 | SDKROOT = iphoneos; 279 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 280 | VALIDATE_PRODUCT = YES; 281 | VERSIONING_SYSTEM = "apple-generic"; 282 | VERSION_INFO_PREFIX = ""; 283 | }; 284 | name = Release; 285 | }; 286 | C8A754E0203DC0BF00C7C234 /* Debug */ = { 287 | isa = XCBuildConfiguration; 288 | buildSettings = { 289 | CLANG_ENABLE_MODULES = YES; 290 | CODE_SIGN_IDENTITY = ""; 291 | CODE_SIGN_STYLE = Automatic; 292 | DEFINES_MODULE = YES; 293 | DEVELOPMENT_TEAM = 2R7KRC44ZL; 294 | DYLIB_COMPATIBILITY_VERSION = 1; 295 | DYLIB_CURRENT_VERSION = 1; 296 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 297 | INFOPLIST_FILE = UPMenu/Info.plist; 298 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 299 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 300 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 301 | PRODUCT_BUNDLE_IDENTIFIER = com.tubikstudio.UPMenu; 302 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 303 | SKIP_INSTALL = YES; 304 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 305 | SWIFT_VERSION = 4.0; 306 | TARGETED_DEVICE_FAMILY = "1,2"; 307 | }; 308 | name = Debug; 309 | }; 310 | C8A754E1203DC0BF00C7C234 /* Release */ = { 311 | isa = XCBuildConfiguration; 312 | buildSettings = { 313 | CLANG_ENABLE_MODULES = YES; 314 | CODE_SIGN_IDENTITY = ""; 315 | CODE_SIGN_STYLE = Automatic; 316 | DEFINES_MODULE = YES; 317 | DEVELOPMENT_TEAM = 2R7KRC44ZL; 318 | DYLIB_COMPATIBILITY_VERSION = 1; 319 | DYLIB_CURRENT_VERSION = 1; 320 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 321 | INFOPLIST_FILE = UPMenu/Info.plist; 322 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 323 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 324 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 325 | PRODUCT_BUNDLE_IDENTIFIER = com.tubikstudio.UPMenu; 326 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 327 | SKIP_INSTALL = YES; 328 | SWIFT_VERSION = 4.0; 329 | TARGETED_DEVICE_FAMILY = "1,2"; 330 | }; 331 | name = Release; 332 | }; 333 | /* End XCBuildConfiguration section */ 334 | 335 | /* Begin XCConfigurationList section */ 336 | C8A754D1203DC0BF00C7C234 /* Build configuration list for PBXProject "UPMenu" */ = { 337 | isa = XCConfigurationList; 338 | buildConfigurations = ( 339 | C8A754DD203DC0BF00C7C234 /* Debug */, 340 | C8A754DE203DC0BF00C7C234 /* Release */, 341 | ); 342 | defaultConfigurationIsVisible = 0; 343 | defaultConfigurationName = Release; 344 | }; 345 | C8A754DF203DC0BF00C7C234 /* Build configuration list for PBXNativeTarget "UPMenu" */ = { 346 | isa = XCConfigurationList; 347 | buildConfigurations = ( 348 | C8A754E0203DC0BF00C7C234 /* Debug */, 349 | C8A754E1203DC0BF00C7C234 /* Release */, 350 | ); 351 | defaultConfigurationIsVisible = 0; 352 | defaultConfigurationName = Release; 353 | }; 354 | /* End XCConfigurationList section */ 355 | }; 356 | rootObject = C8A754CE203DC0BF00C7C234 /* Project object */; 357 | } 358 | -------------------------------------------------------------------------------- /Example/Example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 7F0CE4B9720D2A3B9BCEA33D /* Pods_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 29DDD0079E4032915F827955 /* Pods_Example.framework */; }; 11 | C899FFF52068F15700C8CF01 /* MenuTitleView.xib in Resources */ = {isa = PBXBuildFile; fileRef = C899FFF42068F15700C8CF01 /* MenuTitleView.xib */; }; 12 | C8A754EF203DC11F00C7C234 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8A754EE203DC11F00C7C234 /* AppDelegate.swift */; }; 13 | C8A754F1203DC11F00C7C234 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8A754F0203DC11F00C7C234 /* ViewController.swift */; }; 14 | C8A754F4203DC11F00C7C234 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C8A754F2203DC11F00C7C234 /* Main.storyboard */; }; 15 | C8A754F6203DC11F00C7C234 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C8A754F5203DC11F00C7C234 /* Assets.xcassets */; }; 16 | C8A754F9203DC11F00C7C234 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C8A754F7203DC11F00C7C234 /* LaunchScreen.storyboard */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | 29DDD0079E4032915F827955 /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 21 | 39E3AEDB355BCCE0E4266790 /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Example/Pods-Example.release.xcconfig"; sourceTree = ""; }; 22 | 8C196959FEBCF2FB55A8260C /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example/Pods-Example.debug.xcconfig"; sourceTree = ""; }; 23 | C899FFF42068F15700C8CF01 /* MenuTitleView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MenuTitleView.xib; sourceTree = ""; }; 24 | C8A754EB203DC11F00C7C234 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | C8A754EE203DC11F00C7C234 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 26 | C8A754F0203DC11F00C7C234 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 27 | C8A754F3203DC11F00C7C234 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 28 | C8A754F5203DC11F00C7C234 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 29 | C8A754F8203DC11F00C7C234 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 30 | C8A754FA203DC11F00C7C234 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 31 | /* End PBXFileReference section */ 32 | 33 | /* Begin PBXFrameworksBuildPhase section */ 34 | C8A754E8203DC11F00C7C234 /* Frameworks */ = { 35 | isa = PBXFrameworksBuildPhase; 36 | buildActionMask = 2147483647; 37 | files = ( 38 | 7F0CE4B9720D2A3B9BCEA33D /* Pods_Example.framework in Frameworks */, 39 | ); 40 | runOnlyForDeploymentPostprocessing = 0; 41 | }; 42 | /* End PBXFrameworksBuildPhase section */ 43 | 44 | /* Begin PBXGroup section */ 45 | B35C5E5708FB0555459759BB /* Frameworks */ = { 46 | isa = PBXGroup; 47 | children = ( 48 | 29DDD0079E4032915F827955 /* Pods_Example.framework */, 49 | ); 50 | name = Frameworks; 51 | sourceTree = ""; 52 | }; 53 | C8A754E2203DC11F00C7C234 = { 54 | isa = PBXGroup; 55 | children = ( 56 | C8A754ED203DC11F00C7C234 /* Example */, 57 | C8A754EC203DC11F00C7C234 /* Products */, 58 | E4516A4620091CABAC0F8421 /* Pods */, 59 | B35C5E5708FB0555459759BB /* Frameworks */, 60 | ); 61 | sourceTree = ""; 62 | }; 63 | C8A754EC203DC11F00C7C234 /* Products */ = { 64 | isa = PBXGroup; 65 | children = ( 66 | C8A754EB203DC11F00C7C234 /* Example.app */, 67 | ); 68 | name = Products; 69 | sourceTree = ""; 70 | }; 71 | C8A754ED203DC11F00C7C234 /* Example */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | C8A754EE203DC11F00C7C234 /* AppDelegate.swift */, 75 | C8A754F0203DC11F00C7C234 /* ViewController.swift */, 76 | C8A754F2203DC11F00C7C234 /* Main.storyboard */, 77 | C8A754F5203DC11F00C7C234 /* Assets.xcassets */, 78 | C8A754F7203DC11F00C7C234 /* LaunchScreen.storyboard */, 79 | C8A754FA203DC11F00C7C234 /* Info.plist */, 80 | C899FFF42068F15700C8CF01 /* MenuTitleView.xib */, 81 | ); 82 | path = Example; 83 | sourceTree = ""; 84 | }; 85 | E4516A4620091CABAC0F8421 /* Pods */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 8C196959FEBCF2FB55A8260C /* Pods-Example.debug.xcconfig */, 89 | 39E3AEDB355BCCE0E4266790 /* Pods-Example.release.xcconfig */, 90 | ); 91 | name = Pods; 92 | sourceTree = ""; 93 | }; 94 | /* End PBXGroup section */ 95 | 96 | /* Begin PBXNativeTarget section */ 97 | C8A754EA203DC11F00C7C234 /* Example */ = { 98 | isa = PBXNativeTarget; 99 | buildConfigurationList = C8A754FD203DC11F00C7C234 /* Build configuration list for PBXNativeTarget "Example" */; 100 | buildPhases = ( 101 | 0915728ED7D96EE1949F271D /* [CP] Check Pods Manifest.lock */, 102 | C8A754E7203DC11F00C7C234 /* Sources */, 103 | C8A754E8203DC11F00C7C234 /* Frameworks */, 104 | C8A754E9203DC11F00C7C234 /* Resources */, 105 | 9ED65E214738307800D39392 /* [CP] Embed Pods Frameworks */, 106 | FE6B949A7D5CB77B39628A75 /* [CP] Copy Pods Resources */, 107 | ); 108 | buildRules = ( 109 | ); 110 | dependencies = ( 111 | ); 112 | name = Example; 113 | productName = Example; 114 | productReference = C8A754EB203DC11F00C7C234 /* Example.app */; 115 | productType = "com.apple.product-type.application"; 116 | }; 117 | /* End PBXNativeTarget section */ 118 | 119 | /* Begin PBXProject section */ 120 | C8A754E3203DC11F00C7C234 /* Project object */ = { 121 | isa = PBXProject; 122 | attributes = { 123 | LastSwiftUpdateCheck = 0920; 124 | LastUpgradeCheck = 0920; 125 | ORGANIZATIONNAME = "Tubik Studio"; 126 | TargetAttributes = { 127 | C8A754EA203DC11F00C7C234 = { 128 | CreatedOnToolsVersion = 9.2; 129 | ProvisioningStyle = Automatic; 130 | }; 131 | }; 132 | }; 133 | buildConfigurationList = C8A754E6203DC11F00C7C234 /* Build configuration list for PBXProject "Example" */; 134 | compatibilityVersion = "Xcode 8.0"; 135 | developmentRegion = en; 136 | hasScannedForEncodings = 0; 137 | knownRegions = ( 138 | en, 139 | Base, 140 | ); 141 | mainGroup = C8A754E2203DC11F00C7C234; 142 | productRefGroup = C8A754EC203DC11F00C7C234 /* Products */; 143 | projectDirPath = ""; 144 | projectRoot = ""; 145 | targets = ( 146 | C8A754EA203DC11F00C7C234 /* Example */, 147 | ); 148 | }; 149 | /* End PBXProject section */ 150 | 151 | /* Begin PBXResourcesBuildPhase section */ 152 | C8A754E9203DC11F00C7C234 /* Resources */ = { 153 | isa = PBXResourcesBuildPhase; 154 | buildActionMask = 2147483647; 155 | files = ( 156 | C899FFF52068F15700C8CF01 /* MenuTitleView.xib in Resources */, 157 | C8A754F9203DC11F00C7C234 /* LaunchScreen.storyboard in Resources */, 158 | C8A754F6203DC11F00C7C234 /* Assets.xcassets in Resources */, 159 | C8A754F4203DC11F00C7C234 /* Main.storyboard in Resources */, 160 | ); 161 | runOnlyForDeploymentPostprocessing = 0; 162 | }; 163 | /* End PBXResourcesBuildPhase section */ 164 | 165 | /* Begin PBXShellScriptBuildPhase section */ 166 | 0915728ED7D96EE1949F271D /* [CP] Check Pods Manifest.lock */ = { 167 | isa = PBXShellScriptBuildPhase; 168 | buildActionMask = 2147483647; 169 | files = ( 170 | ); 171 | inputPaths = ( 172 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 173 | "${PODS_ROOT}/Manifest.lock", 174 | ); 175 | name = "[CP] Check Pods Manifest.lock"; 176 | outputPaths = ( 177 | "$(DERIVED_FILE_DIR)/Pods-Example-checkManifestLockResult.txt", 178 | ); 179 | runOnlyForDeploymentPostprocessing = 0; 180 | shellPath = /bin/sh; 181 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 182 | showEnvVarsInLog = 0; 183 | }; 184 | 9ED65E214738307800D39392 /* [CP] Embed Pods Frameworks */ = { 185 | isa = PBXShellScriptBuildPhase; 186 | buildActionMask = 2147483647; 187 | files = ( 188 | ); 189 | inputPaths = ( 190 | "${SRCROOT}/Pods/Target Support Files/Pods-Example/Pods-Example-frameworks.sh", 191 | "${BUILT_PRODUCTS_DIR}/UPMenu/UPMenu.framework", 192 | ); 193 | name = "[CP] Embed Pods Frameworks"; 194 | outputPaths = ( 195 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/UPMenu.framework", 196 | ); 197 | runOnlyForDeploymentPostprocessing = 0; 198 | shellPath = /bin/sh; 199 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Example/Pods-Example-frameworks.sh\"\n"; 200 | showEnvVarsInLog = 0; 201 | }; 202 | FE6B949A7D5CB77B39628A75 /* [CP] Copy Pods Resources */ = { 203 | isa = PBXShellScriptBuildPhase; 204 | buildActionMask = 2147483647; 205 | files = ( 206 | ); 207 | inputPaths = ( 208 | ); 209 | name = "[CP] Copy Pods Resources"; 210 | outputPaths = ( 211 | ); 212 | runOnlyForDeploymentPostprocessing = 0; 213 | shellPath = /bin/sh; 214 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Example/Pods-Example-resources.sh\"\n"; 215 | showEnvVarsInLog = 0; 216 | }; 217 | /* End PBXShellScriptBuildPhase section */ 218 | 219 | /* Begin PBXSourcesBuildPhase section */ 220 | C8A754E7203DC11F00C7C234 /* Sources */ = { 221 | isa = PBXSourcesBuildPhase; 222 | buildActionMask = 2147483647; 223 | files = ( 224 | C8A754F1203DC11F00C7C234 /* ViewController.swift in Sources */, 225 | C8A754EF203DC11F00C7C234 /* AppDelegate.swift in Sources */, 226 | ); 227 | runOnlyForDeploymentPostprocessing = 0; 228 | }; 229 | /* End PBXSourcesBuildPhase section */ 230 | 231 | /* Begin PBXVariantGroup section */ 232 | C8A754F2203DC11F00C7C234 /* Main.storyboard */ = { 233 | isa = PBXVariantGroup; 234 | children = ( 235 | C8A754F3203DC11F00C7C234 /* Base */, 236 | ); 237 | name = Main.storyboard; 238 | sourceTree = ""; 239 | }; 240 | C8A754F7203DC11F00C7C234 /* LaunchScreen.storyboard */ = { 241 | isa = PBXVariantGroup; 242 | children = ( 243 | C8A754F8203DC11F00C7C234 /* Base */, 244 | ); 245 | name = LaunchScreen.storyboard; 246 | sourceTree = ""; 247 | }; 248 | /* End PBXVariantGroup section */ 249 | 250 | /* Begin XCBuildConfiguration section */ 251 | C8A754FB203DC11F00C7C234 /* Debug */ = { 252 | isa = XCBuildConfiguration; 253 | buildSettings = { 254 | ALWAYS_SEARCH_USER_PATHS = NO; 255 | CLANG_ANALYZER_NONNULL = YES; 256 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 257 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 258 | CLANG_CXX_LIBRARY = "libc++"; 259 | CLANG_ENABLE_MODULES = YES; 260 | CLANG_ENABLE_OBJC_ARC = YES; 261 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 262 | CLANG_WARN_BOOL_CONVERSION = YES; 263 | CLANG_WARN_COMMA = YES; 264 | CLANG_WARN_CONSTANT_CONVERSION = YES; 265 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 266 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 267 | CLANG_WARN_EMPTY_BODY = YES; 268 | CLANG_WARN_ENUM_CONVERSION = YES; 269 | CLANG_WARN_INFINITE_RECURSION = YES; 270 | CLANG_WARN_INT_CONVERSION = YES; 271 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 272 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 273 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 274 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 275 | CLANG_WARN_STRICT_PROTOTYPES = YES; 276 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 277 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 278 | CLANG_WARN_UNREACHABLE_CODE = YES; 279 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 280 | CODE_SIGN_IDENTITY = "iPhone Developer"; 281 | COPY_PHASE_STRIP = NO; 282 | DEBUG_INFORMATION_FORMAT = dwarf; 283 | ENABLE_STRICT_OBJC_MSGSEND = YES; 284 | ENABLE_TESTABILITY = YES; 285 | GCC_C_LANGUAGE_STANDARD = gnu11; 286 | GCC_DYNAMIC_NO_PIC = NO; 287 | GCC_NO_COMMON_BLOCKS = YES; 288 | GCC_OPTIMIZATION_LEVEL = 0; 289 | GCC_PREPROCESSOR_DEFINITIONS = ( 290 | "DEBUG=1", 291 | "$(inherited)", 292 | ); 293 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 294 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 295 | GCC_WARN_UNDECLARED_SELECTOR = YES; 296 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 297 | GCC_WARN_UNUSED_FUNCTION = YES; 298 | GCC_WARN_UNUSED_VARIABLE = YES; 299 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 300 | MTL_ENABLE_DEBUG_INFO = YES; 301 | ONLY_ACTIVE_ARCH = YES; 302 | SDKROOT = iphoneos; 303 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 304 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 305 | }; 306 | name = Debug; 307 | }; 308 | C8A754FC203DC11F00C7C234 /* Release */ = { 309 | isa = XCBuildConfiguration; 310 | buildSettings = { 311 | ALWAYS_SEARCH_USER_PATHS = NO; 312 | CLANG_ANALYZER_NONNULL = YES; 313 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 314 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 315 | CLANG_CXX_LIBRARY = "libc++"; 316 | CLANG_ENABLE_MODULES = YES; 317 | CLANG_ENABLE_OBJC_ARC = YES; 318 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 319 | CLANG_WARN_BOOL_CONVERSION = YES; 320 | CLANG_WARN_COMMA = YES; 321 | CLANG_WARN_CONSTANT_CONVERSION = YES; 322 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 323 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 324 | CLANG_WARN_EMPTY_BODY = YES; 325 | CLANG_WARN_ENUM_CONVERSION = YES; 326 | CLANG_WARN_INFINITE_RECURSION = YES; 327 | CLANG_WARN_INT_CONVERSION = YES; 328 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 329 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 330 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 331 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 332 | CLANG_WARN_STRICT_PROTOTYPES = YES; 333 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 334 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 335 | CLANG_WARN_UNREACHABLE_CODE = YES; 336 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 337 | CODE_SIGN_IDENTITY = "iPhone Developer"; 338 | COPY_PHASE_STRIP = NO; 339 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 340 | ENABLE_NS_ASSERTIONS = NO; 341 | ENABLE_STRICT_OBJC_MSGSEND = YES; 342 | GCC_C_LANGUAGE_STANDARD = gnu11; 343 | GCC_NO_COMMON_BLOCKS = YES; 344 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 345 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 346 | GCC_WARN_UNDECLARED_SELECTOR = YES; 347 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 348 | GCC_WARN_UNUSED_FUNCTION = YES; 349 | GCC_WARN_UNUSED_VARIABLE = YES; 350 | IPHONEOS_DEPLOYMENT_TARGET = 11.2; 351 | MTL_ENABLE_DEBUG_INFO = NO; 352 | SDKROOT = iphoneos; 353 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 354 | VALIDATE_PRODUCT = YES; 355 | }; 356 | name = Release; 357 | }; 358 | C8A754FE203DC11F00C7C234 /* Debug */ = { 359 | isa = XCBuildConfiguration; 360 | baseConfigurationReference = 8C196959FEBCF2FB55A8260C /* Pods-Example.debug.xcconfig */; 361 | buildSettings = { 362 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 363 | CODE_SIGN_STYLE = Automatic; 364 | DEVELOPMENT_TEAM = 2R7KRC44ZL; 365 | INFOPLIST_FILE = Example/Info.plist; 366 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 367 | PRODUCT_BUNDLE_IDENTIFIER = com.tubikstudio.Example; 368 | PRODUCT_NAME = "$(TARGET_NAME)"; 369 | SWIFT_VERSION = 4.0; 370 | TARGETED_DEVICE_FAMILY = "1,2"; 371 | }; 372 | name = Debug; 373 | }; 374 | C8A754FF203DC11F00C7C234 /* Release */ = { 375 | isa = XCBuildConfiguration; 376 | baseConfigurationReference = 39E3AEDB355BCCE0E4266790 /* Pods-Example.release.xcconfig */; 377 | buildSettings = { 378 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 379 | CODE_SIGN_STYLE = Automatic; 380 | DEVELOPMENT_TEAM = 2R7KRC44ZL; 381 | INFOPLIST_FILE = Example/Info.plist; 382 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 383 | PRODUCT_BUNDLE_IDENTIFIER = com.tubikstudio.Example; 384 | PRODUCT_NAME = "$(TARGET_NAME)"; 385 | SWIFT_VERSION = 4.0; 386 | TARGETED_DEVICE_FAMILY = "1,2"; 387 | }; 388 | name = Release; 389 | }; 390 | /* End XCBuildConfiguration section */ 391 | 392 | /* Begin XCConfigurationList section */ 393 | C8A754E6203DC11F00C7C234 /* Build configuration list for PBXProject "Example" */ = { 394 | isa = XCConfigurationList; 395 | buildConfigurations = ( 396 | C8A754FB203DC11F00C7C234 /* Debug */, 397 | C8A754FC203DC11F00C7C234 /* Release */, 398 | ); 399 | defaultConfigurationIsVisible = 0; 400 | defaultConfigurationName = Release; 401 | }; 402 | C8A754FD203DC11F00C7C234 /* Build configuration list for PBXNativeTarget "Example" */ = { 403 | isa = XCConfigurationList; 404 | buildConfigurations = ( 405 | C8A754FE203DC11F00C7C234 /* Debug */, 406 | C8A754FF203DC11F00C7C234 /* Release */, 407 | ); 408 | defaultConfigurationIsVisible = 0; 409 | defaultConfigurationName = Release; 410 | }; 411 | /* End XCConfigurationList section */ 412 | }; 413 | rootObject = C8A754E3203DC11F00C7C234 /* Project object */; 414 | } 415 | -------------------------------------------------------------------------------- /UPMenu/UPMenu/Source/UPMenu.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UPMenu.swift 3 | // UPMenu 4 | // 5 | // Created by Tubik Studio on 16/3/18. 6 | // Copyright © 2018 Tubik Studio. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol UPMenuDelegate: class { 12 | 13 | func upMenu(_ upMenu: UPMenu, didTapOnHamburgerButton sender: UIButton) 14 | func upMenu(_ upMenu: UPMenu, didTapOnCloseButton sender: UIButton) 15 | func upMenu(_ upMenu: UPMenu, didSelectMenuItemAt indexPath: IndexPath) 16 | func upMenuWillAppear() 17 | func upMenuDidAppear() 18 | func upMenuWillClose() 19 | func upMenuDidClosed() 20 | 21 | } 22 | 23 | public extension UPMenuDelegate { 24 | 25 | func upMenu(_ upMenu: UPMenu, didTapOnHamburgerButton sender: UIButton) {} 26 | func upMenu(_ upMenu: UPMenu, didTapOnCloseButton sender: UIButton) {} 27 | func upMenu(_ upMenu: UPMenu, didSelectMenuItemAt indexPath: IndexPath) {} 28 | func upMenuWillAppear() {} 29 | func upMenuDidAppear() {} 30 | func upMenuWillClose() {} 31 | func upMenuDidClosed() {} 32 | 33 | } 34 | 35 | @IBDesignable public class UPMenu: UIView { 36 | 37 | public struct Appearance { 38 | public var menuImage: UIImage? 39 | public var closeMenuImage: UIImage? 40 | public var closedMenuColor = UIColor.white 41 | public var titleViewBackgorundColor = UIColor.white 42 | public var menuItemsViewBackgroundColor = UIColor.black 43 | public var menuItemCellBackgroundColor = UIColor.black 44 | public var menuItemCellTitleFont = UIFont.systemFont(ofSize: 24) 45 | public var menuItemCellTitleColor = UIColor.white 46 | } 47 | 48 | private struct Constants { 49 | static let closedMenuSize = CGSize(width: 57, height: 57) 50 | static let hamburgerButtonSize = CGSize(width: 24, height: 20) 51 | } 52 | 53 | private enum MenuState { 54 | case closed, expanded 55 | 56 | var image: UIImage? { 57 | switch self { 58 | case .closed: 59 | return UIImage(named: "closeIcn", in: Bundle(for: UPMenu.self), compatibleWith: nil) 60 | case .expanded: 61 | return UIImage(named: "menuIcn", in: Bundle(for: UPMenu.self), compatibleWith: nil) 62 | } 63 | } 64 | } 65 | 66 | // MARK: - Properties 67 | 68 | public weak var delegate: UPMenuDelegate? 69 | 70 | public private(set) var menuItems = [UPMenuItem]() 71 | 72 | public var menuItemsListHeight: CGFloat = 217 { 73 | didSet { 74 | menuItemsContainerHeightConstraint.constant = menuItemsListHeight 75 | layoutIfNeeded() 76 | } 77 | } 78 | 79 | public var menuItemHeight: CGFloat = 44 80 | 81 | public var appearance = Appearance() { 82 | didSet { 83 | updateAppearance(for: self.menuState) 84 | } 85 | } 86 | 87 | public var startPoint: CGPoint? { 88 | didSet { 89 | center = startPoint ?? superview?.center ?? .zero 90 | } 91 | } 92 | 93 | @IBOutlet public private(set) weak var hamburgerMenuButton: UIButton! 94 | 95 | @IBOutlet public private(set) weak var closeButton: UIButton! 96 | 97 | @IBOutlet private weak var mainContentView: UIView! 98 | @IBOutlet private weak var menuItemsContainerView: UIView! 99 | @IBOutlet private weak var hamburgerMenuButtonWidthConstraint: NSLayoutConstraint! 100 | @IBOutlet private weak var hamburgerMenuButtonHeightConstraint: NSLayoutConstraint! 101 | @IBOutlet private weak var tableViewTopConstraint: NSLayoutConstraint! 102 | @IBOutlet private weak var menuItemsContainerHeightConstraint: NSLayoutConstraint! 103 | @IBOutlet private weak var tableView: UITableView! 104 | private let maskLayer = CALayer() 105 | private var isGoingToHide: Bool = false 106 | private var menuState: MenuState = .closed 107 | private var animating: Bool = false 108 | 109 | // MARK: - UIView 110 | 111 | public override init(frame: CGRect) { 112 | super.init(frame: frame) 113 | 114 | xibSetup() 115 | } 116 | 117 | required public init?(coder aDecoder: NSCoder) { 118 | super.init(coder: aDecoder) 119 | 120 | xibSetup() 121 | } 122 | 123 | override public func point(inside point: CGPoint, with event: UIEvent?) -> Bool { 124 | if menuState == .expanded { 125 | return true 126 | } else { 127 | return maskLayer.frame.contains(point) 128 | } 129 | } 130 | 131 | override public func layoutSubviews() { 132 | super.layoutSubviews() 133 | if !animating { 134 | setupInitialMask() 135 | } 136 | } 137 | 138 | // MARK: - Methods 139 | 140 | public func addTitleView(_ titleView: UIView) { 141 | mainContentView.subviews.forEach { $0.removeFromSuperview() } 142 | mainContentView.addSubview(titleView) 143 | 144 | titleView.translatesAutoresizingMaskIntoConstraints = false 145 | 146 | mainContentView.addConstraint(NSLayoutConstraint(item: titleView, 147 | attribute: .trailing, 148 | relatedBy: .equal, 149 | toItem: mainContentView, 150 | attribute: .trailing, 151 | multiplier: 1, 152 | constant: 0)) 153 | 154 | mainContentView.addConstraint(NSLayoutConstraint(item: titleView, 155 | attribute: .leading, 156 | relatedBy: .equal, 157 | toItem: mainContentView, 158 | attribute: .leading, 159 | multiplier: 1, 160 | constant: 0)) 161 | 162 | mainContentView.addConstraint(NSLayoutConstraint(item: titleView, 163 | attribute: .top, 164 | relatedBy: .equal, 165 | toItem: mainContentView, 166 | attribute: .top, 167 | multiplier: 1, 168 | constant: 0)) 169 | 170 | mainContentView.addConstraint(NSLayoutConstraint(item: titleView, 171 | attribute: .bottom, 172 | relatedBy: .equal, 173 | toItem: mainContentView, 174 | attribute: .bottom, 175 | multiplier: 1, 176 | constant: 0)) 177 | mainContentView.subviews.forEach { 178 | $0.isHidden = menuState == .closed 179 | } 180 | } 181 | 182 | public func updateMenuItems(with newItems: [UPMenuItem]) { 183 | menuItems = newItems 184 | tableView.reloadData() 185 | } 186 | 187 | public func expand() { 188 | guard let superView = self.superview else { return } 189 | superView.isUserInteractionEnabled = false 190 | delegate?.upMenuWillAppear() 191 | if startPoint == nil { 192 | startPoint = center 193 | } 194 | UIView.animate(withDuration: 0.2, 195 | delay: 0, 196 | options: [.curveEaseIn, .curveEaseOut], 197 | animations: { 198 | self.animating = true 199 | self.hamburgerMenuButtonWidthConstraint.constant = 0 200 | self.hamburgerMenuButton.alpha = 0 201 | self.tableViewTopConstraint.constant = superView.bounds.height 202 | self.layoutIfNeeded() 203 | }, 204 | completion: { finished in 205 | guard finished else { return } 206 | UIView.animate(withDuration: 0.2, 207 | delay: 0, 208 | options: [.curveEaseIn, .curveEaseOut], 209 | animations: { 210 | self.center = CGPoint(x: superView.center.x, y: superView.center.y + 80) 211 | }, 212 | completion: { finished in 213 | guard finished else { return } 214 | self.updateAppearance(for: .expanded) 215 | self.mainContentView.subviews.forEach { 216 | $0.isHidden = false 217 | } 218 | UIView.animate(withDuration: 0.3, 219 | delay: 0, 220 | options: [.curveEaseIn, .curveEaseOut], 221 | animations: { 222 | self.tableViewTopConstraint.constant = 0 223 | self.maskLayer.bounds = CGRect(x: 0, y: 0, width: 1600, height: 1600) 224 | self.center = CGPoint(x: superView.center.x, y: superView.center.y + 5) 225 | self.layoutIfNeeded() 226 | }, 227 | completion: { finished in 228 | guard finished else { return } 229 | UIView.animate(withDuration: 0.2, 230 | animations: { 231 | self.center = superView.center 232 | }, 233 | completion: { finished in 234 | guard finished else { return } 235 | self.animating = false 236 | superView.isUserInteractionEnabled = true 237 | self.menuState = .expanded 238 | self.delegate?.upMenuDidAppear() 239 | }) 240 | }) 241 | }) 242 | 243 | }) 244 | } 245 | 246 | public func close() { 247 | guard let superView = self.superview else { return } 248 | self.animating = true 249 | superView.isUserInteractionEnabled = false 250 | delegate?.upMenuWillClose() 251 | isGoingToHide = true 252 | 253 | UIView.animate(withDuration: 0.3, 254 | delay: 0, 255 | options: [.curveEaseIn], 256 | animations: { 257 | self.maskLayer.bounds = CGRect(origin: .zero, size: Constants.closedMenuSize) 258 | self.tableViewTopConstraint.constant = superView.bounds.height 259 | self.layoutIfNeeded() 260 | self.mainContentView.subviews.forEach { 261 | $0.isHidden = true 262 | } 263 | }, 264 | completion: { finished in 265 | self.updateAppearance(for: .closed) 266 | guard finished else { return } 267 | UIView.animate(withDuration: 0.2, 268 | delay: 0, 269 | options: [.curveEaseIn, .curveEaseOut], 270 | animations: { 271 | self.center = self.startPoint ?? superView.center 272 | }, 273 | completion: { finished in 274 | guard finished else { return } 275 | UIView.animate(withDuration: 0.1, 276 | delay: 0, 277 | options: [.curveEaseIn, .curveEaseOut], 278 | animations: { 279 | self.rotate(degrees: -180) 280 | self.hamburgerMenuButtonHeightConstraint.constant = Constants.hamburgerButtonSize.height 281 | self.hamburgerMenuButtonWidthConstraint.constant = Constants.hamburgerButtonSize.width 282 | self.hamburgerMenuButton.alpha = 1 283 | self.layoutIfNeeded() 284 | }, 285 | completion: { finished in 286 | guard finished else { return } 287 | self.rotate(degrees: -180) 288 | self.animating = false 289 | self.isGoingToHide = false 290 | superView.isUserInteractionEnabled = true 291 | self.menuState = .closed 292 | self.delegate?.upMenuDidClosed() 293 | }) 294 | }) 295 | }) 296 | } 297 | 298 | @IBAction private func touchUpInsideHamburgerMenuButton(_ sender: UIButton) { 299 | delegate?.upMenu(self, didTapOnHamburgerButton: sender) 300 | expand() 301 | } 302 | 303 | @IBAction private func touchUpInsideCloseButton(_ sender: UIButton) { 304 | delegate?.upMenu(self, didTapOnCloseButton: sender) 305 | close() 306 | } 307 | 308 | private func xibSetup() { 309 | let view = loadViewFromNib() 310 | view.frame = bounds 311 | view.autoresizingMask = [.flexibleWidth, .flexibleHeight] 312 | addSubview(view) 313 | closeButton.isExclusiveTouch = true 314 | tableView.register(UINib(nibName: "UPMenuTableViewCell", bundle: Bundle(for: UPMenu.self)), 315 | forCellReuseIdentifier: UPMenuTableViewCell.reuseIdentifier) 316 | updateAppearance(for: menuState) 317 | } 318 | 319 | private func loadViewFromNib() -> UIView { 320 | let bundle = Bundle(for: UPMenu.self) 321 | let nib = UINib(nibName: String(describing: UPMenu.self), bundle: bundle) 322 | let view = nib.instantiate(withOwner: self, options: nil).first as! UIView 323 | return view 324 | } 325 | 326 | private func setupInitialMask() { 327 | maskLayer.contents = UIImage(named: "menu", in: Bundle(for: UPMenu.self), compatibleWith: nil)?.cgImage 328 | maskLayer.frame = CGRect(origin: .zero, size: Constants.closedMenuSize) 329 | maskLayer.position = CGPoint(x: frame.size.width/2.0, y: frame.size.height/2.0) 330 | layer.mask = maskLayer 331 | } 332 | 333 | private func rotate(degrees: CGFloat) { 334 | let radians = degrees / 180.0 * CGFloat.pi 335 | let rotation = self.transform.rotated(by: radians) 336 | self.transform = rotation 337 | } 338 | 339 | private func updateAppearance(for menuState: MenuState) { 340 | mainContentView.backgroundColor = menuState == .closed ? appearance.closedMenuColor : appearance.titleViewBackgorundColor 341 | menuItemsContainerView.backgroundColor = menuState == .closed ? appearance.closedMenuColor : appearance.menuItemsViewBackgroundColor 342 | tableView.isHidden = menuState == .closed 343 | closeButton.setImage(appearance.closeMenuImage ?? MenuState.closed.image, for: .normal) 344 | hamburgerMenuButton.setImage(appearance.menuImage ?? MenuState.expanded.image, for: .normal) 345 | tableView.reloadData() 346 | } 347 | } 348 | 349 | // MARK: - UITableViewDelegate 350 | 351 | extension UPMenu: UITableViewDelegate { 352 | 353 | public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 354 | return menuItemHeight 355 | } 356 | 357 | public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 358 | delegate?.upMenu(self, didSelectMenuItemAt: indexPath) 359 | } 360 | 361 | } 362 | 363 | // MARK: - UITableViewDataSource 364 | 365 | extension UPMenu: UITableViewDataSource { 366 | 367 | public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 368 | return menuItems.count 369 | } 370 | 371 | public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 372 | let cell = tableView.dequeueReusableCell(withIdentifier: UPMenuTableViewCell.reuseIdentifier, 373 | for: indexPath) as! UPMenuTableViewCell 374 | 375 | cell.configure(menuItemImage: menuItems[indexPath.row].image, 376 | menuItemTitle: menuItems[indexPath.row].title, 377 | menuAppearance: appearance) 378 | 379 | return cell 380 | } 381 | 382 | } 383 | -------------------------------------------------------------------------------- /Example/Pods/UPMenu/UPMenu/UPMenu/Source/UPMenu.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UPMenu.swift 3 | // UPMenu 4 | // 5 | // Created by Tubik Studio on 16/3/18. 6 | // Copyright © 2018 Tubik Studio. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol UPMenuDelegate: class { 12 | 13 | func upMenu(_ upMenu: UPMenu, didTapOnHamburgerButton sender: UIButton) 14 | func upMenu(_ upMenu: UPMenu, didTapOnCloseButton sender: UIButton) 15 | func upMenu(_ upMenu: UPMenu, didSelectMenuItemAt indexPath: IndexPath) 16 | func upMenuWillAppear() 17 | func upMenuDidAppear() 18 | func upMenuWillClose() 19 | func upMenuDidClosed() 20 | 21 | } 22 | 23 | public extension UPMenuDelegate { 24 | 25 | func upMenu(_ upMenu: UPMenu, didTapOnHamburgerButton sender: UIButton) {} 26 | func upMenu(_ upMenu: UPMenu, didTapOnCloseButton sender: UIButton) {} 27 | func upMenu(_ upMenu: UPMenu, didSelectMenuItemAt indexPath: IndexPath) {} 28 | func upMenuWillAppear() {} 29 | func upMenuDidAppear() {} 30 | func upMenuWillClose() {} 31 | func upMenuDidClosed() {} 32 | 33 | } 34 | 35 | @IBDesignable public class UPMenu: UIView { 36 | 37 | public struct Appearance { 38 | public var menuImage: UIImage? 39 | public var closeMenuImage: UIImage? 40 | public var closedMenuColor = UIColor.white 41 | public var titleViewBackgorundColor = UIColor.white 42 | public var menuItemsViewBackgroundColor = UIColor.black 43 | public var menuItemCellBackgroundColor = UIColor.black 44 | public var menuItemCellTitleFont = UIFont.systemFont(ofSize: 24) 45 | public var menuItemCellTitleColor = UIColor.white 46 | } 47 | 48 | private struct Constants { 49 | static let closedMenuSize = CGSize(width: 57, height: 57) 50 | static let hamburgerButtonSize = CGSize(width: 24, height: 20) 51 | } 52 | 53 | private enum MenuState { 54 | case closed, expanded 55 | 56 | var image: UIImage? { 57 | switch self { 58 | case .closed: 59 | return UIImage(named: "closeIcn", in: Bundle(for: UPMenu.self), compatibleWith: nil) 60 | case .expanded: 61 | return UIImage(named: "menuIcn", in: Bundle(for: UPMenu.self), compatibleWith: nil) 62 | } 63 | } 64 | } 65 | 66 | // MARK: - Properties 67 | 68 | public weak var delegate: UPMenuDelegate? 69 | 70 | public private(set) var menuItems = [UPMenuItem]() 71 | 72 | public var menuItemsListHeight: CGFloat = 217 { 73 | didSet { 74 | menuItemsContainerHeightConstraint.constant = menuItemsListHeight 75 | layoutIfNeeded() 76 | } 77 | } 78 | 79 | public var menuItemHeight: CGFloat = 44 80 | 81 | public var appearance = Appearance() { 82 | didSet { 83 | updateAppearance(for: self.menuState) 84 | } 85 | } 86 | 87 | public var startPoint: CGPoint? { 88 | didSet { 89 | center = startPoint ?? superview?.center ?? .zero 90 | } 91 | } 92 | 93 | @IBOutlet public private(set) weak var hamburgerMenuButton: UIButton! 94 | 95 | @IBOutlet public private(set) weak var closeButton: UIButton! 96 | 97 | @IBOutlet private weak var mainContentView: UIView! 98 | @IBOutlet private weak var menuItemsContainerView: UIView! 99 | @IBOutlet private weak var hamburgerMenuButtonWidthConstraint: NSLayoutConstraint! 100 | @IBOutlet private weak var hamburgerMenuButtonHeightConstraint: NSLayoutConstraint! 101 | @IBOutlet private weak var tableViewTopConstraint: NSLayoutConstraint! 102 | @IBOutlet private weak var menuItemsContainerHeightConstraint: NSLayoutConstraint! 103 | @IBOutlet private weak var tableView: UITableView! 104 | private let maskLayer = CALayer() 105 | private var isGoingToHide: Bool = false 106 | private var menuState: MenuState = .closed 107 | private var animating: Bool = false 108 | 109 | // MARK: - UIView 110 | 111 | public override init(frame: CGRect) { 112 | super.init(frame: frame) 113 | 114 | xibSetup() 115 | } 116 | 117 | required public init?(coder aDecoder: NSCoder) { 118 | super.init(coder: aDecoder) 119 | 120 | xibSetup() 121 | } 122 | 123 | override public func point(inside point: CGPoint, with event: UIEvent?) -> Bool { 124 | if menuState == .expanded { 125 | return true 126 | } else { 127 | return maskLayer.frame.contains(point) 128 | } 129 | } 130 | 131 | override public func layoutSubviews() { 132 | super.layoutSubviews() 133 | if !animating { 134 | setupInitialMask() 135 | } 136 | } 137 | 138 | // MARK: - Methods 139 | 140 | public func addTitleView(_ titleView: UIView) { 141 | mainContentView.subviews.forEach { $0.removeFromSuperview() } 142 | mainContentView.addSubview(titleView) 143 | 144 | titleView.translatesAutoresizingMaskIntoConstraints = false 145 | 146 | mainContentView.addConstraint(NSLayoutConstraint(item: titleView, 147 | attribute: .trailing, 148 | relatedBy: .equal, 149 | toItem: mainContentView, 150 | attribute: .trailing, 151 | multiplier: 1, 152 | constant: 0)) 153 | 154 | mainContentView.addConstraint(NSLayoutConstraint(item: titleView, 155 | attribute: .leading, 156 | relatedBy: .equal, 157 | toItem: mainContentView, 158 | attribute: .leading, 159 | multiplier: 1, 160 | constant: 0)) 161 | 162 | mainContentView.addConstraint(NSLayoutConstraint(item: titleView, 163 | attribute: .top, 164 | relatedBy: .equal, 165 | toItem: mainContentView, 166 | attribute: .top, 167 | multiplier: 1, 168 | constant: 0)) 169 | 170 | mainContentView.addConstraint(NSLayoutConstraint(item: titleView, 171 | attribute: .bottom, 172 | relatedBy: .equal, 173 | toItem: mainContentView, 174 | attribute: .bottom, 175 | multiplier: 1, 176 | constant: 0)) 177 | mainContentView.subviews.forEach { 178 | $0.isHidden = menuState == .closed 179 | } 180 | } 181 | 182 | public func updateMenuItems(with newItems: [UPMenuItem]) { 183 | menuItems = newItems 184 | tableView.reloadData() 185 | } 186 | 187 | public func expand() { 188 | guard let superView = self.superview else { return } 189 | superView.isUserInteractionEnabled = false 190 | delegate?.upMenuWillAppear() 191 | if startPoint == nil { 192 | startPoint = center 193 | } 194 | UIView.animate(withDuration: 0.2, 195 | delay: 0, 196 | options: [.curveEaseIn, .curveEaseOut], 197 | animations: { 198 | self.animating = true 199 | self.hamburgerMenuButtonWidthConstraint.constant = 0 200 | self.hamburgerMenuButton.alpha = 0 201 | self.tableViewTopConstraint.constant = superView.bounds.height 202 | self.layoutIfNeeded() 203 | }, 204 | completion: { finished in 205 | guard finished else { return } 206 | UIView.animate(withDuration: 0.2, 207 | delay: 0, 208 | options: [.curveEaseIn, .curveEaseOut], 209 | animations: { 210 | self.center = CGPoint(x: superView.center.x, y: superView.center.y + 80) 211 | }, 212 | completion: { finished in 213 | guard finished else { return } 214 | self.updateAppearance(for: .expanded) 215 | self.mainContentView.subviews.forEach { 216 | $0.isHidden = false 217 | } 218 | UIView.animate(withDuration: 0.3, 219 | delay: 0, 220 | options: [.curveEaseIn, .curveEaseOut], 221 | animations: { 222 | self.tableViewTopConstraint.constant = 0 223 | self.maskLayer.bounds = CGRect(x: 0, y: 0, width: 1600, height: 1600) 224 | self.center = CGPoint(x: superView.center.x, y: superView.center.y + 5) 225 | self.layoutIfNeeded() 226 | }, 227 | completion: { finished in 228 | guard finished else { return } 229 | UIView.animate(withDuration: 0.2, 230 | animations: { 231 | self.center = superView.center 232 | }, 233 | completion: { finished in 234 | guard finished else { return } 235 | self.animating = false 236 | superView.isUserInteractionEnabled = true 237 | self.menuState = .expanded 238 | self.delegate?.upMenuDidAppear() 239 | }) 240 | }) 241 | }) 242 | 243 | }) 244 | } 245 | 246 | public func close() { 247 | guard let superView = self.superview else { return } 248 | self.animating = true 249 | superView.isUserInteractionEnabled = false 250 | delegate?.upMenuWillClose() 251 | isGoingToHide = true 252 | 253 | UIView.animate(withDuration: 0.3, 254 | delay: 0, 255 | options: [.curveEaseIn], 256 | animations: { 257 | self.maskLayer.bounds = CGRect(origin: .zero, size: Constants.closedMenuSize) 258 | self.tableViewTopConstraint.constant = superView.bounds.height 259 | self.layoutIfNeeded() 260 | self.mainContentView.subviews.forEach { 261 | $0.isHidden = true 262 | } 263 | }, 264 | completion: { finished in 265 | self.updateAppearance(for: .closed) 266 | guard finished else { return } 267 | UIView.animate(withDuration: 0.2, 268 | delay: 0, 269 | options: [.curveEaseIn, .curveEaseOut], 270 | animations: { 271 | self.center = self.startPoint ?? superView.center 272 | }, 273 | completion: { finished in 274 | guard finished else { return } 275 | UIView.animate(withDuration: 0.1, 276 | delay: 0, 277 | options: [.curveEaseIn, .curveEaseOut], 278 | animations: { 279 | self.rotate(degrees: -180) 280 | self.hamburgerMenuButtonHeightConstraint.constant = Constants.hamburgerButtonSize.height 281 | self.hamburgerMenuButtonWidthConstraint.constant = Constants.hamburgerButtonSize.width 282 | self.hamburgerMenuButton.alpha = 1 283 | self.layoutIfNeeded() 284 | }, 285 | completion: { finished in 286 | guard finished else { return } 287 | self.rotate(degrees: -180) 288 | self.animating = false 289 | self.isGoingToHide = false 290 | superView.isUserInteractionEnabled = true 291 | self.menuState = .closed 292 | self.delegate?.upMenuDidClosed() 293 | }) 294 | }) 295 | }) 296 | } 297 | 298 | @IBAction private func touchUpInsideHamburgerMenuButton(_ sender: UIButton) { 299 | delegate?.upMenu(self, didTapOnHamburgerButton: sender) 300 | expand() 301 | } 302 | 303 | @IBAction private func touchUpInsideCloseButton(_ sender: UIButton) { 304 | delegate?.upMenu(self, didTapOnCloseButton: sender) 305 | close() 306 | } 307 | 308 | private func xibSetup() { 309 | let view = loadViewFromNib() 310 | view.frame = bounds 311 | view.autoresizingMask = [.flexibleWidth, .flexibleHeight] 312 | addSubview(view) 313 | closeButton.isExclusiveTouch = true 314 | tableView.register(UINib(nibName: "UPMenuTableViewCell", bundle: Bundle(for: UPMenu.self)), 315 | forCellReuseIdentifier: UPMenuTableViewCell.reuseIdentifier) 316 | updateAppearance(for: menuState) 317 | } 318 | 319 | private func loadViewFromNib() -> UIView { 320 | let bundle = Bundle(for: UPMenu.self) 321 | let nib = UINib(nibName: String(describing: UPMenu.self), bundle: bundle) 322 | let view = nib.instantiate(withOwner: self, options: nil).first as! UIView 323 | return view 324 | } 325 | 326 | private func setupInitialMask() { 327 | maskLayer.contents = UIImage(named: "menu", in: Bundle(for: UPMenu.self), compatibleWith: nil)?.cgImage 328 | maskLayer.frame = CGRect(origin: .zero, size: Constants.closedMenuSize) 329 | maskLayer.position = CGPoint(x: frame.size.width/2.0, y: frame.size.height/2.0) 330 | layer.mask = maskLayer 331 | } 332 | 333 | private func rotate(degrees: CGFloat) { 334 | let radians = degrees / 180.0 * CGFloat.pi 335 | let rotation = self.transform.rotated(by: radians) 336 | self.transform = rotation 337 | } 338 | 339 | private func updateAppearance(for menuState: MenuState) { 340 | mainContentView.backgroundColor = menuState == .closed ? appearance.closedMenuColor : appearance.titleViewBackgorundColor 341 | menuItemsContainerView.backgroundColor = menuState == .closed ? appearance.closedMenuColor : appearance.menuItemsViewBackgroundColor 342 | tableView.isHidden = menuState == .closed 343 | closeButton.setImage(appearance.closeMenuImage ?? MenuState.closed.image, for: .normal) 344 | hamburgerMenuButton.setImage(appearance.menuImage ?? MenuState.expanded.image, for: .normal) 345 | tableView.reloadData() 346 | } 347 | } 348 | 349 | // MARK: - UITableViewDelegate 350 | 351 | extension UPMenu: UITableViewDelegate { 352 | 353 | public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 354 | return menuItemHeight 355 | } 356 | 357 | public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 358 | delegate?.upMenu(self, didSelectMenuItemAt: indexPath) 359 | } 360 | 361 | } 362 | 363 | // MARK: - UITableViewDataSource 364 | 365 | extension UPMenu: UITableViewDataSource { 366 | 367 | public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 368 | return menuItems.count 369 | } 370 | 371 | public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 372 | let cell = tableView.dequeueReusableCell(withIdentifier: UPMenuTableViewCell.reuseIdentifier, 373 | for: indexPath) as! UPMenuTableViewCell 374 | 375 | cell.configure(menuItemImage: menuItems[indexPath.row].image, 376 | menuItemTitle: menuItems[indexPath.row].title, 377 | menuAppearance: appearance) 378 | 379 | return cell 380 | } 381 | 382 | } 383 | --------------------------------------------------------------------------------