├── .gitattributes ├── .gitignore ├── LICENSE ├── Podfile ├── Podfile.lock ├── Pods ├── Manifest.lock ├── Pods.xcodeproj │ └── project.pbxproj └── Target Support Files │ ├── Pods-demo │ ├── Info.plist │ ├── Pods-demo-acknowledgements.markdown │ ├── Pods-demo-acknowledgements.plist │ ├── Pods-demo-dummy.m │ ├── Pods-demo-frameworks.sh │ ├── Pods-demo-resources.sh │ ├── Pods-demo-umbrella.h │ ├── Pods-demo.debug.xcconfig │ ├── Pods-demo.modulemap │ └── Pods-demo.release.xcconfig │ └── Pods-drawer-view │ ├── Info.plist │ ├── Pods-drawer-view-acknowledgements.markdown │ ├── Pods-drawer-view-acknowledgements.plist │ ├── Pods-drawer-view-dummy.m │ ├── Pods-drawer-view-resources.sh │ ├── Pods-drawer-view-umbrella.h │ ├── Pods-drawer-view.debug.xcconfig │ ├── Pods-drawer-view.modulemap │ └── Pods-drawer-view.release.xcconfig ├── README.md ├── assets ├── drawer-view demo 01.gif ├── drawer-view demo 02.gif ├── drawer-view demo 03.gif └── drawer-view demo 04.gif ├── demo ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ └── IMG_23879.imageset │ │ ├── Contents.json │ │ └── IMG_23879.png ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist └── ViewController.swift ├── drawer-view.podspec ├── drawer-view.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcuserdata │ └── astemireleev.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── drawer-view.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── drawer-view ├── 1.0.1 │ └── drawer-view.podspec ├── DefaultTitleLabelAnimator.swift ├── DrawerView.BlurStyle+Convert.swift ├── DrawerView.State+Opposite.swift ├── DrawerView.swift ├── DrawerViewTouchHandling.swift ├── ImmediatePanGestureRecognizer.swift ├── Info.plist ├── LineArrowShapeLayer.swift ├── TitleLabelAnimator.swift └── drawer_view.h └── logo-drawer_view.png /.gitattributes: -------------------------------------------------------------------------------- 1 | *.podspec linguist-detectable=false 2 | *.ruby linguist-detectable=false 3 | *.ru linguist-detectable=false 4 | *.spec linguist-detectable=false 5 | *.rbx linguist-detectable=false 6 | *.rabl linguist-detectable=false 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## OS X Finder 2 | .DS_Store 3 | 4 | ## Build generated 5 | build/ 6 | DerivedData 7 | 8 | ## Various settings 9 | *.pbxuser 10 | !default.pbxuser 11 | *.mode1v3 12 | !default.mode1v3 13 | *.mode2v3 14 | !default.mode2v3 15 | *.perspectivev3 16 | !default.perspectivev3 17 | xcuserdata 18 | 19 | ## Other 20 | *.xccheckout 21 | *.moved-aside 22 | *.xcuserstate 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | 29 | # Swift Package Manager 30 | .build/ 31 | 32 | # Carthage 33 | Carthage/Build 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Astemir Eleev 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 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'demo' do 5 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | # Pods for demo 9 | 10 | end 11 | 12 | target 'drawer-view' do 13 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 14 | use_frameworks! 15 | 16 | # Pods for drawer-view 17 | 18 | end 19 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODFILE CHECKSUM: fb9470eeceb758fe599be6a46131c7f0a98e93ac 2 | 3 | COCOAPODS: 1.5.3 4 | -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODFILE CHECKSUM: fb9470eeceb758fe599be6a46131c7f0a98e93ac 2 | 3 | COCOAPODS: 1.5.3 4 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 08844E52D3BE2CEF1645875D00D6B9D4 /* Pods-demo-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = D7249A99B7A720E0241FD34832E03CE8 /* Pods-demo-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 2DB68B1A3FF71EBCA0D3792257F4FBE2 /* Pods-drawer-view-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A6555BD6F8175528712A33002ED9391 /* Pods-drawer-view-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 12 | 7655B1A2E030C39A185248DD71D76027 /* Pods-drawer-view-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = AA856F0862DE4A2808E95831B874F895 /* Pods-drawer-view-dummy.m */; }; 13 | 9D48FE91692A627FCFFF6E4086F646CE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A16F4CFC63FAC439D7A04994F579A03 /* Foundation.framework */; }; 14 | AF685E97814F4ED0462CD9DA8485C8DA /* Pods-demo-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = B4F92635D081ACD6C440367BC56963F7 /* Pods-demo-dummy.m */; }; 15 | EEFCF65A50642BDFD310225AF927E1B0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A16F4CFC63FAC439D7A04994F579A03 /* Foundation.framework */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | 1A6555BD6F8175528712A33002ED9391 /* Pods-drawer-view-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-drawer-view-umbrella.h"; sourceTree = ""; }; 20 | 1C7CF195399922B9C07C4384CAF97CED /* Pods-drawer-view-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-drawer-view-resources.sh"; sourceTree = ""; }; 21 | 23E06BDFE2A72798508D9F0E33C69032 /* Pods-demo-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-demo-acknowledgements.markdown"; sourceTree = ""; }; 22 | 243AF058131CE26CCF80D29333E6632B /* Pods-demo-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-demo-resources.sh"; sourceTree = ""; }; 23 | 2BA9D9FDDE0B9AA947CBD47A13083797 /* Pods-drawer-view-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-drawer-view-acknowledgements.plist"; sourceTree = ""; }; 24 | 2FC46DFAA8A3AB7DAFEADEFFD81351CE /* Pods-demo-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-demo-frameworks.sh"; sourceTree = ""; }; 25 | 4F86082CAD9CDF26E2B24744D82FE213 /* Pods-drawer-view.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-drawer-view.modulemap"; sourceTree = ""; }; 26 | 5A16F4CFC63FAC439D7A04994F579A03 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 27 | 5F3AFF7067045807C304DE09F0F3ADB0 /* Pods-drawer-view.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-drawer-view.debug.xcconfig"; sourceTree = ""; }; 28 | 78C36980ECCFE2AE0DD0667DF90CCFCE /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 29 | 7D6AEDBA2EA0855DC518AE02208C5CB8 /* Pods_demo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_demo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 30 | 87A1C5751487C5DB1170EF51A71A65D4 /* Pods-demo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-demo.debug.xcconfig"; sourceTree = ""; }; 31 | 8A94ED49751B534A3CE6EA13F9EDEE25 /* Pods-demo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-demo.release.xcconfig"; sourceTree = ""; }; 32 | 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 33 | AA856F0862DE4A2808E95831B874F895 /* Pods-drawer-view-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-drawer-view-dummy.m"; sourceTree = ""; }; 34 | B4F92635D081ACD6C440367BC56963F7 /* Pods-demo-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-demo-dummy.m"; sourceTree = ""; }; 35 | BB607177DB96711F7449CF658A984CEA /* Pods-drawer-view.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-drawer-view.release.xcconfig"; sourceTree = ""; }; 36 | C09B0909856B914AA1D708BD507ABB05 /* Pods_drawer_view.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_drawer_view.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 37 | C48CF5C3E8A493478FD4339ED1318A44 /* Pods-demo.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-demo.modulemap"; sourceTree = ""; }; 38 | D7249A99B7A720E0241FD34832E03CE8 /* Pods-demo-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-demo-umbrella.h"; sourceTree = ""; }; 39 | E0EF3A47EFB71B7767344C6C2ED19335 /* Pods-drawer-view-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-drawer-view-acknowledgements.markdown"; sourceTree = ""; }; 40 | F2FC1786893F8C2DC05FB00A3382CD8A /* Pods-demo-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-demo-acknowledgements.plist"; sourceTree = ""; }; 41 | F93C7427ACA624B513CF5E5C3F8164ED /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 42 | /* End PBXFileReference section */ 43 | 44 | /* Begin PBXFrameworksBuildPhase section */ 45 | 210E342C54FC3890AC235FCD53D192D0 /* Frameworks */ = { 46 | isa = PBXFrameworksBuildPhase; 47 | buildActionMask = 2147483647; 48 | files = ( 49 | 9D48FE91692A627FCFFF6E4086F646CE /* Foundation.framework in Frameworks */, 50 | ); 51 | runOnlyForDeploymentPostprocessing = 0; 52 | }; 53 | A914CAE1AFC50BE454CB9F4B24FDDFF1 /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | EEFCF65A50642BDFD310225AF927E1B0 /* Foundation.framework in Frameworks */, 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 2D5A032793E201FA671B0C85AC480BB9 /* Pods-drawer-view */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 78C36980ECCFE2AE0DD0667DF90CCFCE /* Info.plist */, 68 | 4F86082CAD9CDF26E2B24744D82FE213 /* Pods-drawer-view.modulemap */, 69 | E0EF3A47EFB71B7767344C6C2ED19335 /* Pods-drawer-view-acknowledgements.markdown */, 70 | 2BA9D9FDDE0B9AA947CBD47A13083797 /* Pods-drawer-view-acknowledgements.plist */, 71 | AA856F0862DE4A2808E95831B874F895 /* Pods-drawer-view-dummy.m */, 72 | 1C7CF195399922B9C07C4384CAF97CED /* Pods-drawer-view-resources.sh */, 73 | 1A6555BD6F8175528712A33002ED9391 /* Pods-drawer-view-umbrella.h */, 74 | 5F3AFF7067045807C304DE09F0F3ADB0 /* Pods-drawer-view.debug.xcconfig */, 75 | BB607177DB96711F7449CF658A984CEA /* Pods-drawer-view.release.xcconfig */, 76 | ); 77 | name = "Pods-drawer-view"; 78 | path = "Target Support Files/Pods-drawer-view"; 79 | sourceTree = ""; 80 | }; 81 | 2DB345364E8369448F1C15D57220DFC6 /* Pods-demo */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | F93C7427ACA624B513CF5E5C3F8164ED /* Info.plist */, 85 | C48CF5C3E8A493478FD4339ED1318A44 /* Pods-demo.modulemap */, 86 | 23E06BDFE2A72798508D9F0E33C69032 /* Pods-demo-acknowledgements.markdown */, 87 | F2FC1786893F8C2DC05FB00A3382CD8A /* Pods-demo-acknowledgements.plist */, 88 | B4F92635D081ACD6C440367BC56963F7 /* Pods-demo-dummy.m */, 89 | 2FC46DFAA8A3AB7DAFEADEFFD81351CE /* Pods-demo-frameworks.sh */, 90 | 243AF058131CE26CCF80D29333E6632B /* Pods-demo-resources.sh */, 91 | D7249A99B7A720E0241FD34832E03CE8 /* Pods-demo-umbrella.h */, 92 | 87A1C5751487C5DB1170EF51A71A65D4 /* Pods-demo.debug.xcconfig */, 93 | 8A94ED49751B534A3CE6EA13F9EDEE25 /* Pods-demo.release.xcconfig */, 94 | ); 95 | name = "Pods-demo"; 96 | path = "Target Support Files/Pods-demo"; 97 | sourceTree = ""; 98 | }; 99 | 5E0D919E635D23B70123790B8308F8EF /* iOS */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 5A16F4CFC63FAC439D7A04994F579A03 /* Foundation.framework */, 103 | ); 104 | name = iOS; 105 | sourceTree = ""; 106 | }; 107 | 6BD1773FFE88373DD17F05B5ED092887 /* Targets Support Files */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 2DB345364E8369448F1C15D57220DFC6 /* Pods-demo */, 111 | 2D5A032793E201FA671B0C85AC480BB9 /* Pods-drawer-view */, 112 | ); 113 | name = "Targets Support Files"; 114 | sourceTree = ""; 115 | }; 116 | 7DB346D0F39D3F0E887471402A8071AB = { 117 | isa = PBXGroup; 118 | children = ( 119 | 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, 120 | BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */, 121 | C390E3CD86A61C76096B3BD78379A77E /* Products */, 122 | 6BD1773FFE88373DD17F05B5ED092887 /* Targets Support Files */, 123 | ); 124 | sourceTree = ""; 125 | }; 126 | BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | 5E0D919E635D23B70123790B8308F8EF /* iOS */, 130 | ); 131 | name = Frameworks; 132 | sourceTree = ""; 133 | }; 134 | C390E3CD86A61C76096B3BD78379A77E /* Products */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | 7D6AEDBA2EA0855DC518AE02208C5CB8 /* Pods_demo.framework */, 138 | C09B0909856B914AA1D708BD507ABB05 /* Pods_drawer_view.framework */, 139 | ); 140 | name = Products; 141 | sourceTree = ""; 142 | }; 143 | /* End PBXGroup section */ 144 | 145 | /* Begin PBXHeadersBuildPhase section */ 146 | A39331AB431195006A7AD6B6EE55F192 /* Headers */ = { 147 | isa = PBXHeadersBuildPhase; 148 | buildActionMask = 2147483647; 149 | files = ( 150 | 08844E52D3BE2CEF1645875D00D6B9D4 /* Pods-demo-umbrella.h in Headers */, 151 | ); 152 | runOnlyForDeploymentPostprocessing = 0; 153 | }; 154 | F0A6F172784A6D3B53B6D080623052F9 /* Headers */ = { 155 | isa = PBXHeadersBuildPhase; 156 | buildActionMask = 2147483647; 157 | files = ( 158 | 2DB68B1A3FF71EBCA0D3792257F4FBE2 /* Pods-drawer-view-umbrella.h in Headers */, 159 | ); 160 | runOnlyForDeploymentPostprocessing = 0; 161 | }; 162 | /* End PBXHeadersBuildPhase section */ 163 | 164 | /* Begin PBXNativeTarget section */ 165 | DC784CA5B0B2CC0B5D5A1EAB4C5EFEC4 /* Pods-demo */ = { 166 | isa = PBXNativeTarget; 167 | buildConfigurationList = B02560DA67EC4305D39B3B0408E126A4 /* Build configuration list for PBXNativeTarget "Pods-demo" */; 168 | buildPhases = ( 169 | A39331AB431195006A7AD6B6EE55F192 /* Headers */, 170 | 655E9B362CE97969A38DCC11CC5A94E0 /* Sources */, 171 | A914CAE1AFC50BE454CB9F4B24FDDFF1 /* Frameworks */, 172 | 6055C49B6DF7529BACB1F0762E22AEB7 /* Resources */, 173 | ); 174 | buildRules = ( 175 | ); 176 | dependencies = ( 177 | ); 178 | name = "Pods-demo"; 179 | productName = "Pods-demo"; 180 | productReference = 7D6AEDBA2EA0855DC518AE02208C5CB8 /* Pods_demo.framework */; 181 | productType = "com.apple.product-type.framework"; 182 | }; 183 | E178FF6AE3AF2608999686628F258499 /* Pods-drawer-view */ = { 184 | isa = PBXNativeTarget; 185 | buildConfigurationList = C73B7ACE001A62648D8F258B05A2458F /* Build configuration list for PBXNativeTarget "Pods-drawer-view" */; 186 | buildPhases = ( 187 | F0A6F172784A6D3B53B6D080623052F9 /* Headers */, 188 | 9BE928FE62477BEF3BDC8A953BD0AD5C /* Sources */, 189 | 210E342C54FC3890AC235FCD53D192D0 /* Frameworks */, 190 | AF72462BABE761A8907FAF2F86784740 /* Resources */, 191 | ); 192 | buildRules = ( 193 | ); 194 | dependencies = ( 195 | ); 196 | name = "Pods-drawer-view"; 197 | productName = "Pods-drawer-view"; 198 | productReference = C09B0909856B914AA1D708BD507ABB05 /* Pods_drawer_view.framework */; 199 | productType = "com.apple.product-type.framework"; 200 | }; 201 | /* End PBXNativeTarget section */ 202 | 203 | /* Begin PBXProject section */ 204 | D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { 205 | isa = PBXProject; 206 | attributes = { 207 | LastSwiftUpdateCheck = 0930; 208 | LastUpgradeCheck = 1020; 209 | }; 210 | buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; 211 | compatibilityVersion = "Xcode 3.2"; 212 | developmentRegion = en; 213 | hasScannedForEncodings = 0; 214 | knownRegions = ( 215 | en, 216 | Base, 217 | ); 218 | mainGroup = 7DB346D0F39D3F0E887471402A8071AB; 219 | productRefGroup = C390E3CD86A61C76096B3BD78379A77E /* Products */; 220 | projectDirPath = ""; 221 | projectRoot = ""; 222 | targets = ( 223 | DC784CA5B0B2CC0B5D5A1EAB4C5EFEC4 /* Pods-demo */, 224 | E178FF6AE3AF2608999686628F258499 /* Pods-drawer-view */, 225 | ); 226 | }; 227 | /* End PBXProject section */ 228 | 229 | /* Begin PBXResourcesBuildPhase section */ 230 | 6055C49B6DF7529BACB1F0762E22AEB7 /* Resources */ = { 231 | isa = PBXResourcesBuildPhase; 232 | buildActionMask = 2147483647; 233 | files = ( 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | }; 237 | AF72462BABE761A8907FAF2F86784740 /* Resources */ = { 238 | isa = PBXResourcesBuildPhase; 239 | buildActionMask = 2147483647; 240 | files = ( 241 | ); 242 | runOnlyForDeploymentPostprocessing = 0; 243 | }; 244 | /* End PBXResourcesBuildPhase section */ 245 | 246 | /* Begin PBXSourcesBuildPhase section */ 247 | 655E9B362CE97969A38DCC11CC5A94E0 /* Sources */ = { 248 | isa = PBXSourcesBuildPhase; 249 | buildActionMask = 2147483647; 250 | files = ( 251 | AF685E97814F4ED0462CD9DA8485C8DA /* Pods-demo-dummy.m in Sources */, 252 | ); 253 | runOnlyForDeploymentPostprocessing = 0; 254 | }; 255 | 9BE928FE62477BEF3BDC8A953BD0AD5C /* Sources */ = { 256 | isa = PBXSourcesBuildPhase; 257 | buildActionMask = 2147483647; 258 | files = ( 259 | 7655B1A2E030C39A185248DD71D76027 /* Pods-drawer-view-dummy.m in Sources */, 260 | ); 261 | runOnlyForDeploymentPostprocessing = 0; 262 | }; 263 | /* End PBXSourcesBuildPhase section */ 264 | 265 | /* Begin XCBuildConfiguration section */ 266 | 4597BC755BD0977CDC4B2D222395B8F6 /* Release */ = { 267 | isa = XCBuildConfiguration; 268 | baseConfigurationReference = 8A94ED49751B534A3CE6EA13F9EDEE25 /* Pods-demo.release.xcconfig */; 269 | buildSettings = { 270 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 271 | CLANG_ENABLE_OBJC_WEAK = NO; 272 | CODE_SIGN_IDENTITY = ""; 273 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 274 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 275 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 276 | CURRENT_PROJECT_VERSION = 1; 277 | DEFINES_MODULE = YES; 278 | DYLIB_COMPATIBILITY_VERSION = 1; 279 | DYLIB_CURRENT_VERSION = 1; 280 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 281 | INFOPLIST_FILE = "Target Support Files/Pods-demo/Info.plist"; 282 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 283 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 284 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 285 | MACH_O_TYPE = staticlib; 286 | MODULEMAP_FILE = "Target Support Files/Pods-demo/Pods-demo.modulemap"; 287 | OTHER_LDFLAGS = ""; 288 | OTHER_LIBTOOLFLAGS = ""; 289 | PODS_ROOT = "$(SRCROOT)"; 290 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 291 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 292 | SDKROOT = iphoneos; 293 | SKIP_INSTALL = YES; 294 | TARGETED_DEVICE_FAMILY = "1,2"; 295 | VALIDATE_PRODUCT = YES; 296 | VERSIONING_SYSTEM = "apple-generic"; 297 | VERSION_INFO_PREFIX = ""; 298 | }; 299 | name = Release; 300 | }; 301 | 4E77DE639AC5E60C0A6E300909831E6B /* Debug */ = { 302 | isa = XCBuildConfiguration; 303 | baseConfigurationReference = 87A1C5751487C5DB1170EF51A71A65D4 /* Pods-demo.debug.xcconfig */; 304 | buildSettings = { 305 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 306 | CLANG_ENABLE_OBJC_WEAK = NO; 307 | CODE_SIGN_IDENTITY = ""; 308 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 309 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 310 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 311 | CURRENT_PROJECT_VERSION = 1; 312 | DEFINES_MODULE = YES; 313 | DYLIB_COMPATIBILITY_VERSION = 1; 314 | DYLIB_CURRENT_VERSION = 1; 315 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 316 | INFOPLIST_FILE = "Target Support Files/Pods-demo/Info.plist"; 317 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 318 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 319 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 320 | MACH_O_TYPE = staticlib; 321 | MODULEMAP_FILE = "Target Support Files/Pods-demo/Pods-demo.modulemap"; 322 | OTHER_LDFLAGS = ""; 323 | OTHER_LIBTOOLFLAGS = ""; 324 | PODS_ROOT = "$(SRCROOT)"; 325 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 326 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 327 | SDKROOT = iphoneos; 328 | SKIP_INSTALL = YES; 329 | TARGETED_DEVICE_FAMILY = "1,2"; 330 | VERSIONING_SYSTEM = "apple-generic"; 331 | VERSION_INFO_PREFIX = ""; 332 | }; 333 | name = Debug; 334 | }; 335 | 8C3D32AC054F4DBEE82EB2FD6A303D73 /* Debug */ = { 336 | isa = XCBuildConfiguration; 337 | buildSettings = { 338 | ALWAYS_SEARCH_USER_PATHS = NO; 339 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 340 | CLANG_ANALYZER_NONNULL = YES; 341 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 342 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 343 | CLANG_CXX_LIBRARY = "libc++"; 344 | CLANG_ENABLE_MODULES = YES; 345 | CLANG_ENABLE_OBJC_ARC = YES; 346 | CLANG_ENABLE_OBJC_WEAK = YES; 347 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 348 | CLANG_WARN_BOOL_CONVERSION = YES; 349 | CLANG_WARN_COMMA = YES; 350 | CLANG_WARN_CONSTANT_CONVERSION = YES; 351 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 352 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 353 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 354 | CLANG_WARN_EMPTY_BODY = YES; 355 | CLANG_WARN_ENUM_CONVERSION = YES; 356 | CLANG_WARN_INFINITE_RECURSION = YES; 357 | CLANG_WARN_INT_CONVERSION = YES; 358 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 359 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 360 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 361 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 362 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 363 | CLANG_WARN_STRICT_PROTOTYPES = YES; 364 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 365 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 366 | CLANG_WARN_UNREACHABLE_CODE = YES; 367 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 368 | CODE_SIGNING_ALLOWED = NO; 369 | CODE_SIGNING_REQUIRED = NO; 370 | COPY_PHASE_STRIP = NO; 371 | DEBUG_INFORMATION_FORMAT = dwarf; 372 | ENABLE_STRICT_OBJC_MSGSEND = YES; 373 | ENABLE_TESTABILITY = YES; 374 | GCC_C_LANGUAGE_STANDARD = gnu11; 375 | GCC_DYNAMIC_NO_PIC = NO; 376 | GCC_NO_COMMON_BLOCKS = YES; 377 | GCC_OPTIMIZATION_LEVEL = 0; 378 | GCC_PREPROCESSOR_DEFINITIONS = ( 379 | "POD_CONFIGURATION_DEBUG=1", 380 | "DEBUG=1", 381 | "$(inherited)", 382 | ); 383 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 384 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 385 | GCC_WARN_UNDECLARED_SELECTOR = YES; 386 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 387 | GCC_WARN_UNUSED_FUNCTION = YES; 388 | GCC_WARN_UNUSED_VARIABLE = YES; 389 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 390 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 391 | MTL_FAST_MATH = YES; 392 | ONLY_ACTIVE_ARCH = YES; 393 | PRODUCT_NAME = "$(TARGET_NAME)"; 394 | STRIP_INSTALLED_PRODUCT = NO; 395 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 396 | SYMROOT = "${SRCROOT}/../build"; 397 | }; 398 | name = Debug; 399 | }; 400 | B751CA5B597BFC35A6C0287C65F9E2E1 /* Release */ = { 401 | isa = XCBuildConfiguration; 402 | buildSettings = { 403 | ALWAYS_SEARCH_USER_PATHS = NO; 404 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 405 | CLANG_ANALYZER_NONNULL = YES; 406 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 407 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 408 | CLANG_CXX_LIBRARY = "libc++"; 409 | CLANG_ENABLE_MODULES = YES; 410 | CLANG_ENABLE_OBJC_ARC = YES; 411 | CLANG_ENABLE_OBJC_WEAK = YES; 412 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 413 | CLANG_WARN_BOOL_CONVERSION = YES; 414 | CLANG_WARN_COMMA = YES; 415 | CLANG_WARN_CONSTANT_CONVERSION = YES; 416 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 417 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 418 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 419 | CLANG_WARN_EMPTY_BODY = YES; 420 | CLANG_WARN_ENUM_CONVERSION = YES; 421 | CLANG_WARN_INFINITE_RECURSION = YES; 422 | CLANG_WARN_INT_CONVERSION = YES; 423 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 424 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 425 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 426 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 427 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 428 | CLANG_WARN_STRICT_PROTOTYPES = YES; 429 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 430 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 431 | CLANG_WARN_UNREACHABLE_CODE = YES; 432 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 433 | CODE_SIGNING_ALLOWED = NO; 434 | CODE_SIGNING_REQUIRED = NO; 435 | COPY_PHASE_STRIP = NO; 436 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 437 | ENABLE_NS_ASSERTIONS = NO; 438 | ENABLE_STRICT_OBJC_MSGSEND = YES; 439 | GCC_C_LANGUAGE_STANDARD = gnu11; 440 | GCC_NO_COMMON_BLOCKS = YES; 441 | GCC_PREPROCESSOR_DEFINITIONS = ( 442 | "POD_CONFIGURATION_RELEASE=1", 443 | "$(inherited)", 444 | ); 445 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 446 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 447 | GCC_WARN_UNDECLARED_SELECTOR = YES; 448 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 449 | GCC_WARN_UNUSED_FUNCTION = YES; 450 | GCC_WARN_UNUSED_VARIABLE = YES; 451 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 452 | MTL_ENABLE_DEBUG_INFO = NO; 453 | MTL_FAST_MATH = YES; 454 | PRODUCT_NAME = "$(TARGET_NAME)"; 455 | STRIP_INSTALLED_PRODUCT = NO; 456 | SYMROOT = "${SRCROOT}/../build"; 457 | }; 458 | name = Release; 459 | }; 460 | BCB3FC4832130AF6A3301B52F7ADA38E /* Release */ = { 461 | isa = XCBuildConfiguration; 462 | baseConfigurationReference = BB607177DB96711F7449CF658A984CEA /* Pods-drawer-view.release.xcconfig */; 463 | buildSettings = { 464 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 465 | CLANG_ENABLE_OBJC_WEAK = NO; 466 | CODE_SIGN_IDENTITY = ""; 467 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 468 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 469 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 470 | CURRENT_PROJECT_VERSION = 1; 471 | DEFINES_MODULE = YES; 472 | DYLIB_COMPATIBILITY_VERSION = 1; 473 | DYLIB_CURRENT_VERSION = 1; 474 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 475 | INFOPLIST_FILE = "Target Support Files/Pods-drawer-view/Info.plist"; 476 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 477 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 478 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 479 | MACH_O_TYPE = staticlib; 480 | MODULEMAP_FILE = "Target Support Files/Pods-drawer-view/Pods-drawer-view.modulemap"; 481 | OTHER_LDFLAGS = ""; 482 | OTHER_LIBTOOLFLAGS = ""; 483 | PODS_ROOT = "$(SRCROOT)"; 484 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 485 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 486 | SDKROOT = iphoneos; 487 | SKIP_INSTALL = YES; 488 | TARGETED_DEVICE_FAMILY = "1,2"; 489 | VALIDATE_PRODUCT = YES; 490 | VERSIONING_SYSTEM = "apple-generic"; 491 | VERSION_INFO_PREFIX = ""; 492 | }; 493 | name = Release; 494 | }; 495 | E0091944E6913F262FC8EF4D666CEA43 /* Debug */ = { 496 | isa = XCBuildConfiguration; 497 | baseConfigurationReference = 5F3AFF7067045807C304DE09F0F3ADB0 /* Pods-drawer-view.debug.xcconfig */; 498 | buildSettings = { 499 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 500 | CLANG_ENABLE_OBJC_WEAK = NO; 501 | CODE_SIGN_IDENTITY = ""; 502 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 503 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 504 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 505 | CURRENT_PROJECT_VERSION = 1; 506 | DEFINES_MODULE = YES; 507 | DYLIB_COMPATIBILITY_VERSION = 1; 508 | DYLIB_CURRENT_VERSION = 1; 509 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 510 | INFOPLIST_FILE = "Target Support Files/Pods-drawer-view/Info.plist"; 511 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 512 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 513 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 514 | MACH_O_TYPE = staticlib; 515 | MODULEMAP_FILE = "Target Support Files/Pods-drawer-view/Pods-drawer-view.modulemap"; 516 | OTHER_LDFLAGS = ""; 517 | OTHER_LIBTOOLFLAGS = ""; 518 | PODS_ROOT = "$(SRCROOT)"; 519 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 520 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 521 | SDKROOT = iphoneos; 522 | SKIP_INSTALL = YES; 523 | TARGETED_DEVICE_FAMILY = "1,2"; 524 | VERSIONING_SYSTEM = "apple-generic"; 525 | VERSION_INFO_PREFIX = ""; 526 | }; 527 | name = Debug; 528 | }; 529 | /* End XCBuildConfiguration section */ 530 | 531 | /* Begin XCConfigurationList section */ 532 | 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { 533 | isa = XCConfigurationList; 534 | buildConfigurations = ( 535 | 8C3D32AC054F4DBEE82EB2FD6A303D73 /* Debug */, 536 | B751CA5B597BFC35A6C0287C65F9E2E1 /* Release */, 537 | ); 538 | defaultConfigurationIsVisible = 0; 539 | defaultConfigurationName = Release; 540 | }; 541 | B02560DA67EC4305D39B3B0408E126A4 /* Build configuration list for PBXNativeTarget "Pods-demo" */ = { 542 | isa = XCConfigurationList; 543 | buildConfigurations = ( 544 | 4E77DE639AC5E60C0A6E300909831E6B /* Debug */, 545 | 4597BC755BD0977CDC4B2D222395B8F6 /* Release */, 546 | ); 547 | defaultConfigurationIsVisible = 0; 548 | defaultConfigurationName = Release; 549 | }; 550 | C73B7ACE001A62648D8F258B05A2458F /* Build configuration list for PBXNativeTarget "Pods-drawer-view" */ = { 551 | isa = XCConfigurationList; 552 | buildConfigurations = ( 553 | E0091944E6913F262FC8EF4D666CEA43 /* Debug */, 554 | BCB3FC4832130AF6A3301B52F7ADA38E /* Release */, 555 | ); 556 | defaultConfigurationIsVisible = 0; 557 | defaultConfigurationName = Release; 558 | }; 559 | /* End XCConfigurationList section */ 560 | }; 561 | rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; 562 | } 563 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-demo/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 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-demo/Pods-demo-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-demo/Pods-demo-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 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-demo/Pods-demo-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_demo : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_demo 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-demo/Pods-demo-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 7 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # frameworks to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 13 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 14 | 15 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 16 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 17 | 18 | # Used as a return value for each invocation of `strip_invalid_archs` function. 19 | STRIP_BINARY_RETVAL=0 20 | 21 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 22 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 23 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 24 | 25 | # Copies and strips a vendored framework 26 | install_framework() 27 | { 28 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 29 | local source="${BUILT_PRODUCTS_DIR}/$1" 30 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 31 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 32 | elif [ -r "$1" ]; then 33 | local source="$1" 34 | fi 35 | 36 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 37 | 38 | if [ -L "${source}" ]; then 39 | echo "Symlinked..." 40 | source="$(readlink "${source}")" 41 | fi 42 | 43 | # Use filter instead of exclude so missing patterns don't throw errors. 44 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 45 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 46 | 47 | local basename 48 | basename="$(basename -s .framework "$1")" 49 | binary="${destination}/${basename}.framework/${basename}" 50 | if ! [ -r "$binary" ]; then 51 | binary="${destination}/${basename}" 52 | fi 53 | 54 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 55 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 56 | strip_invalid_archs "$binary" 57 | fi 58 | 59 | # Resign the code if required by the build settings to avoid unstable apps 60 | code_sign_if_enabled "${destination}/$(basename "$1")" 61 | 62 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 63 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 64 | local swift_runtime_libs 65 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 66 | for lib in $swift_runtime_libs; do 67 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 68 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 69 | code_sign_if_enabled "${destination}/${lib}" 70 | done 71 | fi 72 | } 73 | 74 | # Copies and strips a vendored dSYM 75 | install_dsym() { 76 | local source="$1" 77 | if [ -r "$source" ]; then 78 | # Copy the dSYM into a the targets temp dir. 79 | 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}\"" 80 | 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}" 81 | 82 | local basename 83 | basename="$(basename -s .framework.dSYM "$source")" 84 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" 85 | 86 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 87 | if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then 88 | strip_invalid_archs "$binary" 89 | fi 90 | 91 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then 92 | # Move the stripped file into its final destination. 93 | 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}\"" 94 | 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}" 95 | else 96 | # 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. 97 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" 98 | fi 99 | fi 100 | } 101 | 102 | # Signs a framework with the provided identity 103 | code_sign_if_enabled() { 104 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 105 | # Use the current code_sign_identitiy 106 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 107 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 108 | 109 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 110 | code_sign_cmd="$code_sign_cmd &" 111 | fi 112 | echo "$code_sign_cmd" 113 | eval "$code_sign_cmd" 114 | fi 115 | } 116 | 117 | # Strip invalid architectures 118 | strip_invalid_archs() { 119 | binary="$1" 120 | # Get architectures for current target binary 121 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 122 | # Intersect them with the architectures we are building for 123 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 124 | # If there are no archs supported by this binary then warn the user 125 | if [[ -z "$intersected_archs" ]]; then 126 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 127 | STRIP_BINARY_RETVAL=0 128 | return 129 | fi 130 | stripped="" 131 | for arch in $binary_archs; do 132 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 133 | # Strip non-valid architectures in-place 134 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 135 | stripped="$stripped $arch" 136 | fi 137 | done 138 | if [[ "$stripped" ]]; then 139 | echo "Stripped $binary of architectures:$stripped" 140 | fi 141 | STRIP_BINARY_RETVAL=1 142 | } 143 | 144 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 145 | wait 146 | fi 147 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-demo/Pods-demo-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then 7 | # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # resources to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 13 | 14 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 15 | > "$RESOURCES_TO_COPY" 16 | 17 | XCASSET_FILES=() 18 | 19 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 20 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 21 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 22 | 23 | case "${TARGETED_DEVICE_FAMILY:-}" in 24 | 1,2) 25 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 26 | ;; 27 | 1) 28 | TARGET_DEVICE_ARGS="--target-device iphone" 29 | ;; 30 | 2) 31 | TARGET_DEVICE_ARGS="--target-device ipad" 32 | ;; 33 | 3) 34 | TARGET_DEVICE_ARGS="--target-device tv" 35 | ;; 36 | 4) 37 | TARGET_DEVICE_ARGS="--target-device watch" 38 | ;; 39 | *) 40 | TARGET_DEVICE_ARGS="--target-device mac" 41 | ;; 42 | esac 43 | 44 | install_resource() 45 | { 46 | if [[ "$1" = /* ]] ; then 47 | RESOURCE_PATH="$1" 48 | else 49 | RESOURCE_PATH="${PODS_ROOT}/$1" 50 | fi 51 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 52 | cat << EOM 53 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 54 | EOM 55 | exit 1 56 | fi 57 | case $RESOURCE_PATH in 58 | *.storyboard) 59 | 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 60 | 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} 61 | ;; 62 | *.xib) 63 | 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 64 | 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} 65 | ;; 66 | *.framework) 67 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 68 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 69 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 70 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 71 | ;; 72 | *.xcdatamodel) 73 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 74 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 75 | ;; 76 | *.xcdatamodeld) 77 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 78 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 79 | ;; 80 | *.xcmappingmodel) 81 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 82 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 83 | ;; 84 | *.xcassets) 85 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 86 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 87 | ;; 88 | *) 89 | echo "$RESOURCE_PATH" || true 90 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 91 | ;; 92 | esac 93 | } 94 | 95 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 96 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 97 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 98 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 99 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 100 | fi 101 | rm -f "$RESOURCES_TO_COPY" 102 | 103 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] 104 | then 105 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 106 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 107 | while read line; do 108 | if [[ $line != "${PODS_ROOT}*" ]]; then 109 | XCASSET_FILES+=("$line") 110 | fi 111 | done <<<"$OTHER_XCASSETS" 112 | 113 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then 114 | 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}" 115 | else 116 | 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}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" 117 | fi 118 | fi 119 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-demo/Pods-demo-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_demoVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_demoVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-demo/Pods-demo.debug.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 3 | PODS_BUILD_DIR = ${BUILD_DIR} 4 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 5 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 6 | PODS_ROOT = ${SRCROOT}/Pods 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-demo/Pods-demo.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_demo { 2 | umbrella header "Pods-demo-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-demo/Pods-demo.release.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 3 | PODS_BUILD_DIR = ${BUILD_DIR} 4 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 5 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 6 | PODS_ROOT = ${SRCROOT}/Pods 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-drawer-view/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 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-drawer-view/Pods-drawer-view-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-drawer-view/Pods-drawer-view-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 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-drawer-view/Pods-drawer-view-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_drawer_view : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_drawer_view 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-drawer-view/Pods-drawer-view-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then 7 | # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # resources to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 13 | 14 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 15 | > "$RESOURCES_TO_COPY" 16 | 17 | XCASSET_FILES=() 18 | 19 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 20 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 21 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 22 | 23 | case "${TARGETED_DEVICE_FAMILY:-}" in 24 | 1,2) 25 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 26 | ;; 27 | 1) 28 | TARGET_DEVICE_ARGS="--target-device iphone" 29 | ;; 30 | 2) 31 | TARGET_DEVICE_ARGS="--target-device ipad" 32 | ;; 33 | 3) 34 | TARGET_DEVICE_ARGS="--target-device tv" 35 | ;; 36 | 4) 37 | TARGET_DEVICE_ARGS="--target-device watch" 38 | ;; 39 | *) 40 | TARGET_DEVICE_ARGS="--target-device mac" 41 | ;; 42 | esac 43 | 44 | install_resource() 45 | { 46 | if [[ "$1" = /* ]] ; then 47 | RESOURCE_PATH="$1" 48 | else 49 | RESOURCE_PATH="${PODS_ROOT}/$1" 50 | fi 51 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 52 | cat << EOM 53 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 54 | EOM 55 | exit 1 56 | fi 57 | case $RESOURCE_PATH in 58 | *.storyboard) 59 | 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 60 | 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} 61 | ;; 62 | *.xib) 63 | 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 64 | 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} 65 | ;; 66 | *.framework) 67 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 68 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 69 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 70 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 71 | ;; 72 | *.xcdatamodel) 73 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 74 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 75 | ;; 76 | *.xcdatamodeld) 77 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 78 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 79 | ;; 80 | *.xcmappingmodel) 81 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 82 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 83 | ;; 84 | *.xcassets) 85 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 86 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 87 | ;; 88 | *) 89 | echo "$RESOURCE_PATH" || true 90 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 91 | ;; 92 | esac 93 | } 94 | 95 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 96 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 97 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 98 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 99 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 100 | fi 101 | rm -f "$RESOURCES_TO_COPY" 102 | 103 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] 104 | then 105 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 106 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 107 | while read line; do 108 | if [[ $line != "${PODS_ROOT}*" ]]; then 109 | XCASSET_FILES+=("$line") 110 | fi 111 | done <<<"$OTHER_XCASSETS" 112 | 113 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then 114 | 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}" 115 | else 116 | 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}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" 117 | fi 118 | fi 119 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-drawer-view/Pods-drawer-view-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_drawer_viewVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_drawer_viewVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-drawer-view/Pods-drawer-view.debug.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks' 3 | PODS_BUILD_DIR = ${BUILD_DIR} 4 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 5 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 6 | PODS_ROOT = ${SRCROOT}/Pods 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-drawer-view/Pods-drawer-view.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_drawer_view { 2 | umbrella header "Pods-drawer-view-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-drawer-view/Pods-drawer-view.release.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' '@executable_path/../../Frameworks' 3 | PODS_BUILD_DIR = ${BUILD_DIR} 4 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 5 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 6 | PODS_ROOT = ${SRCROOT}/Pods 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # drawer-view [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome) 2 | 3 | [![Platforms](https://img.shields.io/badge/platform-iOS-yellow.svg)]() 4 | [![Language](https://img.shields.io/badge/language-Swift_5.0-orange.svg)]() 5 | [![Autolayout](https://img.shields.io/badge/autolayout-enabled-blue.svg)]() 6 | [![CocoaPod](https://img.shields.io/badge/pod-1.0.4-lightblue.svg)]() 7 | [![License](https://img.shields.io/badge/license-MIT-blue.svg)]() 8 | 9 | **Last Update: 06/April/2019.** 10 | 11 | ![](logo-drawer_view.png) 12 | 13 | ### If you like the project, please give it a star ⭐ It will show the creator your appreciation and help others to discover the repo. 14 | 15 | # ✍️ About 16 | 📤 Drawer View is a custom UI component, replication of Apple's Apple Music player and Shortcuts' `components` view (also can be seen in `Maps` app). 17 | 18 | # 🏗 Installation 19 | ## CocoaPods 20 | `drawer-view` is availabe via `CocoaPods` 21 | 22 | ``` 23 | pod 'drawer-view', '~> 1.0.4' 24 | ``` 25 | ## Manual 26 | You can always use `copy-paste` the sources method 😄. Or you can compile the framework and include it with your project. 27 | 28 | # 📺 Demo 29 | Please wait while the `.gif` files are loading... (they are about `25Mb`) 30 | 31 |

32 | 33 | 34 | 35 |

36 | 37 |

38 | Drawing 39 |

40 | 41 | # 🍱 Features 42 | 43 | - **Easy to use** 44 | - You only need to instantiate a class called `DrawerView` and add your UI components. 45 | - **Flexible `API`** 46 | - Includes a number of customization points that allows to decorate the `DrawerView` as you'd like. 47 | - **Callbacks** 48 | - You can use built-in callbacks in order to integrate animations or get the state changes. 49 | - **Behavior** 50 | - You may tell the component to close the drawer when the device is rotated or user interacts with the child components. 51 | - **Autolayout** 52 | - You don't need to do anything related to autolayout - the component properly handles all the changes. The only thing you need to do is to add your `UI` components and make sure that aulayout constraints are properly setup for them. 53 | 54 | # 📚 Code Samples 55 | 56 | ## Instantiation 57 | 58 | The most simple instantiation: you only need to provide the `superview`: 59 | ```swift 60 | let _ = DrawerView(superView: view) 61 | ``` 62 | 63 | You can specify how much space will be between top anchor of the `DrawerView` and the `superview` by setting `topLayoutGuidePadding` property and how tall the `DrawerView` will be when it is closed by setting `closedHeight` property: 64 | ```swift 65 | let _ = DrawerView(topLayoutGuidePadding: 100, closedHeight: 82, superView: view) 66 | ``` 67 | 68 | You can specify `blur` effect and its type. It will be animated alongside with the drawer view. There are several styles for `blur`: 69 | ```swift 70 | let _ = DrawerView(blurStyle: .light, superView: view) 71 | ``` 72 | 73 | By default the `DrawerView` will include a visual indicator called `LineArrow`. `LineArrow` is an indicator that decorates the view and helps a user with interaction. You can change the properties of the indicator by setting its `height`, `width` and `color`: 74 | ```swift 75 | let _ = DrawerView(lineArrow: (height: 8, width: 82, color: .black), superView: view) 76 | // Or you can set `nil` in order to turn the indicator off 77 | ``` 78 | 79 | ## Properties & Methods 80 | 81 | You can change the behavior of the component when a device is rotated. By default the `DrawerView` will not be closed when a device is rotated. However, you can change this behavior: 82 | ```swift 83 | drawerView.closeOnRotation = true 84 | ``` 85 | 86 | You can programmatically change the state of the component: 87 | ```swift 88 | drawerView.change(state: .open, shouldAnimate: true) 89 | ``` 90 | 91 | By default, interactions with the child views don't affect the `DrawerView` anyhow. However, you can change this behavior and allow the `DrawerView` to be dismissed when one of the child views are interacted: 92 | ```swift 93 | drawerView.closeOnChildViewTaps = true 94 | ``` 95 | 96 | There is an animation closure that is used to animate the external components alongside with the `DrawerView`: 97 | ```swift 98 | drawerView.animationClosure = { state in 99 | switch state { 100 | case .open: 101 | someOtherView.alpha = 1.0 102 | case .closed: 103 | someOtherView.alpha = 0.0 104 | } 105 | } 106 | ``` 107 | 108 | You can optionally specify a completion closure that gets called when animation is completed: 109 | ```swift 110 | drawerView.completionClosure = { state in 111 | switch state { 112 | case .open: 113 | service.launch() 114 | case .closed: 115 | service.dismiss() 116 | } 117 | } 118 | ``` 119 | 120 | The third and final callback closure can be used to get `DrawerView`state changes: 121 | ```swift 122 | drawerView.onStateChangeClosure = { state in 123 | state == .closed ? showDialog() : doNothing() 124 | } 125 | ``` 126 | 127 | ## Other settable properties 128 | 129 | Also there are many other properties that be customized: 130 | ```swift 131 | drawerView.cornerRadius = 60 132 | drawerView.animationDuration = 2.5 133 | drawerView.animationDampingRatio = 0.9 134 | drawerView.shadowRadius = 0.25 135 | drawerView.shadowOpacity = 0.132 136 | drawerView.closeOnBlurTapped = true 137 | drawerView.closeOnDrawerTaps = true 138 | ``` 139 | 140 | # 👨‍💻 Author 141 | [Astemir Eleev](https://github.com/jVirus) 142 | 143 | # 🔖 Licence 144 | The project is available under [MIT licence](https://github.com/jVirus/drawer-view/blob/master/LICENSE) 145 | -------------------------------------------------------------------------------- /assets/drawer-view demo 01.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/drawer-view/27e74972e3d1603a95bda8af0ae994910b9712e2/assets/drawer-view demo 01.gif -------------------------------------------------------------------------------- /assets/drawer-view demo 02.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/drawer-view/27e74972e3d1603a95bda8af0ae994910b9712e2/assets/drawer-view demo 02.gif -------------------------------------------------------------------------------- /assets/drawer-view demo 03.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/drawer-view/27e74972e3d1603a95bda8af0ae994910b9712e2/assets/drawer-view demo 03.gif -------------------------------------------------------------------------------- /assets/drawer-view demo 04.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/drawer-view/27e74972e3d1603a95bda8af0ae994910b9712e2/assets/drawer-view demo 04.gif -------------------------------------------------------------------------------- /demo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // demo 4 | // 5 | // Created by Astemir Eleev on 26/11/2018. 6 | // Copyright © 2018 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /demo/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 | } -------------------------------------------------------------------------------- /demo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /demo/Assets.xcassets/IMG_23879.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "IMG_23879.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /demo/Assets.xcassets/IMG_23879.imageset/IMG_23879.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/drawer-view/27e74972e3d1603a95bda8af0ae994910b9712e2/demo/Assets.xcassets/IMG_23879.imageset/IMG_23879.png -------------------------------------------------------------------------------- /demo/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 | -------------------------------------------------------------------------------- /demo/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 | -------------------------------------------------------------------------------- /demo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Drawer View Demo 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UIRequiresFullScreen 34 | 35 | UIStatusBarHidden 36 | 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationLandscapeLeft 41 | UIInterfaceOrientationLandscapeRight 42 | 43 | UISupportedInterfaceOrientations~ipad 44 | 45 | UIInterfaceOrientationPortrait 46 | UIInterfaceOrientationPortraitUpsideDown 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /demo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // demo 4 | // 5 | // Created by Astemir Eleev on 26/11/2018. 6 | // Copyright © 2018 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import drawer_view 11 | 12 | class ViewController: UIViewController { 13 | 14 | private var drawerView: DrawerView! 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | // Do any additional setup after loading the view, typically from a nib. 19 | 20 | drawerView = DrawerView(topLayoutGuidePadding: 200, 21 | closedHeight: 80, 22 | blurStyle: .extraLight, 23 | superView: view) 24 | 25 | // drawerView.closeOnRotation = true 26 | // drawerView.change(state: .open, shouldAnimate: true) 27 | // drawerView.closeOnChildViewTaps = true 28 | // drawerView.animationClosure 29 | // drawerView.completionClosure 30 | // drawerView.onStateChangeClosure 31 | // drawerView.cornerRadius = 60 32 | // drawerView.animationDuration = 1.5 33 | // drawerView.animationDampingRatio = 1.0 34 | // drawerView.shadowRadius 35 | // drawerView.shadowOpacity 36 | 37 | // return () 38 | 39 | drawerView.titleLabelAnimator = DefaultTitleLabelAnimator(text: "Title Label") 40 | 41 | // let closeButton = UIButton(type: .system) 42 | // drawerView.addSubview(closeButton) 43 | // 44 | // closeButton.backgroundColor = UIColor.init(white: 1.0, alpha: 0.5) 45 | // closeButton.setTitleColor(.black, for: .normal) 46 | // closeButton.titleLabel?.font = UIFont.systemFont(ofSize: 17, weight: .bold) 47 | // closeButton.setTitle("Close", for: .normal) 48 | // 49 | // closeButton.translatesAutoresizingMaskIntoConstraints = false 50 | // 51 | // NSLayoutConstraint.activate([ 52 | // closeButton.centerXAnchor.constraint(equalTo: (drawerView?.centerXAnchor)!, constant: 0.0), 53 | // closeButton.centerYAnchor.constraint(equalTo: (drawerView?.centerYAnchor)!, constant: 0.0) 54 | // ]) 55 | // 56 | // debugPrint("DrawerView subviews: ", drawerView.subviews) 57 | } 58 | 59 | override var prefersStatusBarHidden: Bool { 60 | return true 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /drawer-view.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint drawer-view.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "drawer-view" 19 | s.version = "1.0.4" 20 | s.summary = "📤 Drawer View is a custom UI component replication of Apple's Apple Music player and Shortcuts components view" 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | s.description = <<-DESC 28 | 📤 `Drawer View` is a custom UI component replication of Apple's `Apple Music` player and `Shortcuts` components view 29 | DESC 30 | 31 | s.homepage = "https://github.com/jVirus/drawer-view" 32 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 33 | 34 | 35 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 36 | # 37 | # Licensing your code is important. See http://choosealicense.com for more info. 38 | # CocoaPods will detect a license file if there is a named LICENSE* 39 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 40 | # 41 | 42 | # s.license = "MIT (example)" 43 | s.license = { :type => "MIT", :file => "LICENSE" } 44 | 45 | 46 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 47 | # 48 | # Specify the authors of the library, with email addresses. Email addresses 49 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 50 | # accepts just a name if you'd rather not provide an email address. 51 | # 52 | # Specify a social_media_url where others can refer to, for example a twitter 53 | # profile URL. 54 | # 55 | 56 | # s.author = { "Astemir Eleev" => "astemireleev@domen.com" } 57 | s.author = { "Astemir Eleev" => "astemireleev@gmail.com" } 58 | # Or just: s.author = "Astemir Eleev" 59 | # s.authors = { "Astemir Eleev" => "astemireleev@domen.com" } 60 | # s.social_media_url = "http://twitter.com/Astemir Eleev" 61 | 62 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 63 | # 64 | # If this Pod runs only on iOS or OS X, then specify the platform and 65 | # the deployment target. You can optionally include the target after the platform. 66 | # 67 | 68 | s.platform = :ios 69 | # s.platform = :ios, "5.0" 70 | 71 | # When using multiple platforms 72 | s.ios.deployment_target = "11.0" 73 | # s.osx.deployment_target = "10.12" 74 | # s.watchos.deployment_target = "4.0" 75 | # s.tvos.deployment_target = "11.0" 76 | 77 | 78 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 79 | # 80 | # Specify the location from where the source should be retrieved. 81 | # Supports git, hg, bzr, svn and HTTP. 82 | # 83 | 84 | # "#{s.version}" 85 | s.source = { :git => "https://github.com/jVirus/drawer-view.git", :tag => s.version.to_s } 86 | 87 | 88 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 89 | # 90 | # CocoaPods is smart about how it includes source code. For source files 91 | # giving a folder will include any swift, h, m, mm, c & cpp files. 92 | # For header files it will include any header in the folder. 93 | # Not including the public_header_files will make all headers public. 94 | # 95 | 96 | s.source_files = "drawer-view/**/*.swift" 97 | # s.exclude_files = "Classes/Exclude" 98 | 99 | # s.public_header_files = "drawer-view/**/*.h" 100 | 101 | 102 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 103 | # 104 | # A list of resources included with the Pod. These are copied into the 105 | # target bundle with a build phase script. Anything else will be cleaned. 106 | # You can preserve files from being cleaned, please don't preserve 107 | # non-essential files like tests, examples and documentation. 108 | # 109 | 110 | # s.resource = "icon.png" 111 | # s.resources = "Resources/*.png" 112 | 113 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 114 | 115 | 116 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 117 | # 118 | # Link your library with frameworks, or libraries. Libraries do not include 119 | # the lib prefix of their name. 120 | # 121 | 122 | # s.framework = "SomeFramework" 123 | # s.frameworks = "SomeFramework", "AnotherFramework" 124 | 125 | # s.library = "iconv" 126 | # s.libraries = "iconv", "xml2" 127 | 128 | 129 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 130 | # 131 | # If your library depends on compiler flags you can set them in the xcconfig hash 132 | # where they will only apply to your library. If you depend on other Podspecs 133 | # you can include multiple dependencies to ensure it works. 134 | 135 | # s.requires_arc = true 136 | 137 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 138 | # s.dependency "JSONKit", "~> 1.4" 139 | 140 | s.requires_arc = true 141 | s.pod_target_xcconfig = { 'SWIFT_VERSION' => '5.0' } 142 | s.swift_version = "5.0" 143 | 144 | end 145 | -------------------------------------------------------------------------------- /drawer-view.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 27BD28860C40DA152FAB3BC4 /* Pods_demo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B7F552B3B05E9A762C4F5FF1 /* Pods_demo.framework */; }; 11 | 42223C60E46CF9E45A69B2C5 /* Pods_drawer_view.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3BF7465B617D4FAA4591D193 /* Pods_drawer_view.framework */; }; 12 | A917125A21AEC0F30091AFF5 /* LineArrowShapeLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A917125921AEC0F30091AFF5 /* LineArrowShapeLayer.swift */; }; 13 | A917125C21AEC1230091AFF5 /* DrawerView.BlurStyle+Convert.swift in Sources */ = {isa = PBXBuildFile; fileRef = A917125B21AEC1230091AFF5 /* DrawerView.BlurStyle+Convert.swift */; }; 14 | A917125E21AEC1450091AFF5 /* DrawerView.State+Opposite.swift in Sources */ = {isa = PBXBuildFile; fileRef = A917125D21AEC1450091AFF5 /* DrawerView.State+Opposite.swift */; }; 15 | A917126021AED9830091AFF5 /* DefaultTitleLabelAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A917125F21AED9830091AFF5 /* DefaultTitleLabelAnimator.swift */; }; 16 | A917126221AEEA490091AFF5 /* TitleLabelAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A917126121AEEA490091AFF5 /* TitleLabelAnimator.swift */; }; 17 | A95C228021AFD67B008E8B39 /* drawer_view.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A95CFFA821AC36CD008B0E8E /* drawer_view.framework */; }; 18 | A95C228121AFD67B008E8B39 /* drawer_view.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A95CFFA821AC36CD008B0E8E /* drawer_view.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 19 | A95CEB3D225896E700BE8591 /* DrawerViewTouchHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = A95CEB3C225896E700BE8591 /* DrawerViewTouchHandling.swift */; }; 20 | A95CFFAD21AC36CD008B0E8E /* drawer_view.h in Headers */ = {isa = PBXBuildFile; fileRef = A95CFFAB21AC36CD008B0E8E /* drawer_view.h */; settings = {ATTRIBUTES = (Public, ); }; }; 21 | A95CFFB421AC36EF008B0E8E /* ImmediatePanGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A95CFFB321AC36EF008B0E8E /* ImmediatePanGestureRecognizer.swift */; }; 22 | A95CFFB621AC3706008B0E8E /* DrawerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A95CFFB521AC3706008B0E8E /* DrawerView.swift */; }; 23 | A95CFFB821AC372F008B0E8E /* .gitignore in Resources */ = {isa = PBXBuildFile; fileRef = A95CFFB721AC372F008B0E8E /* .gitignore */; }; 24 | A95CFFC021AC37A1008B0E8E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A95CFFBF21AC37A1008B0E8E /* AppDelegate.swift */; }; 25 | A95CFFC221AC37A1008B0E8E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A95CFFC121AC37A1008B0E8E /* ViewController.swift */; }; 26 | A95CFFC521AC37A1008B0E8E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A95CFFC321AC37A1008B0E8E /* Main.storyboard */; }; 27 | A95CFFC721AC37A3008B0E8E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A95CFFC621AC37A3008B0E8E /* Assets.xcassets */; }; 28 | A95CFFCA21AC37A3008B0E8E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A95CFFC821AC37A3008B0E8E /* LaunchScreen.storyboard */; }; 29 | /* End PBXBuildFile section */ 30 | 31 | /* Begin PBXContainerItemProxy section */ 32 | A95C228221AFD67B008E8B39 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = A95CFF9F21AC36CD008B0E8E /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = A95CFFA721AC36CD008B0E8E; 37 | remoteInfo = "drawer-view"; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXCopyFilesBuildPhase section */ 42 | A95C228421AFD67B008E8B39 /* Embed Frameworks */ = { 43 | isa = PBXCopyFilesBuildPhase; 44 | buildActionMask = 2147483647; 45 | dstPath = ""; 46 | dstSubfolderSpec = 10; 47 | files = ( 48 | A95C228121AFD67B008E8B39 /* drawer_view.framework in Embed Frameworks */, 49 | ); 50 | name = "Embed Frameworks"; 51 | runOnlyForDeploymentPostprocessing = 0; 52 | }; 53 | /* End PBXCopyFilesBuildPhase section */ 54 | 55 | /* Begin PBXFileReference section */ 56 | 29D93570AD4AD783407212BA /* Pods-drawer-view.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-drawer-view.release.xcconfig"; path = "Pods/Target Support Files/Pods-drawer-view/Pods-drawer-view.release.xcconfig"; sourceTree = ""; }; 57 | 3BF7465B617D4FAA4591D193 /* Pods_drawer_view.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_drawer_view.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | 5A05DA3074F947B644045E84 /* Pods-drawer-view.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-drawer-view.debug.xcconfig"; path = "Pods/Target Support Files/Pods-drawer-view/Pods-drawer-view.debug.xcconfig"; sourceTree = ""; }; 59 | 82C2C949031EF4E6C7CC31D1 /* Pods-demo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-demo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-demo/Pods-demo.debug.xcconfig"; sourceTree = ""; }; 60 | A917125921AEC0F30091AFF5 /* LineArrowShapeLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineArrowShapeLayer.swift; sourceTree = ""; }; 61 | A917125B21AEC1230091AFF5 /* DrawerView.BlurStyle+Convert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DrawerView.BlurStyle+Convert.swift"; sourceTree = ""; }; 62 | A917125D21AEC1450091AFF5 /* DrawerView.State+Opposite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DrawerView.State+Opposite.swift"; sourceTree = ""; }; 63 | A917125F21AED9830091AFF5 /* DefaultTitleLabelAnimator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultTitleLabelAnimator.swift; sourceTree = ""; }; 64 | A917126121AEEA490091AFF5 /* TitleLabelAnimator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleLabelAnimator.swift; sourceTree = ""; }; 65 | A95CEB3C225896E700BE8591 /* DrawerViewTouchHandling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DrawerViewTouchHandling.swift; sourceTree = ""; }; 66 | A95CFFA821AC36CD008B0E8E /* drawer_view.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = drawer_view.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 67 | A95CFFAB21AC36CD008B0E8E /* drawer_view.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = drawer_view.h; sourceTree = ""; }; 68 | A95CFFAC21AC36CD008B0E8E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 69 | A95CFFB321AC36EF008B0E8E /* ImmediatePanGestureRecognizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImmediatePanGestureRecognizer.swift; sourceTree = ""; }; 70 | A95CFFB521AC3706008B0E8E /* DrawerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DrawerView.swift; sourceTree = ""; }; 71 | A95CFFB721AC372F008B0E8E /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; 72 | A95CFFBD21AC37A1008B0E8E /* demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = demo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 73 | A95CFFBF21AC37A1008B0E8E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 74 | A95CFFC121AC37A1008B0E8E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 75 | A95CFFC421AC37A1008B0E8E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 76 | A95CFFC621AC37A3008B0E8E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 77 | A95CFFC921AC37A3008B0E8E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 78 | A95CFFCB21AC37A3008B0E8E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 79 | B7F552B3B05E9A762C4F5FF1 /* Pods_demo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_demo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 80 | E06FF2D202F4E2F1D7B8B1F9 /* Pods-demo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-demo.release.xcconfig"; path = "Pods/Target Support Files/Pods-demo/Pods-demo.release.xcconfig"; sourceTree = ""; }; 81 | /* End PBXFileReference section */ 82 | 83 | /* Begin PBXFrameworksBuildPhase section */ 84 | A95CFFA521AC36CD008B0E8E /* Frameworks */ = { 85 | isa = PBXFrameworksBuildPhase; 86 | buildActionMask = 2147483647; 87 | files = ( 88 | 42223C60E46CF9E45A69B2C5 /* Pods_drawer_view.framework in Frameworks */, 89 | ); 90 | runOnlyForDeploymentPostprocessing = 0; 91 | }; 92 | A95CFFBA21AC37A1008B0E8E /* Frameworks */ = { 93 | isa = PBXFrameworksBuildPhase; 94 | buildActionMask = 2147483647; 95 | files = ( 96 | A95C228021AFD67B008E8B39 /* drawer_view.framework in Frameworks */, 97 | 27BD28860C40DA152FAB3BC4 /* Pods_demo.framework in Frameworks */, 98 | ); 99 | runOnlyForDeploymentPostprocessing = 0; 100 | }; 101 | /* End PBXFrameworksBuildPhase section */ 102 | 103 | /* Begin PBXGroup section */ 104 | A917125721AE65A40091AFF5 /* Frameworks */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | B7F552B3B05E9A762C4F5FF1 /* Pods_demo.framework */, 108 | 3BF7465B617D4FAA4591D193 /* Pods_drawer_view.framework */, 109 | ); 110 | name = Frameworks; 111 | sourceTree = ""; 112 | }; 113 | A95CFF9E21AC36CD008B0E8E = { 114 | isa = PBXGroup; 115 | children = ( 116 | A95CFFB721AC372F008B0E8E /* .gitignore */, 117 | A95CFFAA21AC36CD008B0E8E /* drawer-view */, 118 | A95CFFBE21AC37A1008B0E8E /* demo */, 119 | A95CFFA921AC36CD008B0E8E /* Products */, 120 | A917125721AE65A40091AFF5 /* Frameworks */, 121 | B1680C3354F5D92D62C024E8 /* Pods */, 122 | ); 123 | sourceTree = ""; 124 | }; 125 | A95CFFA921AC36CD008B0E8E /* Products */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | A95CFFA821AC36CD008B0E8E /* drawer_view.framework */, 129 | A95CFFBD21AC37A1008B0E8E /* demo.app */, 130 | ); 131 | name = Products; 132 | sourceTree = ""; 133 | }; 134 | A95CFFAA21AC36CD008B0E8E /* drawer-view */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | A95CFFAB21AC36CD008B0E8E /* drawer_view.h */, 138 | A95CFFAC21AC36CD008B0E8E /* Info.plist */, 139 | A95CFFB321AC36EF008B0E8E /* ImmediatePanGestureRecognizer.swift */, 140 | A95CEB3C225896E700BE8591 /* DrawerViewTouchHandling.swift */, 141 | A95CFFB521AC3706008B0E8E /* DrawerView.swift */, 142 | A917125B21AEC1230091AFF5 /* DrawerView.BlurStyle+Convert.swift */, 143 | A917125D21AEC1450091AFF5 /* DrawerView.State+Opposite.swift */, 144 | A917126121AEEA490091AFF5 /* TitleLabelAnimator.swift */, 145 | A917125F21AED9830091AFF5 /* DefaultTitleLabelAnimator.swift */, 146 | A917125921AEC0F30091AFF5 /* LineArrowShapeLayer.swift */, 147 | ); 148 | path = "drawer-view"; 149 | sourceTree = ""; 150 | }; 151 | A95CFFBE21AC37A1008B0E8E /* demo */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | A95CFFBF21AC37A1008B0E8E /* AppDelegate.swift */, 155 | A95CFFC121AC37A1008B0E8E /* ViewController.swift */, 156 | A95CFFC321AC37A1008B0E8E /* Main.storyboard */, 157 | A95CFFC621AC37A3008B0E8E /* Assets.xcassets */, 158 | A95CFFC821AC37A3008B0E8E /* LaunchScreen.storyboard */, 159 | A95CFFCB21AC37A3008B0E8E /* Info.plist */, 160 | ); 161 | path = demo; 162 | sourceTree = ""; 163 | }; 164 | B1680C3354F5D92D62C024E8 /* Pods */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | 82C2C949031EF4E6C7CC31D1 /* Pods-demo.debug.xcconfig */, 168 | E06FF2D202F4E2F1D7B8B1F9 /* Pods-demo.release.xcconfig */, 169 | 5A05DA3074F947B644045E84 /* Pods-drawer-view.debug.xcconfig */, 170 | 29D93570AD4AD783407212BA /* Pods-drawer-view.release.xcconfig */, 171 | ); 172 | name = Pods; 173 | sourceTree = ""; 174 | }; 175 | /* End PBXGroup section */ 176 | 177 | /* Begin PBXHeadersBuildPhase section */ 178 | A95CFFA321AC36CD008B0E8E /* Headers */ = { 179 | isa = PBXHeadersBuildPhase; 180 | buildActionMask = 2147483647; 181 | files = ( 182 | A95CFFAD21AC36CD008B0E8E /* drawer_view.h in Headers */, 183 | ); 184 | runOnlyForDeploymentPostprocessing = 0; 185 | }; 186 | /* End PBXHeadersBuildPhase section */ 187 | 188 | /* Begin PBXNativeTarget section */ 189 | A95CFFA721AC36CD008B0E8E /* drawer-view */ = { 190 | isa = PBXNativeTarget; 191 | buildConfigurationList = A95CFFB021AC36CD008B0E8E /* Build configuration list for PBXNativeTarget "drawer-view" */; 192 | buildPhases = ( 193 | 05E0869271AED9B69642CFA1 /* [CP] Check Pods Manifest.lock */, 194 | A95CFFA321AC36CD008B0E8E /* Headers */, 195 | A95CFFA421AC36CD008B0E8E /* Sources */, 196 | A95CFFA521AC36CD008B0E8E /* Frameworks */, 197 | A95CFFA621AC36CD008B0E8E /* Resources */, 198 | ); 199 | buildRules = ( 200 | ); 201 | dependencies = ( 202 | ); 203 | name = "drawer-view"; 204 | productName = "drawer-view"; 205 | productReference = A95CFFA821AC36CD008B0E8E /* drawer_view.framework */; 206 | productType = "com.apple.product-type.framework"; 207 | }; 208 | A95CFFBC21AC37A1008B0E8E /* demo */ = { 209 | isa = PBXNativeTarget; 210 | buildConfigurationList = A95CFFCC21AC37A3008B0E8E /* Build configuration list for PBXNativeTarget "demo" */; 211 | buildPhases = ( 212 | BC13C454F55765B979E4E458 /* [CP] Check Pods Manifest.lock */, 213 | A95CFFB921AC37A1008B0E8E /* Sources */, 214 | A95CFFBA21AC37A1008B0E8E /* Frameworks */, 215 | A95CFFBB21AC37A1008B0E8E /* Resources */, 216 | A95C228421AFD67B008E8B39 /* Embed Frameworks */, 217 | ); 218 | buildRules = ( 219 | ); 220 | dependencies = ( 221 | A95C228321AFD67B008E8B39 /* PBXTargetDependency */, 222 | ); 223 | name = demo; 224 | productName = demo; 225 | productReference = A95CFFBD21AC37A1008B0E8E /* demo.app */; 226 | productType = "com.apple.product-type.application"; 227 | }; 228 | /* End PBXNativeTarget section */ 229 | 230 | /* Begin PBXProject section */ 231 | A95CFF9F21AC36CD008B0E8E /* Project object */ = { 232 | isa = PBXProject; 233 | attributes = { 234 | LastSwiftUpdateCheck = 1010; 235 | LastUpgradeCheck = 1010; 236 | ORGANIZATIONNAME = "Astemir Eleev"; 237 | TargetAttributes = { 238 | A95CFFA721AC36CD008B0E8E = { 239 | CreatedOnToolsVersion = 10.1; 240 | LastSwiftMigration = 1020; 241 | }; 242 | A95CFFBC21AC37A1008B0E8E = { 243 | CreatedOnToolsVersion = 10.1; 244 | LastSwiftMigration = 1020; 245 | }; 246 | }; 247 | }; 248 | buildConfigurationList = A95CFFA221AC36CD008B0E8E /* Build configuration list for PBXProject "drawer-view" */; 249 | compatibilityVersion = "Xcode 9.3"; 250 | developmentRegion = en; 251 | hasScannedForEncodings = 0; 252 | knownRegions = ( 253 | en, 254 | Base, 255 | ); 256 | mainGroup = A95CFF9E21AC36CD008B0E8E; 257 | productRefGroup = A95CFFA921AC36CD008B0E8E /* Products */; 258 | projectDirPath = ""; 259 | projectRoot = ""; 260 | targets = ( 261 | A95CFFA721AC36CD008B0E8E /* drawer-view */, 262 | A95CFFBC21AC37A1008B0E8E /* demo */, 263 | ); 264 | }; 265 | /* End PBXProject section */ 266 | 267 | /* Begin PBXResourcesBuildPhase section */ 268 | A95CFFA621AC36CD008B0E8E /* Resources */ = { 269 | isa = PBXResourcesBuildPhase; 270 | buildActionMask = 2147483647; 271 | files = ( 272 | A95CFFB821AC372F008B0E8E /* .gitignore in Resources */, 273 | ); 274 | runOnlyForDeploymentPostprocessing = 0; 275 | }; 276 | A95CFFBB21AC37A1008B0E8E /* Resources */ = { 277 | isa = PBXResourcesBuildPhase; 278 | buildActionMask = 2147483647; 279 | files = ( 280 | A95CFFCA21AC37A3008B0E8E /* LaunchScreen.storyboard in Resources */, 281 | A95CFFC721AC37A3008B0E8E /* Assets.xcassets in Resources */, 282 | A95CFFC521AC37A1008B0E8E /* Main.storyboard in Resources */, 283 | ); 284 | runOnlyForDeploymentPostprocessing = 0; 285 | }; 286 | /* End PBXResourcesBuildPhase section */ 287 | 288 | /* Begin PBXShellScriptBuildPhase section */ 289 | 05E0869271AED9B69642CFA1 /* [CP] Check Pods Manifest.lock */ = { 290 | isa = PBXShellScriptBuildPhase; 291 | buildActionMask = 2147483647; 292 | files = ( 293 | ); 294 | inputFileListPaths = ( 295 | ); 296 | inputPaths = ( 297 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 298 | "${PODS_ROOT}/Manifest.lock", 299 | ); 300 | name = "[CP] Check Pods Manifest.lock"; 301 | outputFileListPaths = ( 302 | ); 303 | outputPaths = ( 304 | "$(DERIVED_FILE_DIR)/Pods-drawer-view-checkManifestLockResult.txt", 305 | ); 306 | runOnlyForDeploymentPostprocessing = 0; 307 | shellPath = /bin/sh; 308 | 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"; 309 | showEnvVarsInLog = 0; 310 | }; 311 | BC13C454F55765B979E4E458 /* [CP] Check Pods Manifest.lock */ = { 312 | isa = PBXShellScriptBuildPhase; 313 | buildActionMask = 2147483647; 314 | files = ( 315 | ); 316 | inputFileListPaths = ( 317 | ); 318 | inputPaths = ( 319 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 320 | "${PODS_ROOT}/Manifest.lock", 321 | ); 322 | name = "[CP] Check Pods Manifest.lock"; 323 | outputFileListPaths = ( 324 | ); 325 | outputPaths = ( 326 | "$(DERIVED_FILE_DIR)/Pods-demo-checkManifestLockResult.txt", 327 | ); 328 | runOnlyForDeploymentPostprocessing = 0; 329 | shellPath = /bin/sh; 330 | 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"; 331 | showEnvVarsInLog = 0; 332 | }; 333 | /* End PBXShellScriptBuildPhase section */ 334 | 335 | /* Begin PBXSourcesBuildPhase section */ 336 | A95CFFA421AC36CD008B0E8E /* Sources */ = { 337 | isa = PBXSourcesBuildPhase; 338 | buildActionMask = 2147483647; 339 | files = ( 340 | A95CEB3D225896E700BE8591 /* DrawerViewTouchHandling.swift in Sources */, 341 | A917126221AEEA490091AFF5 /* TitleLabelAnimator.swift in Sources */, 342 | A917125A21AEC0F30091AFF5 /* LineArrowShapeLayer.swift in Sources */, 343 | A917125C21AEC1230091AFF5 /* DrawerView.BlurStyle+Convert.swift in Sources */, 344 | A95CFFB421AC36EF008B0E8E /* ImmediatePanGestureRecognizer.swift in Sources */, 345 | A917126021AED9830091AFF5 /* DefaultTitleLabelAnimator.swift in Sources */, 346 | A95CFFB621AC3706008B0E8E /* DrawerView.swift in Sources */, 347 | A917125E21AEC1450091AFF5 /* DrawerView.State+Opposite.swift in Sources */, 348 | ); 349 | runOnlyForDeploymentPostprocessing = 0; 350 | }; 351 | A95CFFB921AC37A1008B0E8E /* Sources */ = { 352 | isa = PBXSourcesBuildPhase; 353 | buildActionMask = 2147483647; 354 | files = ( 355 | A95CFFC221AC37A1008B0E8E /* ViewController.swift in Sources */, 356 | A95CFFC021AC37A1008B0E8E /* AppDelegate.swift in Sources */, 357 | ); 358 | runOnlyForDeploymentPostprocessing = 0; 359 | }; 360 | /* End PBXSourcesBuildPhase section */ 361 | 362 | /* Begin PBXTargetDependency section */ 363 | A95C228321AFD67B008E8B39 /* PBXTargetDependency */ = { 364 | isa = PBXTargetDependency; 365 | target = A95CFFA721AC36CD008B0E8E /* drawer-view */; 366 | targetProxy = A95C228221AFD67B008E8B39 /* PBXContainerItemProxy */; 367 | }; 368 | /* End PBXTargetDependency section */ 369 | 370 | /* Begin PBXVariantGroup section */ 371 | A95CFFC321AC37A1008B0E8E /* Main.storyboard */ = { 372 | isa = PBXVariantGroup; 373 | children = ( 374 | A95CFFC421AC37A1008B0E8E /* Base */, 375 | ); 376 | name = Main.storyboard; 377 | sourceTree = ""; 378 | }; 379 | A95CFFC821AC37A3008B0E8E /* LaunchScreen.storyboard */ = { 380 | isa = PBXVariantGroup; 381 | children = ( 382 | A95CFFC921AC37A3008B0E8E /* Base */, 383 | ); 384 | name = LaunchScreen.storyboard; 385 | sourceTree = ""; 386 | }; 387 | /* End PBXVariantGroup section */ 388 | 389 | /* Begin XCBuildConfiguration section */ 390 | A95CFFAE21AC36CD008B0E8E /* Debug */ = { 391 | isa = XCBuildConfiguration; 392 | buildSettings = { 393 | ALWAYS_SEARCH_USER_PATHS = NO; 394 | CLANG_ANALYZER_NONNULL = YES; 395 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 396 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 397 | CLANG_CXX_LIBRARY = "libc++"; 398 | CLANG_ENABLE_MODULES = YES; 399 | CLANG_ENABLE_OBJC_ARC = YES; 400 | CLANG_ENABLE_OBJC_WEAK = YES; 401 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 402 | CLANG_WARN_BOOL_CONVERSION = YES; 403 | CLANG_WARN_COMMA = YES; 404 | CLANG_WARN_CONSTANT_CONVERSION = YES; 405 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 406 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 407 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 408 | CLANG_WARN_EMPTY_BODY = YES; 409 | CLANG_WARN_ENUM_CONVERSION = YES; 410 | CLANG_WARN_INFINITE_RECURSION = YES; 411 | CLANG_WARN_INT_CONVERSION = YES; 412 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 413 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 414 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 415 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 416 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 417 | CLANG_WARN_STRICT_PROTOTYPES = YES; 418 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 419 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 420 | CLANG_WARN_UNREACHABLE_CODE = YES; 421 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 422 | CODE_SIGN_IDENTITY = "iPhone Developer"; 423 | COPY_PHASE_STRIP = NO; 424 | CURRENT_PROJECT_VERSION = 1; 425 | DEBUG_INFORMATION_FORMAT = dwarf; 426 | ENABLE_STRICT_OBJC_MSGSEND = YES; 427 | ENABLE_TESTABILITY = YES; 428 | GCC_C_LANGUAGE_STANDARD = gnu11; 429 | GCC_DYNAMIC_NO_PIC = NO; 430 | GCC_NO_COMMON_BLOCKS = YES; 431 | GCC_OPTIMIZATION_LEVEL = 0; 432 | GCC_PREPROCESSOR_DEFINITIONS = ( 433 | "DEBUG=1", 434 | "$(inherited)", 435 | ); 436 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 437 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 438 | GCC_WARN_UNDECLARED_SELECTOR = YES; 439 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 440 | GCC_WARN_UNUSED_FUNCTION = YES; 441 | GCC_WARN_UNUSED_VARIABLE = YES; 442 | IPHONEOS_DEPLOYMENT_TARGET = 12.1; 443 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 444 | MTL_FAST_MATH = YES; 445 | ONLY_ACTIVE_ARCH = YES; 446 | SDKROOT = iphoneos; 447 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 448 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 449 | VERSIONING_SYSTEM = "apple-generic"; 450 | VERSION_INFO_PREFIX = ""; 451 | }; 452 | name = Debug; 453 | }; 454 | A95CFFAF21AC36CD008B0E8E /* Release */ = { 455 | isa = XCBuildConfiguration; 456 | buildSettings = { 457 | ALWAYS_SEARCH_USER_PATHS = NO; 458 | CLANG_ANALYZER_NONNULL = YES; 459 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 460 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 461 | CLANG_CXX_LIBRARY = "libc++"; 462 | CLANG_ENABLE_MODULES = YES; 463 | CLANG_ENABLE_OBJC_ARC = YES; 464 | CLANG_ENABLE_OBJC_WEAK = YES; 465 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 466 | CLANG_WARN_BOOL_CONVERSION = YES; 467 | CLANG_WARN_COMMA = YES; 468 | CLANG_WARN_CONSTANT_CONVERSION = YES; 469 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 470 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 471 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 472 | CLANG_WARN_EMPTY_BODY = YES; 473 | CLANG_WARN_ENUM_CONVERSION = YES; 474 | CLANG_WARN_INFINITE_RECURSION = YES; 475 | CLANG_WARN_INT_CONVERSION = YES; 476 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 477 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 478 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 479 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 480 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 481 | CLANG_WARN_STRICT_PROTOTYPES = YES; 482 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 483 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 484 | CLANG_WARN_UNREACHABLE_CODE = YES; 485 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 486 | CODE_SIGN_IDENTITY = "iPhone Developer"; 487 | COPY_PHASE_STRIP = NO; 488 | CURRENT_PROJECT_VERSION = 1; 489 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 490 | ENABLE_NS_ASSERTIONS = NO; 491 | ENABLE_STRICT_OBJC_MSGSEND = YES; 492 | GCC_C_LANGUAGE_STANDARD = gnu11; 493 | GCC_NO_COMMON_BLOCKS = YES; 494 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 495 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 496 | GCC_WARN_UNDECLARED_SELECTOR = YES; 497 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 498 | GCC_WARN_UNUSED_FUNCTION = YES; 499 | GCC_WARN_UNUSED_VARIABLE = YES; 500 | IPHONEOS_DEPLOYMENT_TARGET = 12.1; 501 | MTL_ENABLE_DEBUG_INFO = NO; 502 | MTL_FAST_MATH = YES; 503 | SDKROOT = iphoneos; 504 | SWIFT_COMPILATION_MODE = wholemodule; 505 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 506 | VALIDATE_PRODUCT = YES; 507 | VERSIONING_SYSTEM = "apple-generic"; 508 | VERSION_INFO_PREFIX = ""; 509 | }; 510 | name = Release; 511 | }; 512 | A95CFFB121AC36CD008B0E8E /* Debug */ = { 513 | isa = XCBuildConfiguration; 514 | baseConfigurationReference = 5A05DA3074F947B644045E84 /* Pods-drawer-view.debug.xcconfig */; 515 | buildSettings = { 516 | CLANG_ENABLE_MODULES = YES; 517 | CODE_SIGN_IDENTITY = ""; 518 | CODE_SIGN_STYLE = Automatic; 519 | DEFINES_MODULE = YES; 520 | DEVELOPMENT_TEAM = 5W8256FV33; 521 | DYLIB_COMPATIBILITY_VERSION = 1; 522 | DYLIB_CURRENT_VERSION = 1; 523 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 524 | INFOPLIST_FILE = "drawer-view/Info.plist"; 525 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 526 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 527 | LD_RUNPATH_SEARCH_PATHS = ( 528 | "$(inherited)", 529 | "@executable_path/Frameworks", 530 | "@loader_path/Frameworks", 531 | ); 532 | PRODUCT_BUNDLE_IDENTIFIER = "eleev.astemir.drawer-view"; 533 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 534 | SKIP_INSTALL = YES; 535 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 536 | SWIFT_VERSION = 5.0; 537 | TARGETED_DEVICE_FAMILY = "1,2"; 538 | }; 539 | name = Debug; 540 | }; 541 | A95CFFB221AC36CD008B0E8E /* Release */ = { 542 | isa = XCBuildConfiguration; 543 | baseConfigurationReference = 29D93570AD4AD783407212BA /* Pods-drawer-view.release.xcconfig */; 544 | buildSettings = { 545 | CLANG_ENABLE_MODULES = YES; 546 | CODE_SIGN_IDENTITY = ""; 547 | CODE_SIGN_STYLE = Automatic; 548 | DEFINES_MODULE = YES; 549 | DEVELOPMENT_TEAM = 5W8256FV33; 550 | DYLIB_COMPATIBILITY_VERSION = 1; 551 | DYLIB_CURRENT_VERSION = 1; 552 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 553 | INFOPLIST_FILE = "drawer-view/Info.plist"; 554 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 555 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 556 | LD_RUNPATH_SEARCH_PATHS = ( 557 | "$(inherited)", 558 | "@executable_path/Frameworks", 559 | "@loader_path/Frameworks", 560 | ); 561 | PRODUCT_BUNDLE_IDENTIFIER = "eleev.astemir.drawer-view"; 562 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 563 | SKIP_INSTALL = YES; 564 | SWIFT_VERSION = 5.0; 565 | TARGETED_DEVICE_FAMILY = "1,2"; 566 | }; 567 | name = Release; 568 | }; 569 | A95CFFCD21AC37A3008B0E8E /* Debug */ = { 570 | isa = XCBuildConfiguration; 571 | baseConfigurationReference = 82C2C949031EF4E6C7CC31D1 /* Pods-demo.debug.xcconfig */; 572 | buildSettings = { 573 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 574 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 575 | CODE_SIGN_STYLE = Automatic; 576 | DEVELOPMENT_TEAM = 5W8256FV33; 577 | INFOPLIST_FILE = demo/Info.plist; 578 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 579 | LD_RUNPATH_SEARCH_PATHS = ( 580 | "$(inherited)", 581 | "@executable_path/Frameworks", 582 | ); 583 | PRODUCT_BUNDLE_IDENTIFIER = eleev.astemir.demo; 584 | PRODUCT_NAME = "$(TARGET_NAME)"; 585 | SWIFT_VERSION = 5.0; 586 | TARGETED_DEVICE_FAMILY = "1,2"; 587 | }; 588 | name = Debug; 589 | }; 590 | A95CFFCE21AC37A3008B0E8E /* Release */ = { 591 | isa = XCBuildConfiguration; 592 | baseConfigurationReference = E06FF2D202F4E2F1D7B8B1F9 /* Pods-demo.release.xcconfig */; 593 | buildSettings = { 594 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 595 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 596 | CODE_SIGN_STYLE = Automatic; 597 | DEVELOPMENT_TEAM = 5W8256FV33; 598 | INFOPLIST_FILE = demo/Info.plist; 599 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 600 | LD_RUNPATH_SEARCH_PATHS = ( 601 | "$(inherited)", 602 | "@executable_path/Frameworks", 603 | ); 604 | PRODUCT_BUNDLE_IDENTIFIER = eleev.astemir.demo; 605 | PRODUCT_NAME = "$(TARGET_NAME)"; 606 | SWIFT_VERSION = 5.0; 607 | TARGETED_DEVICE_FAMILY = "1,2"; 608 | }; 609 | name = Release; 610 | }; 611 | /* End XCBuildConfiguration section */ 612 | 613 | /* Begin XCConfigurationList section */ 614 | A95CFFA221AC36CD008B0E8E /* Build configuration list for PBXProject "drawer-view" */ = { 615 | isa = XCConfigurationList; 616 | buildConfigurations = ( 617 | A95CFFAE21AC36CD008B0E8E /* Debug */, 618 | A95CFFAF21AC36CD008B0E8E /* Release */, 619 | ); 620 | defaultConfigurationIsVisible = 0; 621 | defaultConfigurationName = Release; 622 | }; 623 | A95CFFB021AC36CD008B0E8E /* Build configuration list for PBXNativeTarget "drawer-view" */ = { 624 | isa = XCConfigurationList; 625 | buildConfigurations = ( 626 | A95CFFB121AC36CD008B0E8E /* Debug */, 627 | A95CFFB221AC36CD008B0E8E /* Release */, 628 | ); 629 | defaultConfigurationIsVisible = 0; 630 | defaultConfigurationName = Release; 631 | }; 632 | A95CFFCC21AC37A3008B0E8E /* Build configuration list for PBXNativeTarget "demo" */ = { 633 | isa = XCConfigurationList; 634 | buildConfigurations = ( 635 | A95CFFCD21AC37A3008B0E8E /* Debug */, 636 | A95CFFCE21AC37A3008B0E8E /* Release */, 637 | ); 638 | defaultConfigurationIsVisible = 0; 639 | defaultConfigurationName = Release; 640 | }; 641 | /* End XCConfigurationList section */ 642 | }; 643 | rootObject = A95CFF9F21AC36CD008B0E8E /* Project object */; 644 | } 645 | -------------------------------------------------------------------------------- /drawer-view.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /drawer-view.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /drawer-view.xcodeproj/xcuserdata/astemireleev.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | demo.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 3 11 | 12 | drawer-view.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 2 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /drawer-view.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /drawer-view.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /drawer-view/1.0.1/drawer-view.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint drawer-view.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "drawer-view" 19 | s.version = "1.0.1" 20 | s.summary = "📤 Drawer View is a custom UI component replication of Apple's Apple Music player and Shortcuts components view" 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | s.description = <<-DESC 28 | 📤 `Drawer View` is a custom UI component replication of Apple's `Apple Music` player and `Shortcuts` components view 29 | DESC 30 | 31 | s.homepage = "https://github.com/jVirus/drawer-view" 32 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 33 | 34 | 35 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 36 | # 37 | # Licensing your code is important. See http://choosealicense.com for more info. 38 | # CocoaPods will detect a license file if there is a named LICENSE* 39 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 40 | # 41 | 42 | # s.license = "MIT (example)" 43 | s.license = { :type => "MIT", :file => "LICENSE" } 44 | 45 | 46 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 47 | # 48 | # Specify the authors of the library, with email addresses. Email addresses 49 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 50 | # accepts just a name if you'd rather not provide an email address. 51 | # 52 | # Specify a social_media_url where others can refer to, for example a twitter 53 | # profile URL. 54 | # 55 | 56 | # s.author = { "Astemir Eleev" => "astemireleev@domen.com" } 57 | s.author = { "Astemir Eleev" => "astemireleev@gmail.com" } 58 | # Or just: s.author = "Astemir Eleev" 59 | # s.authors = { "Astemir Eleev" => "astemireleev@domen.com" } 60 | # s.social_media_url = "http://twitter.com/Astemir Eleev" 61 | 62 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 63 | # 64 | # If this Pod runs only on iOS or OS X, then specify the platform and 65 | # the deployment target. You can optionally include the target after the platform. 66 | # 67 | 68 | s.platform = :ios 69 | # s.platform = :ios, "5.0" 70 | 71 | # When using multiple platforms 72 | s.ios.deployment_target = "11.0" 73 | # s.osx.deployment_target = "10.12" 74 | # s.watchos.deployment_target = "4.0" 75 | # s.tvos.deployment_target = "11.0" 76 | 77 | 78 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 79 | # 80 | # Specify the location from where the source should be retrieved. 81 | # Supports git, hg, bzr, svn and HTTP. 82 | # 83 | 84 | # "#{s.version}" 85 | s.source = { :git => "https://github.com/jVirus/drawer-view.git", :tag => s.version.to_s } 86 | 87 | 88 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 89 | # 90 | # CocoaPods is smart about how it includes source code. For source files 91 | # giving a folder will include any swift, h, m, mm, c & cpp files. 92 | # For header files it will include any header in the folder. 93 | # Not including the public_header_files will make all headers public. 94 | # 95 | 96 | s.source_files = "drawer-view/**/*.swift" 97 | # s.exclude_files = "Classes/Exclude" 98 | 99 | # s.public_header_files = "drawer-view/**/*.h" 100 | 101 | 102 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 103 | # 104 | # A list of resources included with the Pod. These are copied into the 105 | # target bundle with a build phase script. Anything else will be cleaned. 106 | # You can preserve files from being cleaned, please don't preserve 107 | # non-essential files like tests, examples and documentation. 108 | # 109 | 110 | # s.resource = "icon.png" 111 | # s.resources = "Resources/*.png" 112 | 113 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 114 | 115 | 116 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 117 | # 118 | # Link your library with frameworks, or libraries. Libraries do not include 119 | # the lib prefix of their name. 120 | # 121 | 122 | # s.framework = "SomeFramework" 123 | # s.frameworks = "SomeFramework", "AnotherFramework" 124 | 125 | # s.library = "iconv" 126 | # s.libraries = "iconv", "xml2" 127 | 128 | 129 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 130 | # 131 | # If your library depends on compiler flags you can set them in the xcconfig hash 132 | # where they will only apply to your library. If you depend on other Podspecs 133 | # you can include multiple dependencies to ensure it works. 134 | 135 | # s.requires_arc = true 136 | 137 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 138 | # s.dependency "JSONKit", "~> 1.4" 139 | 140 | s.requires_arc = true 141 | s.pod_target_xcconfig = { 'SWIFT_VERSION' => '4.2' } 142 | s.swift_version = "4.2" 143 | 144 | end 145 | -------------------------------------------------------------------------------- /drawer-view/DefaultTitleLabelAnimator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DefaultTitleLabelAnimator.swift 3 | // drawer-view 4 | // 5 | // Created by Astemir Eleev on 28/11/2018. 6 | // Copyright © 2018 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public struct DefaultTitleLabelAnimator: TitleLabelAnimator { 12 | 13 | // MARK: - Properties 14 | 15 | public let openedTitleLabel: UILabel 16 | public let closedTitleLabel: UILabel 17 | 18 | // MARK: - Initializers 19 | 20 | public init(text: String, 21 | fontSize: (opened: CGFloat, closed: CGFloat) = (20, 28), 22 | color: (opened: UIColor, closed: UIColor) = (.gray, .black)) { 23 | 24 | openedTitleLabel = UILabel() 25 | openedTitleLabel.font = UIFont.systemFont(ofSize: fontSize.opened, weight: .medium) 26 | openedTitleLabel.textColor = color.opened 27 | openedTitleLabel.text = text 28 | openedTitleLabel.textAlignment = .center 29 | openedTitleLabel.alpha = 0.0 30 | 31 | closedTitleLabel = UILabel() 32 | closedTitleLabel.font = UIFont.systemFont(ofSize: fontSize.closed, weight: .heavy) 33 | closedTitleLabel.textColor = color.closed 34 | closedTitleLabel.text = text 35 | closedTitleLabel.textAlignment = .center 36 | closedTitleLabel.alpha = 1.0 37 | } 38 | 39 | // MARK: - Public methods 40 | 41 | public func animate(for state: DrawerView.State) { 42 | switch state { 43 | case .open: 44 | openedTitleLabel.transform = .identity 45 | closedTitleLabel.transform = CGAffineTransform(scaleX: 0.65, y: 0.65).concatenating(CGAffineTransform(translationX: 0, y: -8)) 46 | 47 | openedTitleLabel.alpha = 1.0 48 | closedTitleLabel.alpha = 0.0 49 | case .closed: 50 | openedTitleLabel.transform = CGAffineTransform(scaleX: 1.6, y: 1.6).concatenating(CGAffineTransform(translationX: 0, y: 8)) 51 | closedTitleLabel.transform = .identity 52 | 53 | openedTitleLabel.alpha = 0.0 54 | closedTitleLabel.alpha = 1.0 55 | } 56 | } 57 | 58 | public func prepareLayoutConstraints() { 59 | guard let openedLabelSuperview = openedTitleLabel.superview, let closedLabelSuperview = closedTitleLabel.superview else { 60 | return 61 | } 62 | 63 | openedTitleLabel.translatesAutoresizingMaskIntoConstraints = false 64 | NSLayoutConstraint.activate([ 65 | openedTitleLabel.centerXAnchor.constraint(equalTo: openedLabelSuperview.centerXAnchor, constant: 0.0), 66 | openedTitleLabel.topAnchor.constraint(equalTo: openedLabelSuperview.topAnchor, constant: 36.0) 67 | ]) 68 | 69 | closedTitleLabel.translatesAutoresizingMaskIntoConstraints = false 70 | NSLayoutConstraint.activate([ 71 | closedTitleLabel.centerXAnchor.constraint(equalTo: closedLabelSuperview.centerXAnchor, constant: 0.0), 72 | closedTitleLabel.topAnchor.constraint(equalTo: closedLabelSuperview.topAnchor, constant: 36.0) 73 | ]) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /drawer-view/DrawerView.BlurStyle+Convert.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DrawerView.BlurStyle+Convert.swift 3 | // drawer-view 4 | // 5 | // Created by Astemir Eleev on 28/11/2018. 6 | // Copyright © 2018 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | // MARK: - DrawerView.BlurStyle extension 12 | 13 | extension DrawerView.BlurStyle { 14 | func convert() -> UIBlurEffect.Style? { 15 | switch self { 16 | case .none: 17 | return nil 18 | case .light: 19 | return .light 20 | case .extraLight: 21 | return .extraLight 22 | case .dark: 23 | return .dark 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /drawer-view/DrawerView.State+Opposite.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DrawerView.State+Opposite.swift 3 | // drawer-view 4 | // 5 | // Created by Astemir Eleev on 28/11/2018. 6 | // Copyright © 2018 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | // MARK: - DrawerView.State extension 12 | 13 | extension DrawerView.State { 14 | var opposite: DrawerView.State { 15 | switch self { 16 | case .open: return .closed 17 | case .closed: return .open 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /drawer-view/DrawerView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DrawerView.swift 3 | // drawer-view 4 | // 5 | // Created by Astemir Eleev on 26/11/2018. 6 | // Copyright © 2018 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | // DrawerView UI Component. Intended to be a part of an another UIView and present additional view when needed. The view is not @IBDesignable since there is nothing to present (custom) in the interface builder. However, some properties are @IBInspectable, so you are able to adjust them at design time (in case if you use interface builder). 12 | public class DrawerView: UIView { 13 | 14 | // MARK: - Enum types 15 | 16 | public enum BlurStyle { 17 | case none 18 | case extraLight 19 | case light 20 | case dark 21 | } 22 | 23 | public enum State { 24 | case closed 25 | case open 26 | } 27 | 28 | // MARK: - Public properties 29 | 30 | public let topLayoutGuidePadding: CGFloat 31 | public let closedHeight: CGFloat 32 | public private(set) var visibleHeight: CGFloat 33 | public let blurStyle: BlurStyle 34 | 35 | public private(set) var currentState: State = .closed { 36 | didSet { 37 | if givesHapticFeedback { 38 | hapticFeedback.impactOccurred() 39 | } 40 | onStateChangeClosure(currentState) 41 | } 42 | } 43 | 44 | /// The component will change its state when device is rotated to .closed if the component was in .open state 45 | @IBInspectable public var closeOnRotation = false 46 | /// The component will change its state to .closed when child views are interacted 47 | @IBInspectable public var closeOnChildViewTaps = false 48 | /// The component will change its state to .closed when the drawer is tapped 49 | @IBInspectable public var closeOnDrawerTaps = true 50 | /// The component will change its state to .closed when a tap occurs out of itself 51 | @IBInspectable public var closeOnBlurTapped = false 52 | /// The component will give the user haptic feedback at after state change 53 | @IBInspectable public var givesHapticFeedback = true 54 | @IBInspectable public var animationDuration: TimeInterval = 1.5 55 | @IBInspectable public var animationDampingRatio: CGFloat = 1.0 56 | @IBInspectable public var cornerRadius: CGFloat = 40.0 57 | @IBInspectable public var shadowOpacity: Float = 0.15 { 58 | didSet { 59 | layer.shadowOpacity = shadowOpacity 60 | } 61 | } 62 | @IBInspectable public var shadowRadius: CGFloat = 8 { 63 | didSet { 64 | layer.shadowRadius = shadowRadius 65 | } 66 | } 67 | 68 | /// Use this close if you want to animate any other UIKit related component alongside with this component 69 | public var animationClosure: (_ state: State)->() = { _ in } 70 | /// Use this cloure if you want to get animation completion callbacks 71 | public var completionClosure: (_ state: State)->() = { _ in } 72 | /// Use this clossure if you want to get callbacks when State changes 73 | public var onStateChangeClosure: (_ state: State)->() = { _ in } 74 | 75 | public var titleLabelAnimator: TitleLabelAnimator? { 76 | didSet { 77 | guard let titleLabelAnimator = self.titleLabelAnimator else { 78 | return 79 | } 80 | self.addSubview(titleLabelAnimator.openedTitleLabel) 81 | self.addSubview(titleLabelAnimator.closedTitleLabel) 82 | titleLabelAnimator.prepareLayoutConstraints() 83 | } 84 | } 85 | 86 | // MARK: - Private properties 87 | 88 | private var bottomConstraint = NSLayoutConstraint() 89 | private var customHeightAnchor = NSLayoutConstraint() 90 | 91 | private var sholdRecalculateConstraints = false 92 | private let shouldBlurBackground: Bool 93 | private lazy var hapticFeedback: UIImpactFeedbackGenerator = { 94 | return UIImpactFeedbackGenerator(style: UIImpactFeedbackGenerator.FeedbackStyle.medium) 95 | }() 96 | 97 | /// Holds all the running animators 98 | private var runningAnimators = [UIViewPropertyAnimator]() 99 | 100 | /// Holds propgresses of each animator 101 | private var animationProgress = [CGFloat]() 102 | 103 | private lazy var blurEffectView: UIVisualEffectView? = { 104 | guard let style = blurStyle.convert() else { 105 | return nil 106 | } 107 | let blurEffect = UIBlurEffect(style: style) 108 | let effectView = UIVisualEffectView(effect: blurEffect) 109 | effectView.addGestureRecognizer(outTapGesture) 110 | return effectView 111 | }() 112 | 113 | private lazy var outTapGesture: UITapGestureRecognizer = { 114 | let recognizer = UITapGestureRecognizer() 115 | recognizer.addTarget(self, action: #selector(drawerViewGestureTappedOut(recognizer:))) 116 | return recognizer 117 | }() 118 | 119 | private lazy var tapGesture: UITapGestureRecognizer = { 120 | let recognizer = UITapGestureRecognizer() 121 | recognizer.addTarget(self, action: #selector(drawerViewGestureTapped(recognizer:))) 122 | recognizer.delegate = self 123 | return recognizer 124 | }() 125 | 126 | private lazy var panGesture: ImmediatePanGestureRecognizer = { 127 | let recognizer = ImmediatePanGestureRecognizer() 128 | recognizer.addTarget(self, action: #selector(drawerViewGesturePanned(recognizer:))) 129 | recognizer.delegate = self 130 | return recognizer 131 | }() 132 | 133 | // MARK: - Line Arrow Shape Layer 134 | 135 | private var lineArrowShapeLayer: LineArrowShapeLayer? 136 | 137 | 138 | // MARK: - Initializers 139 | 140 | /// A designated initialier for DrawerView. Use initializer to create a new instnace of a DrawerView. Note that the view will add itself to the super view and must not do that manually. A typical use-case of this class it to instantiate a variable or property and optionally use closures to animate UIKit related contnet alongside with the DrawerView. 141 | public init(topLayoutGuidePadding: CGFloat = 100, 142 | closedHeight: CGFloat = 80, 143 | blurStyle: BlurStyle = .extraLight, 144 | lineArrow: (height: CGFloat, width: CGFloat, color: UIColor)? = (8, 100, .lightGray), 145 | superView: UIView) { 146 | 147 | self.topLayoutGuidePadding = topLayoutGuidePadding 148 | self.closedHeight = closedHeight 149 | self.shouldBlurBackground = blurStyle != .none 150 | self.blurStyle = blurStyle 151 | self.visibleHeight = (superView.bounds.height - topLayoutGuidePadding) - closedHeight 152 | 153 | super.init(frame: .zero) 154 | 155 | superView.addSubview(self) 156 | setupConstraints() 157 | 158 | if let lineArrow = lineArrow { 159 | lineArrowShapeLayer = LineArrowShapeLayer(height: lineArrow.height, 160 | width: lineArrow.width, 161 | color: lineArrow.color) 162 | // We know for sure that LineArrowShapeLayer is not nil since it was just instantiated 163 | layer.addSublayer(lineArrowShapeLayer!) 164 | } 165 | 166 | 167 | // Inserts the blur effect view below the current view and adds autolayout constraints that fill in the superview 168 | if shouldBlurBackground, let blurEffectView = blurEffectView { 169 | superView.insertSubview(blurEffectView, belowSubview: self) 170 | blurEffectView.alpha = currentState == .open ? 1.0 : 0.0 171 | 172 | blurEffectView.translatesAutoresizingMaskIntoConstraints = false 173 | 174 | NSLayoutConstraint.activate([ 175 | blurEffectView.leadingAnchor.constraint(equalTo: superView.leadingAnchor), 176 | blurEffectView.trailingAnchor.constraint(equalTo: superView.trailingAnchor), 177 | blurEffectView.topAnchor.constraint(equalTo: superView.topAnchor), 178 | blurEffectView.bottomAnchor.constraint(equalTo: superView.bottomAnchor) 179 | ]) 180 | } 181 | 182 | backgroundColor = .white 183 | layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner] 184 | layer.shadowColor = UIColor.black.cgColor 185 | layer.shadowOpacity = shadowOpacity 186 | layer.shadowRadius = shadowRadius 187 | 188 | addGestureRecognizer(tapGesture) 189 | addGestureRecognizer(panGesture) 190 | 191 | UIDevice.current.beginGeneratingDeviceOrientationNotifications() 192 | NotificationCenter.default.addObserver(self, selector: #selector(orientationDidChange(notification:)), name: UIDevice.orientationDidChangeNotification, object: nil) 193 | } 194 | 195 | required init?(coder aDecoder: NSCoder) { 196 | fatalError("init(coder:) has not been implemented") 197 | } 198 | 199 | // 200 | 201 | /// In some cases (seems to depend on the view (controller) hierarchy) on has to call this function BEFORE the first animation to make it look right. 202 | /// 203 | /// Otherwise it may look like the component is expanding from the origin of its superview instead of appearing from the bottom. 204 | public func setInitial(frame: CGRect) { 205 | self.blurEffectView?.frame = frame 206 | 207 | var initialFrame = frame 208 | initialFrame.origin.y = initialFrame.size.height 209 | initialFrame.size.height = 0 210 | 211 | self.frame = initialFrame 212 | } 213 | 214 | deinit { 215 | removeGestureRecognizer(tapGesture) 216 | removeGestureRecognizer(panGesture) 217 | NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil) 218 | 219 | subviews.forEach { $0.removeFromSuperview() } 220 | removeFromSuperview() 221 | } 222 | 223 | // MARK: - Overrides 224 | 225 | public override func layoutSubviews() { 226 | super.layoutSubviews() 227 | resolveLayoutChanges() 228 | } 229 | 230 | // MARK: - Methods 231 | 232 | public func change(state: DrawerView.State, shouldAnimate: Bool = true) { 233 | let animationDuration = shouldAnimate ? self.animationDuration : 0.0 234 | animateTransitionIfNeeded(to: state, duration: animationDuration) 235 | } 236 | 237 | @objc private func orientationDidChange(notification: Notification) { 238 | if closeOnRotation { 239 | animateTransitionIfNeeded(to: .closed, duration: animationDuration) 240 | } else if currentState == .open { 241 | animateTransitionIfNeeded(to: .open, duration: animationDuration) 242 | } 243 | sholdRecalculateConstraints = true 244 | } 245 | 246 | private func animateTransitionIfNeeded(to state: State, duration: TimeInterval) { 247 | guard runningAnimators.isEmpty else { return } 248 | 249 | let transitionAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: animationDampingRatio, animations: { 250 | switch state { 251 | case .open: 252 | self.bottomConstraint.constant = 0 253 | self.layer.cornerRadius = self.cornerRadius 254 | 255 | if self.shouldBlurBackground { self.blurEffectView?.alpha = 1.0 } 256 | case .closed: 257 | self.bottomConstraint.constant = self.visibleHeight 258 | self.layer.cornerRadius = 0.0 259 | if self.shouldBlurBackground { self.blurEffectView?.alpha = 0.0 } 260 | } 261 | 262 | self.titleLabelAnimator?.animate(for: state) 263 | self.lineArrowShapeLayer?.animate(for: state) 264 | self.animationClosure(state) 265 | 266 | self.superview?.layoutIfNeeded() 267 | }) 268 | 269 | transitionAnimator.addCompletion { position in 270 | switch position { 271 | case .start: 272 | self.currentState = state.opposite 273 | case .end: 274 | self.currentState = state 275 | case .current: () 276 | @unknown default: 277 | fatalError("The unknown case is not handled. Please, review the transition animator and make the appropriate changes.") 278 | } 279 | 280 | switch self.currentState { 281 | case .open: 282 | self.bottomConstraint.constant = 0 283 | case .closed: 284 | self.bottomConstraint.constant = self.visibleHeight 285 | } 286 | 287 | self.lineArrowShapeLayer?.completeAnimation(for: self.currentState) 288 | self.completionClosure(self.currentState) 289 | 290 | self.runningAnimators.removeAll() 291 | } 292 | 293 | transitionAnimator.startAnimation() 294 | runningAnimators += [transitionAnimator] 295 | } 296 | 297 | @objc private func drawerViewGestureTappedOut(recognizer: UITapGestureRecognizer) { 298 | guard closeOnBlurTapped else { return } 299 | animateTransitionIfNeeded(to: .closed, duration: animationDuration) 300 | } 301 | 302 | @objc private func drawerViewGestureTapped(recognizer: UITapGestureRecognizer) { 303 | guard closeOnDrawerTaps else { return } 304 | let state = currentState.opposite 305 | animateTransitionIfNeeded(to: state, duration: animationDuration) 306 | } 307 | 308 | @objc private func drawerViewGesturePanned(recognizer: UIPanGestureRecognizer) { 309 | 310 | // Discard all gestures that are propagated from the child views 311 | let tapLocation = recognizer.location(in: self) 312 | let containsLocationPoint = self.layer.presentation()?.frame.contains(tapLocation) 313 | 314 | if let containsLocationPoint = containsLocationPoint, containsLocationPoint, !closeOnChildViewTaps { 315 | return 316 | } 317 | 318 | switch recognizer.state { 319 | case .began: 320 | animateTransitionIfNeeded(to: currentState.opposite, duration: animationDuration) 321 | runningAnimators.forEach { $0.pauseAnimation() } 322 | animationProgress = runningAnimators.map { $0.fractionComplete } 323 | 324 | case .changed: 325 | let translation = recognizer.translation(in: self) 326 | var fraction = -translation.y / visibleHeight 327 | 328 | if currentState == .open { fraction *= -1 } 329 | if runningAnimators[0].isReversed { fraction *= -1 } 330 | 331 | for (index, animator) in runningAnimators.enumerated() { 332 | animator.fractionComplete = fraction + animationProgress[index] 333 | } 334 | case .ended: 335 | let yVelocity = recognizer.velocity(in: self).y 336 | let shouldClose = yVelocity > 0 337 | 338 | @inline(__always) func continueRunningAnimators() { 339 | runningAnimators.forEach { $0.continueAnimation(withTimingParameters: nil, durationFactor: 0) } 340 | } 341 | 342 | // if there is no motion, continue all animations and exit early 343 | if yVelocity == 0 { 344 | continueRunningAnimators() 345 | break 346 | } 347 | 348 | @inline(__always) func reverseRunningAnimators() { 349 | runningAnimators.forEach { $0.isReversed = !$0.isReversed } 350 | } 351 | 352 | // reverse the animations based on their current state and pan motion 353 | switch currentState { 354 | case .open: 355 | if !shouldClose, !runningAnimators[0].isReversed { 356 | reverseRunningAnimators() 357 | } 358 | if shouldClose, runningAnimators[0].isReversed { 359 | reverseRunningAnimators() 360 | } 361 | case .closed: 362 | if shouldClose, !runningAnimators[0].isReversed { 363 | reverseRunningAnimators() 364 | } 365 | if !shouldClose, runningAnimators[0].isReversed { 366 | reverseRunningAnimators() 367 | } 368 | } 369 | continueRunningAnimators() 370 | default: () 371 | } 372 | } 373 | 374 | 375 | } 376 | 377 | private extension DrawerView { 378 | 379 | func setupConstraints() { 380 | guard let superview = self.superview else { return } 381 | 382 | translatesAutoresizingMaskIntoConstraints = false 383 | leadingAnchor.constraint(equalTo: superview.leadingAnchor).isActive = true 384 | trailingAnchor.constraint(equalTo: superview.trailingAnchor).isActive = true 385 | 386 | bottomConstraint = bottomAnchor.constraint(equalTo: superview.bottomAnchor, constant: currentState == .closed ? visibleHeight : 0.0) 387 | bottomConstraint.isActive = true 388 | 389 | customHeightAnchor = heightAnchor.constraint(equalToConstant: topLayoutGuidePadding) 390 | customHeightAnchor.isActive = true 391 | } 392 | 393 | func resolveLayoutChanges() { 394 | guard sholdRecalculateConstraints, let superview = self.superview else { return } 395 | let newHeight = superview.bounds.height - topLayoutGuidePadding 396 | 397 | visibleHeight = newHeight - closedHeight 398 | bottomConstraint.constant = visibleHeight 399 | customHeightAnchor.constant = newHeight 400 | superview.layoutIfNeeded() 401 | 402 | if lineArrowShapeLayer != nil { 403 | // Update the bounds of the list arrow shape layer view 404 | lineArrowShapeLayer?.calculateBounds(from: bounds) 405 | lineArrowShapeLayer?.update() 406 | } 407 | 408 | sholdRecalculateConstraints = false 409 | } 410 | } 411 | 412 | extension DrawerView : UIGestureRecognizerDelegate { 413 | public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { 414 | for subview in subviews { 415 | guard let subview = subview as? DrawerViewTouchHandling else { continue } 416 | if subview.drawerViewIntercepts(touch: touch) { return false } 417 | } 418 | return true 419 | } 420 | } 421 | -------------------------------------------------------------------------------- /drawer-view/DrawerViewTouchHandling.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DrawerViewTouchHandling.swift 3 | // drawer-view 4 | // 5 | // Created by Astemir Eleev on 06/04/2019. 6 | // Copyright © 2019 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// The protocol allows to resolve interceptions of touches for the subiews of `DrawerView`. 12 | @objc public protocol DrawerViewTouchHandling { 13 | @objc func drawerViewIntercepts(touch: UITouch) -> Bool 14 | } 15 | -------------------------------------------------------------------------------- /drawer-view/ImmediatePanGestureRecognizer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InstantPanGestureRecognizer.swift 3 | // drawer-view 4 | // 5 | // Created by Astemir Eleev on 26/11/2018. 6 | // Copyright © 2018 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ImmediatePanGestureRecognizer: UIPanGestureRecognizer { 12 | 13 | // MARK: - Overrides 14 | 15 | override func touchesBegan(_ touches: Set, with event: UIEvent) { 16 | if self.state == UIGestureRecognizer.State.began { return } 17 | super.touchesBegan(touches, with: event) 18 | self.state = UIGestureRecognizer.State.began 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /drawer-view/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.4 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /drawer-view/LineArrowShapeLayer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LineArrowShapeLayer.swift 3 | // drawer-view 4 | // 5 | // Created by Astemir Eleev on 28/11/2018. 6 | // Copyright © 2018 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class LineArrowShapeLayer: CAShapeLayer { 12 | 13 | // MARK: - Properties 14 | 15 | private var targetBounds: CGRect = .zero 16 | private var width: CGFloat 17 | private var height: CGFloat 18 | private var bezierPath = UIBezierPath() 19 | private var lastState: DrawerView.State = .closed 20 | 21 | // MARK: - Initialiezers 22 | 23 | init(height: CGFloat, width: CGFloat, color: UIColor) { 24 | self.height = height 25 | self.width = width 26 | super.init() 27 | 28 | fillColor = UIColor.clear.cgColor 29 | strokeColor = color.cgColor 30 | lineWidth = height 31 | lineCap = .round 32 | } 33 | 34 | required init?(coder aDecoder: NSCoder) { 35 | fatalError("init(coder:) has not been implemented") 36 | } 37 | 38 | func update() { 39 | animateBezierPath(to: lastState) 40 | } 41 | 42 | func animate(for state: DrawerView.State) { 43 | animateBezierPath(to: state) 44 | } 45 | 46 | func completeAnimation(for state: DrawerView.State) { 47 | if lastState == state { return } 48 | animateBezierPath(to: state) 49 | } 50 | 51 | func calculateBounds(from bounds: CGRect) { 52 | targetBounds = CGRect(x: (bounds.width / 2) - (width / 2), y: bounds.minY + height * 2, width: width, height: height) 53 | } 54 | 55 | private func animateBezierPath(to state: DrawerView.State) { 56 | lastState = state 57 | 58 | let controlPoint = calculateControlPoint() 59 | let endPoint = calculateEndPoint() 60 | 61 | bezierPath.removeAllPoints() 62 | bezierPath.move(to: calculateStartPoint()) 63 | 64 | switch state { 65 | case .open: 66 | bezierPath.addQuadCurve(to: endPoint, controlPoint: calculateOpened(controlPoint: controlPoint)) 67 | case .closed: 68 | bezierPath.addQuadCurve(to: endPoint, controlPoint: controlPoint) 69 | } 70 | path = bezierPath.cgPath 71 | } 72 | 73 | private func calculateStartPoint() -> CGPoint { 74 | return CGPoint(x: targetBounds.minX, y: targetBounds.midY) 75 | } 76 | 77 | private func calculateEndPoint() -> CGPoint { 78 | return CGPoint(x: targetBounds.maxX, y: targetBounds.midY) 79 | } 80 | 81 | private func calculateControlPoint() -> CGPoint { 82 | return CGPoint(x: targetBounds.midX, y: targetBounds.midY) 83 | } 84 | 85 | private func calculateOpened(controlPoint: CGPoint) -> CGPoint { 86 | return CGPoint(x: controlPoint.x, y: controlPoint.y * 1.5) 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /drawer-view/TitleLabelAnimator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TitleLabelAnimator.swift 3 | // drawer-view 4 | // 5 | // Created by Astemir Eleev on 28/11/2018. 6 | // Copyright © 2018 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol TitleLabelAnimator { 12 | 13 | var openedTitleLabel: UILabel { get } 14 | var closedTitleLabel: UILabel { get } 15 | 16 | init(text: String, 17 | fontSize: (opened: CGFloat, closed: CGFloat), 18 | color: (opened: UIColor, closed: UIColor)) 19 | 20 | func animate(for state: DrawerView.State) 21 | func prepareLayoutConstraints() 22 | } 23 | -------------------------------------------------------------------------------- /drawer-view/drawer_view.h: -------------------------------------------------------------------------------- 1 | // 2 | // drawer_view.h 3 | // drawer-view 4 | // 5 | // Created by Astemir Eleev on 26/11/2018. 6 | // Copyright © 2018 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for drawer_view. 12 | FOUNDATION_EXPORT double drawer_viewVersionNumber; 13 | 14 | //! Project version string for drawer_view. 15 | FOUNDATION_EXPORT const unsigned char drawer_viewVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /logo-drawer_view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/drawer-view/27e74972e3d1603a95bda8af0ae994910b9712e2/logo-drawer_view.png --------------------------------------------------------------------------------