├── .gitignore ├── .gitignore.txt ├── .swift-version ├── BusyNavigationBar.podspec ├── BusyNavigationBar ├── BusyNavigationBar.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── BusyNavigationBar.xccheckout │ │ └── xcuserdata │ │ │ └── gunay.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── BusyNavigationBar.xcscheme │ └── xcuserdata │ │ └── gunay.xcuserdatad │ │ └── xcschemes │ │ ├── Example.xcscheme │ │ └── xcschememanagement.plist ├── BusyNavigationBar │ ├── AnimationLayerCreator.swift │ ├── BusyNavigationBar.h │ ├── BusyNavigationBarOptions.swift │ ├── Info.plist │ └── UINavigationBar+Animation.swift ├── BusyNavigationBarTests │ ├── BusyNavigationBarTests.swift │ └── Info.plist └── Example │ ├── AppDelegate.swift │ ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard │ ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── swift-bird.imageset │ │ ├── Contents.json │ │ └── swift-bird.png │ ├── Info.plist │ └── ViewController.swift ├── LICENSE.txt ├── README.md └── Screenshots ├── blue_stripe2.gif ├── gray_bar.gif ├── gray_bird.gif ├── gray_stripe.gif └── green_bar.gif /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # Xcode 4 | # 5 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 6 | 7 | ## Build generated 8 | build/ 9 | DerivedData 10 | 11 | ## Various settings 12 | *.pbxuser 13 | !default.pbxuser 14 | *.mode1v3 15 | !default.mode1v3 16 | *.mode2v3 17 | !default.mode2v3 18 | *.perspectivev3 19 | !default.perspectivev3 20 | xcuserdata 21 | 22 | ## Other 23 | *.xccheckout 24 | *.moved-aside 25 | *.xcuserstate 26 | *.xcscmblueprint 27 | 28 | ## Obj-C/Swift specific 29 | *.hmap 30 | *.ipa 31 | 32 | # CocoaPods 33 | # 34 | # We recommend against adding the Pods directory to your .gitignore. However 35 | # you should judge for yourself, the pros and cons are mentioned at: 36 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 37 | # 38 | # Pods/ 39 | 40 | # Carthage 41 | # 42 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 43 | # Carthage/Checkouts 44 | 45 | Carthage/Build 46 | 47 | # fastlane 48 | # 49 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 50 | # screenshots whenever they are needed. 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | -------------------------------------------------------------------------------- /.gitignore.txt: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | # Pods/ 27 | 28 | # Carthage 29 | # 30 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 31 | # Carthage/Checkouts 32 | 33 | Carthage/Build 34 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 3.0 2 | -------------------------------------------------------------------------------- /BusyNavigationBar.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "BusyNavigationBar" 3 | s.version = "2.0.0" 4 | s.summary = "A UINavigationBar extension to show loading effects as in Periscope app" 5 | 6 | s.description = <<-DESC 7 | A UINavigationBar extension to show loading effects as in Periscope app. 8 | This extension can insert stripes, bars, or your custom layer above navigation bar's background. 9 | DESC 10 | 11 | s.homepage = "https://github.com/gmertk/BusyNavigationBar" 12 | # s.screenshots = "https://dl.dropboxusercontent.com/u/4397140/pod-screenshots/busynavigationbar/blue_stripe.gif", "https://dl.dropboxusercontent.com/u/4397140/pod-screenshots/busynavigationbar/gray_bird.gif" 13 | 14 | s.license = "MIT" 15 | 16 | s.author = { "Gunay Mert Karadogan" => "mertkaradogan@gmail.com" } 17 | s.social_media_url = "http://twitter.com/gunaymertk" 18 | 19 | s.platform = :ios, "8.0" 20 | 21 | s.source = { :git => "https://github.com/gmertk/BusyNavigationBar.git", :tag => s.version.to_s } 22 | 23 | s.source_files = "BusyNavigationBar/BusyNavigationBar/*.swift" 24 | 25 | end 26 | -------------------------------------------------------------------------------- /BusyNavigationBar/BusyNavigationBar.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 313D93A21B697D0A00106E78 /* BusyNavigationBar.h in Headers */ = {isa = PBXBuildFile; fileRef = 313D93A11B697D0A00106E78 /* BusyNavigationBar.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 313D93A81B697D0A00106E78 /* BusyNavigationBar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 313D939C1B697D0A00106E78 /* BusyNavigationBar.framework */; }; 12 | 313D93AF1B697D0A00106E78 /* BusyNavigationBarTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 313D93AE1B697D0A00106E78 /* BusyNavigationBarTests.swift */; }; 13 | 313D93BB1B697D2D00106E78 /* AnimationLayerCreator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 313D93B81B697D2D00106E78 /* AnimationLayerCreator.swift */; }; 14 | 313D93BC1B697D2D00106E78 /* BusyNavigationBarOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 313D93B91B697D2D00106E78 /* BusyNavigationBarOptions.swift */; }; 15 | 313D93BD1B697D2D00106E78 /* UINavigationBar+Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 313D93BA1B697D2D00106E78 /* UINavigationBar+Animation.swift */; }; 16 | 313D93C71B697D6B00106E78 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 313D93C61B697D6B00106E78 /* AppDelegate.swift */; }; 17 | 313D93C91B697D6B00106E78 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 313D93C81B697D6B00106E78 /* ViewController.swift */; }; 18 | 313D93CC1B697D6B00106E78 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 313D93CA1B697D6B00106E78 /* Main.storyboard */; }; 19 | 313D93CE1B697D6B00106E78 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 313D93CD1B697D6B00106E78 /* Images.xcassets */; }; 20 | 313D93D11B697D6B00106E78 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 313D93CF1B697D6B00106E78 /* LaunchScreen.xib */; }; 21 | 31DE6CBA1B6B8DC100C7CD5B /* AnimationLayerCreator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 313D93B81B697D2D00106E78 /* AnimationLayerCreator.swift */; }; 22 | 31DE6CBB1B6B8DC100C7CD5B /* BusyNavigationBarOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 313D93B91B697D2D00106E78 /* BusyNavigationBarOptions.swift */; }; 23 | 31DE6CBC1B6B8DC100C7CD5B /* UINavigationBar+Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 313D93BA1B697D2D00106E78 /* UINavigationBar+Animation.swift */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXContainerItemProxy section */ 27 | 313D93A91B697D0A00106E78 /* PBXContainerItemProxy */ = { 28 | isa = PBXContainerItemProxy; 29 | containerPortal = 313D93931B697D0A00106E78 /* Project object */; 30 | proxyType = 1; 31 | remoteGlobalIDString = 313D939B1B697D0A00106E78; 32 | remoteInfo = BusyNavigationBar; 33 | }; 34 | /* End PBXContainerItemProxy section */ 35 | 36 | /* Begin PBXFileReference section */ 37 | 313D939C1B697D0A00106E78 /* BusyNavigationBar.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BusyNavigationBar.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | 313D93A01B697D0A00106E78 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 39 | 313D93A11B697D0A00106E78 /* BusyNavigationBar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BusyNavigationBar.h; sourceTree = ""; }; 40 | 313D93A71B697D0A00106E78 /* BusyNavigationBarTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BusyNavigationBarTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 313D93AD1B697D0A00106E78 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 42 | 313D93AE1B697D0A00106E78 /* BusyNavigationBarTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BusyNavigationBarTests.swift; sourceTree = ""; }; 43 | 313D93B81B697D2D00106E78 /* AnimationLayerCreator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimationLayerCreator.swift; sourceTree = ""; }; 44 | 313D93B91B697D2D00106E78 /* BusyNavigationBarOptions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BusyNavigationBarOptions.swift; sourceTree = ""; }; 45 | 313D93BA1B697D2D00106E78 /* UINavigationBar+Animation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UINavigationBar+Animation.swift"; sourceTree = ""; }; 46 | 313D93C21B697D6B00106E78 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 313D93C51B697D6B00106E78 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 48 | 313D93C61B697D6B00106E78 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 49 | 313D93C81B697D6B00106E78 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 50 | 313D93CB1B697D6B00106E78 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 51 | 313D93CD1B697D6B00106E78 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 52 | 313D93D01B697D6B00106E78 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | 313D93981B697D0A00106E78 /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | 313D93A41B697D0A00106E78 /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | 313D93A81B697D0A00106E78 /* BusyNavigationBar.framework in Frameworks */, 68 | ); 69 | runOnlyForDeploymentPostprocessing = 0; 70 | }; 71 | 313D93BF1B697D6B00106E78 /* Frameworks */ = { 72 | isa = PBXFrameworksBuildPhase; 73 | buildActionMask = 2147483647; 74 | files = ( 75 | ); 76 | runOnlyForDeploymentPostprocessing = 0; 77 | }; 78 | /* End PBXFrameworksBuildPhase section */ 79 | 80 | /* Begin PBXGroup section */ 81 | 313D93921B697D0A00106E78 = { 82 | isa = PBXGroup; 83 | children = ( 84 | 313D939E1B697D0A00106E78 /* BusyNavigationBar */, 85 | 313D93AB1B697D0A00106E78 /* BusyNavigationBarTests */, 86 | 313D93C31B697D6B00106E78 /* Example */, 87 | 313D939D1B697D0A00106E78 /* Products */, 88 | ); 89 | sourceTree = ""; 90 | }; 91 | 313D939D1B697D0A00106E78 /* Products */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | 313D939C1B697D0A00106E78 /* BusyNavigationBar.framework */, 95 | 313D93A71B697D0A00106E78 /* BusyNavigationBarTests.xctest */, 96 | 313D93C21B697D6B00106E78 /* Example.app */, 97 | ); 98 | name = Products; 99 | sourceTree = ""; 100 | }; 101 | 313D939E1B697D0A00106E78 /* BusyNavigationBar */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | 313D93A11B697D0A00106E78 /* BusyNavigationBar.h */, 105 | 313D93B81B697D2D00106E78 /* AnimationLayerCreator.swift */, 106 | 313D93B91B697D2D00106E78 /* BusyNavigationBarOptions.swift */, 107 | 313D93BA1B697D2D00106E78 /* UINavigationBar+Animation.swift */, 108 | 313D939F1B697D0A00106E78 /* Supporting Files */, 109 | ); 110 | path = BusyNavigationBar; 111 | sourceTree = ""; 112 | }; 113 | 313D939F1B697D0A00106E78 /* Supporting Files */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 313D93A01B697D0A00106E78 /* Info.plist */, 117 | ); 118 | name = "Supporting Files"; 119 | sourceTree = ""; 120 | }; 121 | 313D93AB1B697D0A00106E78 /* BusyNavigationBarTests */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 313D93AE1B697D0A00106E78 /* BusyNavigationBarTests.swift */, 125 | 313D93AC1B697D0A00106E78 /* Supporting Files */, 126 | ); 127 | path = BusyNavigationBarTests; 128 | sourceTree = ""; 129 | }; 130 | 313D93AC1B697D0A00106E78 /* Supporting Files */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 313D93AD1B697D0A00106E78 /* Info.plist */, 134 | ); 135 | name = "Supporting Files"; 136 | sourceTree = ""; 137 | }; 138 | 313D93C31B697D6B00106E78 /* Example */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | 313D93C61B697D6B00106E78 /* AppDelegate.swift */, 142 | 313D93C81B697D6B00106E78 /* ViewController.swift */, 143 | 313D93CA1B697D6B00106E78 /* Main.storyboard */, 144 | 313D93CD1B697D6B00106E78 /* Images.xcassets */, 145 | 313D93CF1B697D6B00106E78 /* LaunchScreen.xib */, 146 | 313D93C41B697D6B00106E78 /* Supporting Files */, 147 | ); 148 | path = Example; 149 | sourceTree = ""; 150 | }; 151 | 313D93C41B697D6B00106E78 /* Supporting Files */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | 313D93C51B697D6B00106E78 /* Info.plist */, 155 | ); 156 | name = "Supporting Files"; 157 | sourceTree = ""; 158 | }; 159 | /* End PBXGroup section */ 160 | 161 | /* Begin PBXHeadersBuildPhase section */ 162 | 313D93991B697D0A00106E78 /* Headers */ = { 163 | isa = PBXHeadersBuildPhase; 164 | buildActionMask = 2147483647; 165 | files = ( 166 | 313D93A21B697D0A00106E78 /* BusyNavigationBar.h in Headers */, 167 | ); 168 | runOnlyForDeploymentPostprocessing = 0; 169 | }; 170 | /* End PBXHeadersBuildPhase section */ 171 | 172 | /* Begin PBXNativeTarget section */ 173 | 313D939B1B697D0A00106E78 /* BusyNavigationBar */ = { 174 | isa = PBXNativeTarget; 175 | buildConfigurationList = 313D93B21B697D0A00106E78 /* Build configuration list for PBXNativeTarget "BusyNavigationBar" */; 176 | buildPhases = ( 177 | 313D93971B697D0A00106E78 /* Sources */, 178 | 313D93981B697D0A00106E78 /* Frameworks */, 179 | 313D93991B697D0A00106E78 /* Headers */, 180 | 313D939A1B697D0A00106E78 /* Resources */, 181 | ); 182 | buildRules = ( 183 | ); 184 | dependencies = ( 185 | ); 186 | name = BusyNavigationBar; 187 | productName = BusyNavigationBar; 188 | productReference = 313D939C1B697D0A00106E78 /* BusyNavigationBar.framework */; 189 | productType = "com.apple.product-type.framework"; 190 | }; 191 | 313D93A61B697D0A00106E78 /* BusyNavigationBarTests */ = { 192 | isa = PBXNativeTarget; 193 | buildConfigurationList = 313D93B51B697D0A00106E78 /* Build configuration list for PBXNativeTarget "BusyNavigationBarTests" */; 194 | buildPhases = ( 195 | 313D93A31B697D0A00106E78 /* Sources */, 196 | 313D93A41B697D0A00106E78 /* Frameworks */, 197 | 313D93A51B697D0A00106E78 /* Resources */, 198 | ); 199 | buildRules = ( 200 | ); 201 | dependencies = ( 202 | 313D93AA1B697D0A00106E78 /* PBXTargetDependency */, 203 | ); 204 | name = BusyNavigationBarTests; 205 | productName = BusyNavigationBarTests; 206 | productReference = 313D93A71B697D0A00106E78 /* BusyNavigationBarTests.xctest */; 207 | productType = "com.apple.product-type.bundle.unit-test"; 208 | }; 209 | 313D93C11B697D6B00106E78 /* Example */ = { 210 | isa = PBXNativeTarget; 211 | buildConfigurationList = 313D93DE1B697D6B00106E78 /* Build configuration list for PBXNativeTarget "Example" */; 212 | buildPhases = ( 213 | 313D93BE1B697D6B00106E78 /* Sources */, 214 | 313D93BF1B697D6B00106E78 /* Frameworks */, 215 | 313D93C01B697D6B00106E78 /* Resources */, 216 | ); 217 | buildRules = ( 218 | ); 219 | dependencies = ( 220 | ); 221 | name = Example; 222 | productName = Example; 223 | productReference = 313D93C21B697D6B00106E78 /* Example.app */; 224 | productType = "com.apple.product-type.application"; 225 | }; 226 | /* End PBXNativeTarget section */ 227 | 228 | /* Begin PBXProject section */ 229 | 313D93931B697D0A00106E78 /* Project object */ = { 230 | isa = PBXProject; 231 | attributes = { 232 | LastSwiftUpdateCheck = 0700; 233 | LastUpgradeCheck = 0800; 234 | ORGANIZATIONNAME = "Gunay Mert Karadogan"; 235 | TargetAttributes = { 236 | 313D939B1B697D0A00106E78 = { 237 | CreatedOnToolsVersion = 6.4; 238 | LastSwiftMigration = 0810; 239 | ProvisioningStyle = Automatic; 240 | }; 241 | 313D93A61B697D0A00106E78 = { 242 | CreatedOnToolsVersion = 6.4; 243 | LastSwiftMigration = 0810; 244 | }; 245 | 313D93C11B697D6B00106E78 = { 246 | CreatedOnToolsVersion = 6.4; 247 | LastSwiftMigration = 0800; 248 | }; 249 | }; 250 | }; 251 | buildConfigurationList = 313D93961B697D0A00106E78 /* Build configuration list for PBXProject "BusyNavigationBar" */; 252 | compatibilityVersion = "Xcode 3.2"; 253 | developmentRegion = English; 254 | hasScannedForEncodings = 0; 255 | knownRegions = ( 256 | en, 257 | Base, 258 | ); 259 | mainGroup = 313D93921B697D0A00106E78; 260 | productRefGroup = 313D939D1B697D0A00106E78 /* Products */; 261 | projectDirPath = ""; 262 | projectRoot = ""; 263 | targets = ( 264 | 313D939B1B697D0A00106E78 /* BusyNavigationBar */, 265 | 313D93A61B697D0A00106E78 /* BusyNavigationBarTests */, 266 | 313D93C11B697D6B00106E78 /* Example */, 267 | ); 268 | }; 269 | /* End PBXProject section */ 270 | 271 | /* Begin PBXResourcesBuildPhase section */ 272 | 313D939A1B697D0A00106E78 /* Resources */ = { 273 | isa = PBXResourcesBuildPhase; 274 | buildActionMask = 2147483647; 275 | files = ( 276 | ); 277 | runOnlyForDeploymentPostprocessing = 0; 278 | }; 279 | 313D93A51B697D0A00106E78 /* Resources */ = { 280 | isa = PBXResourcesBuildPhase; 281 | buildActionMask = 2147483647; 282 | files = ( 283 | ); 284 | runOnlyForDeploymentPostprocessing = 0; 285 | }; 286 | 313D93C01B697D6B00106E78 /* Resources */ = { 287 | isa = PBXResourcesBuildPhase; 288 | buildActionMask = 2147483647; 289 | files = ( 290 | 313D93CC1B697D6B00106E78 /* Main.storyboard in Resources */, 291 | 313D93D11B697D6B00106E78 /* LaunchScreen.xib in Resources */, 292 | 313D93CE1B697D6B00106E78 /* Images.xcassets in Resources */, 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | }; 296 | /* End PBXResourcesBuildPhase section */ 297 | 298 | /* Begin PBXSourcesBuildPhase section */ 299 | 313D93971B697D0A00106E78 /* Sources */ = { 300 | isa = PBXSourcesBuildPhase; 301 | buildActionMask = 2147483647; 302 | files = ( 303 | 313D93BD1B697D2D00106E78 /* UINavigationBar+Animation.swift in Sources */, 304 | 313D93BB1B697D2D00106E78 /* AnimationLayerCreator.swift in Sources */, 305 | 313D93BC1B697D2D00106E78 /* BusyNavigationBarOptions.swift in Sources */, 306 | ); 307 | runOnlyForDeploymentPostprocessing = 0; 308 | }; 309 | 313D93A31B697D0A00106E78 /* Sources */ = { 310 | isa = PBXSourcesBuildPhase; 311 | buildActionMask = 2147483647; 312 | files = ( 313 | 313D93AF1B697D0A00106E78 /* BusyNavigationBarTests.swift in Sources */, 314 | ); 315 | runOnlyForDeploymentPostprocessing = 0; 316 | }; 317 | 313D93BE1B697D6B00106E78 /* Sources */ = { 318 | isa = PBXSourcesBuildPhase; 319 | buildActionMask = 2147483647; 320 | files = ( 321 | 31DE6CBC1B6B8DC100C7CD5B /* UINavigationBar+Animation.swift in Sources */, 322 | 31DE6CBA1B6B8DC100C7CD5B /* AnimationLayerCreator.swift in Sources */, 323 | 31DE6CBB1B6B8DC100C7CD5B /* BusyNavigationBarOptions.swift in Sources */, 324 | 313D93C91B697D6B00106E78 /* ViewController.swift in Sources */, 325 | 313D93C71B697D6B00106E78 /* AppDelegate.swift in Sources */, 326 | ); 327 | runOnlyForDeploymentPostprocessing = 0; 328 | }; 329 | /* End PBXSourcesBuildPhase section */ 330 | 331 | /* Begin PBXTargetDependency section */ 332 | 313D93AA1B697D0A00106E78 /* PBXTargetDependency */ = { 333 | isa = PBXTargetDependency; 334 | target = 313D939B1B697D0A00106E78 /* BusyNavigationBar */; 335 | targetProxy = 313D93A91B697D0A00106E78 /* PBXContainerItemProxy */; 336 | }; 337 | /* End PBXTargetDependency section */ 338 | 339 | /* Begin PBXVariantGroup section */ 340 | 313D93CA1B697D6B00106E78 /* Main.storyboard */ = { 341 | isa = PBXVariantGroup; 342 | children = ( 343 | 313D93CB1B697D6B00106E78 /* Base */, 344 | ); 345 | name = Main.storyboard; 346 | sourceTree = ""; 347 | }; 348 | 313D93CF1B697D6B00106E78 /* LaunchScreen.xib */ = { 349 | isa = PBXVariantGroup; 350 | children = ( 351 | 313D93D01B697D6B00106E78 /* Base */, 352 | ); 353 | name = LaunchScreen.xib; 354 | sourceTree = ""; 355 | }; 356 | /* End PBXVariantGroup section */ 357 | 358 | /* Begin XCBuildConfiguration section */ 359 | 313D93B01B697D0A00106E78 /* Debug */ = { 360 | isa = XCBuildConfiguration; 361 | buildSettings = { 362 | ALWAYS_SEARCH_USER_PATHS = NO; 363 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 364 | CLANG_CXX_LIBRARY = "libc++"; 365 | CLANG_ENABLE_MODULES = YES; 366 | CLANG_ENABLE_OBJC_ARC = YES; 367 | CLANG_WARN_BOOL_CONVERSION = YES; 368 | CLANG_WARN_CONSTANT_CONVERSION = YES; 369 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 370 | CLANG_WARN_EMPTY_BODY = YES; 371 | CLANG_WARN_ENUM_CONVERSION = YES; 372 | CLANG_WARN_INFINITE_RECURSION = YES; 373 | CLANG_WARN_INT_CONVERSION = YES; 374 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 375 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 376 | CLANG_WARN_UNREACHABLE_CODE = YES; 377 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 378 | CODE_SIGN_IDENTITY = "iPhone Developer"; 379 | COPY_PHASE_STRIP = NO; 380 | CURRENT_PROJECT_VERSION = 1; 381 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 382 | ENABLE_STRICT_OBJC_MSGSEND = YES; 383 | ENABLE_TESTABILITY = YES; 384 | GCC_C_LANGUAGE_STANDARD = gnu99; 385 | GCC_DYNAMIC_NO_PIC = NO; 386 | GCC_NO_COMMON_BLOCKS = YES; 387 | GCC_OPTIMIZATION_LEVEL = 0; 388 | GCC_PREPROCESSOR_DEFINITIONS = ( 389 | "DEBUG=1", 390 | "$(inherited)", 391 | ); 392 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 393 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 394 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 395 | GCC_WARN_UNDECLARED_SELECTOR = YES; 396 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 397 | GCC_WARN_UNUSED_FUNCTION = YES; 398 | GCC_WARN_UNUSED_VARIABLE = YES; 399 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 400 | MTL_ENABLE_DEBUG_INFO = YES; 401 | ONLY_ACTIVE_ARCH = YES; 402 | SDKROOT = iphoneos; 403 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 404 | TARGETED_DEVICE_FAMILY = "1,2"; 405 | VERSIONING_SYSTEM = "apple-generic"; 406 | VERSION_INFO_PREFIX = ""; 407 | }; 408 | name = Debug; 409 | }; 410 | 313D93B11B697D0A00106E78 /* Release */ = { 411 | isa = XCBuildConfiguration; 412 | buildSettings = { 413 | ALWAYS_SEARCH_USER_PATHS = NO; 414 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 415 | CLANG_CXX_LIBRARY = "libc++"; 416 | CLANG_ENABLE_MODULES = YES; 417 | CLANG_ENABLE_OBJC_ARC = YES; 418 | CLANG_WARN_BOOL_CONVERSION = YES; 419 | CLANG_WARN_CONSTANT_CONVERSION = YES; 420 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 421 | CLANG_WARN_EMPTY_BODY = YES; 422 | CLANG_WARN_ENUM_CONVERSION = YES; 423 | CLANG_WARN_INFINITE_RECURSION = YES; 424 | CLANG_WARN_INT_CONVERSION = YES; 425 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 426 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 427 | CLANG_WARN_UNREACHABLE_CODE = YES; 428 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 429 | CODE_SIGN_IDENTITY = "iPhone Developer"; 430 | COPY_PHASE_STRIP = NO; 431 | CURRENT_PROJECT_VERSION = 1; 432 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 433 | ENABLE_NS_ASSERTIONS = NO; 434 | ENABLE_STRICT_OBJC_MSGSEND = YES; 435 | GCC_C_LANGUAGE_STANDARD = gnu99; 436 | GCC_NO_COMMON_BLOCKS = YES; 437 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 438 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 439 | GCC_WARN_UNDECLARED_SELECTOR = YES; 440 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 441 | GCC_WARN_UNUSED_FUNCTION = YES; 442 | GCC_WARN_UNUSED_VARIABLE = YES; 443 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 444 | MTL_ENABLE_DEBUG_INFO = NO; 445 | SDKROOT = iphoneos; 446 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 447 | TARGETED_DEVICE_FAMILY = "1,2"; 448 | VALIDATE_PRODUCT = YES; 449 | VERSIONING_SYSTEM = "apple-generic"; 450 | VERSION_INFO_PREFIX = ""; 451 | }; 452 | name = Release; 453 | }; 454 | 313D93B31B697D0A00106E78 /* Debug */ = { 455 | isa = XCBuildConfiguration; 456 | buildSettings = { 457 | CLANG_ENABLE_MODULES = YES; 458 | CODE_SIGN_IDENTITY = ""; 459 | DEFINES_MODULE = YES; 460 | DYLIB_COMPATIBILITY_VERSION = 1; 461 | DYLIB_CURRENT_VERSION = 1; 462 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 463 | INFOPLIST_FILE = BusyNavigationBar/Info.plist; 464 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 465 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 466 | PRODUCT_BUNDLE_IDENTIFIER = "com.gunaymert.$(PRODUCT_NAME:rfc1034identifier)"; 467 | PRODUCT_NAME = "$(TARGET_NAME)"; 468 | SKIP_INSTALL = YES; 469 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 470 | SWIFT_VERSION = 3.0; 471 | }; 472 | name = Debug; 473 | }; 474 | 313D93B41B697D0A00106E78 /* Release */ = { 475 | isa = XCBuildConfiguration; 476 | buildSettings = { 477 | CLANG_ENABLE_MODULES = YES; 478 | CODE_SIGN_IDENTITY = ""; 479 | DEFINES_MODULE = YES; 480 | DYLIB_COMPATIBILITY_VERSION = 1; 481 | DYLIB_CURRENT_VERSION = 1; 482 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 483 | INFOPLIST_FILE = BusyNavigationBar/Info.plist; 484 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 485 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 486 | PRODUCT_BUNDLE_IDENTIFIER = "com.gunaymert.$(PRODUCT_NAME:rfc1034identifier)"; 487 | PRODUCT_NAME = "$(TARGET_NAME)"; 488 | SKIP_INSTALL = YES; 489 | SWIFT_VERSION = 3.0; 490 | }; 491 | name = Release; 492 | }; 493 | 313D93B61B697D0A00106E78 /* Debug */ = { 494 | isa = XCBuildConfiguration; 495 | buildSettings = { 496 | FRAMEWORK_SEARCH_PATHS = ( 497 | "$(SDKROOT)/Developer/Library/Frameworks", 498 | "$(inherited)", 499 | ); 500 | GCC_PREPROCESSOR_DEFINITIONS = ( 501 | "DEBUG=1", 502 | "$(inherited)", 503 | ); 504 | INFOPLIST_FILE = BusyNavigationBarTests/Info.plist; 505 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 506 | PRODUCT_BUNDLE_IDENTIFIER = "com.gunaymert.$(PRODUCT_NAME:rfc1034identifier)"; 507 | PRODUCT_NAME = "$(TARGET_NAME)"; 508 | SWIFT_VERSION = 3.0; 509 | }; 510 | name = Debug; 511 | }; 512 | 313D93B71B697D0A00106E78 /* Release */ = { 513 | isa = XCBuildConfiguration; 514 | buildSettings = { 515 | FRAMEWORK_SEARCH_PATHS = ( 516 | "$(SDKROOT)/Developer/Library/Frameworks", 517 | "$(inherited)", 518 | ); 519 | INFOPLIST_FILE = BusyNavigationBarTests/Info.plist; 520 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 521 | PRODUCT_BUNDLE_IDENTIFIER = "com.gunaymert.$(PRODUCT_NAME:rfc1034identifier)"; 522 | PRODUCT_NAME = "$(TARGET_NAME)"; 523 | SWIFT_VERSION = 3.0; 524 | }; 525 | name = Release; 526 | }; 527 | 313D93DF1B697D6B00106E78 /* Debug */ = { 528 | isa = XCBuildConfiguration; 529 | buildSettings = { 530 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 531 | GCC_PREPROCESSOR_DEFINITIONS = ( 532 | "DEBUG=1", 533 | "$(inherited)", 534 | ); 535 | INFOPLIST_FILE = Example/Info.plist; 536 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 537 | PRODUCT_BUNDLE_IDENTIFIER = "com.gunaymert.$(PRODUCT_NAME:rfc1034identifier)"; 538 | PRODUCT_NAME = "$(TARGET_NAME)"; 539 | SWIFT_VERSION = 3.0; 540 | }; 541 | name = Debug; 542 | }; 543 | 313D93E01B697D6B00106E78 /* Release */ = { 544 | isa = XCBuildConfiguration; 545 | buildSettings = { 546 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 547 | INFOPLIST_FILE = Example/Info.plist; 548 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 549 | PRODUCT_BUNDLE_IDENTIFIER = "com.gunaymert.$(PRODUCT_NAME:rfc1034identifier)"; 550 | PRODUCT_NAME = "$(TARGET_NAME)"; 551 | SWIFT_VERSION = 3.0; 552 | }; 553 | name = Release; 554 | }; 555 | /* End XCBuildConfiguration section */ 556 | 557 | /* Begin XCConfigurationList section */ 558 | 313D93961B697D0A00106E78 /* Build configuration list for PBXProject "BusyNavigationBar" */ = { 559 | isa = XCConfigurationList; 560 | buildConfigurations = ( 561 | 313D93B01B697D0A00106E78 /* Debug */, 562 | 313D93B11B697D0A00106E78 /* Release */, 563 | ); 564 | defaultConfigurationIsVisible = 0; 565 | defaultConfigurationName = Release; 566 | }; 567 | 313D93B21B697D0A00106E78 /* Build configuration list for PBXNativeTarget "BusyNavigationBar" */ = { 568 | isa = XCConfigurationList; 569 | buildConfigurations = ( 570 | 313D93B31B697D0A00106E78 /* Debug */, 571 | 313D93B41B697D0A00106E78 /* Release */, 572 | ); 573 | defaultConfigurationIsVisible = 0; 574 | defaultConfigurationName = Release; 575 | }; 576 | 313D93B51B697D0A00106E78 /* Build configuration list for PBXNativeTarget "BusyNavigationBarTests" */ = { 577 | isa = XCConfigurationList; 578 | buildConfigurations = ( 579 | 313D93B61B697D0A00106E78 /* Debug */, 580 | 313D93B71B697D0A00106E78 /* Release */, 581 | ); 582 | defaultConfigurationIsVisible = 0; 583 | defaultConfigurationName = Release; 584 | }; 585 | 313D93DE1B697D6B00106E78 /* Build configuration list for PBXNativeTarget "Example" */ = { 586 | isa = XCConfigurationList; 587 | buildConfigurations = ( 588 | 313D93DF1B697D6B00106E78 /* Debug */, 589 | 313D93E01B697D6B00106E78 /* Release */, 590 | ); 591 | defaultConfigurationIsVisible = 0; 592 | defaultConfigurationName = Release; 593 | }; 594 | /* End XCConfigurationList section */ 595 | }; 596 | rootObject = 313D93931B697D0A00106E78 /* Project object */; 597 | } 598 | -------------------------------------------------------------------------------- /BusyNavigationBar/BusyNavigationBar.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BusyNavigationBar/BusyNavigationBar.xcodeproj/project.xcworkspace/xcshareddata/BusyNavigationBar.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | DC7AC2EE-53A2-413C-88A1-5BA9CB204EE0 9 | IDESourceControlProjectName 10 | BusyNavigationBar 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | C92BBB677CCB65EB413A595F311D34AC9C02B963 14 | https://github.com/gmertk/BusyNavigationBar.git 15 | 16 | IDESourceControlProjectPath 17 | BusyNavigationBar/BusyNavigationBar.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | C92BBB677CCB65EB413A595F311D34AC9C02B963 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/gmertk/BusyNavigationBar.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | C92BBB677CCB65EB413A595F311D34AC9C02B963 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | C92BBB677CCB65EB413A595F311D34AC9C02B963 36 | IDESourceControlWCCName 37 | BusyNavigationBar 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /BusyNavigationBar/BusyNavigationBar.xcodeproj/project.xcworkspace/xcuserdata/gunay.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gmertk/BusyNavigationBar/48059ab3bbf4159d71e8ce69c62c51ae284303c7/BusyNavigationBar/BusyNavigationBar.xcodeproj/project.xcworkspace/xcuserdata/gunay.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /BusyNavigationBar/BusyNavigationBar.xcodeproj/xcshareddata/xcschemes/BusyNavigationBar.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 79 | 85 | 86 | 87 | 88 | 89 | 90 | 96 | 97 | 103 | 104 | 105 | 106 | 108 | 109 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /BusyNavigationBar/BusyNavigationBar.xcodeproj/xcuserdata/gunay.xcuserdatad/xcschemes/Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /BusyNavigationBar/BusyNavigationBar.xcodeproj/xcuserdata/gunay.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | BusyNavigationBar.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | Example.xcscheme 13 | 14 | orderHint 15 | 1 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 313D939B1B697D0A00106E78 21 | 22 | primary 23 | 24 | 25 | 313D93A61B697D0A00106E78 26 | 27 | primary 28 | 29 | 30 | 313D93C11B697D6B00106E78 31 | 32 | primary 33 | 34 | 35 | 313D93D51B697D6B00106E78 36 | 37 | primary 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /BusyNavigationBar/BusyNavigationBar/AnimationLayerCreator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AnimationLayerCreator.swift 3 | // BusyNavigationBar 4 | // 5 | // Created by Gunay Mert Karadogan on 27/7/15. 6 | // 7 | // 8 | 9 | import UIKit 10 | 11 | /** 12 | A struct holding the functions to create animation layers 13 | */ 14 | struct AnimationLayerCreator { 15 | 16 | /** 17 | Creates a layer with stripes animating as in Periscope app. 18 | 19 | :param: bounds The bounds of navigation bar 20 | 21 | :returns: A new layer with stripes animating 22 | */ 23 | static func stripeAnimationLayer(_ bounds: CGRect, options: BusyNavigationBarOptions) -> CALayer { 24 | let barWidth = options.barWidth 25 | 26 | let replicator = CAReplicatorLayer() 27 | replicator.backgroundColor = UIColor.clear.cgColor 28 | replicator.bounds = bounds 29 | replicator.instanceCount = 40 30 | replicator.instanceTransform = CATransform3DMakeTranslation(options.gapWidth + barWidth, 0, 0) 31 | 32 | let stripe = CALayer() 33 | stripe.bounds = CGRect(x: 0, y: 0, width: barWidth, height: bounds.height * 2) 34 | stripe.backgroundColor = options.color.cgColor 35 | stripe.position = CGPoint(x: barWidth / 2, y: bounds.height / 2) 36 | stripe.transform = CATransform3DMakeRotation(CGFloat(M_PI / 4), 0, 0, 1) 37 | replicator.addSublayer(stripe) 38 | 39 | let animation = CABasicAnimation(keyPath: "position.x") 40 | animation.toValue = stripe.position.x - (options.gapWidth + barWidth) 41 | animation.duration = 0.5 42 | animation.speed = options.speed 43 | animation.repeatCount = Float.infinity 44 | stripe.add(animation, forKey: nil) 45 | 46 | return replicator 47 | } 48 | 49 | 50 | /** 51 | Creates a layer with bars animating as in a equalizer. As in Marin Todorov's newsletter. 52 | 53 | :param: bounds The bounds of navigation bar 54 | 55 | :returns: A new layer with bars animating 56 | */ 57 | static func barAnimation(_ bounds: CGRect, options: BusyNavigationBarOptions) -> CALayer { 58 | let barWidth: CGFloat = options.barWidth 59 | let barHeight = bounds.height 60 | 61 | let replicator = CAReplicatorLayer() 62 | replicator.backgroundColor = UIColor.clear.cgColor 63 | replicator.bounds = bounds 64 | replicator.instanceCount = 40 65 | replicator.instanceDelay = 0.1 66 | replicator.instanceTransform = CATransform3DMakeTranslation(options.gapWidth, 0, 0) 67 | 68 | let bar = CALayer() 69 | bar.bounds = CGRect(x: 0, y: 0, width: barWidth, height: barHeight) 70 | bar.backgroundColor = options.color.cgColor 71 | bar.cornerRadius = 1.0 72 | bar.position = CGPoint(x: barWidth/2, y: bounds.height) 73 | replicator.addSublayer(bar) 74 | 75 | let animation = CABasicAnimation(keyPath: "position.y") 76 | animation.toValue = bounds.height / 2 77 | animation.duration = 0.5 78 | animation.speed = options.speed 79 | animation.autoreverses = true 80 | animation.repeatCount = Float.infinity 81 | bar.add(animation, forKey: nil) 82 | 83 | return replicator 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /BusyNavigationBar/BusyNavigationBar/BusyNavigationBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // BusyNavigationBar.h 3 | // BusyNavigationBar 4 | // 5 | // Created by Gunay Mert Karadogan on 29/7/15. 6 | // Copyright (c) 2015 Gunay Mert Karadogan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for BusyNavigationBar. 12 | FOUNDATION_EXPORT double BusyNavigationBarVersionNumber; 13 | 14 | //! Project version string for BusyNavigationBar. 15 | FOUNDATION_EXPORT const unsigned char BusyNavigationBarVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /BusyNavigationBar/BusyNavigationBar/BusyNavigationBarOptions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BusyNavigationBarOptions.swift 3 | // BusyNavigationBar 4 | // 5 | // Created by Gunay Mert Karadogan on 27/7/15. 6 | // 7 | // 8 | 9 | import UIKit 10 | 11 | /** 12 | Animation type 13 | 14 | - Stripes: Sliding stripes as seen in Periscope app. 15 | - Bars: Bars going up and down like a wave. 16 | - CustomLayer(() -> CALayer): Your layer to be inserted above navigation bar's background. In this case, properties other than transparentMaskEnabled and alpha will not be used. 17 | */ 18 | public enum BusyAnimationType { 19 | case stripes, bars, customLayer(() -> CALayer) 20 | } 21 | 22 | /** 23 | Options to customize the behaviour of BusyNavigationBar 24 | */ 25 | open class BusyNavigationBarOptions { 26 | /// Animation type. Defaults to .Stripes. 27 | open var animationType: BusyAnimationType = .stripes 28 | 29 | /// Color of the shapes. Defaults to gray. 30 | open var color = UIColor.gray 31 | 32 | /// Alpha of the animation layer. Remember that there is also an additional (constant) gradient mask over the animation layer. Defaults to 0.5. 33 | open var alpha: CGFloat = 0.5 34 | 35 | /// Width of the bar. Defaults to 20. 36 | open var barWidth: CGFloat = 20 37 | 38 | /// Gap between bars. Defaults to 30. 39 | open var gapWidth: CGFloat = 30 40 | 41 | /// Speed of the animation. 1 corresponds to 0.5 sec. Defaults to 1. 42 | open var speed: Float = 1 43 | 44 | /// Flag for enabling the transparent masking layer over the animation layer. 45 | open var transparentMaskEnabled = true 46 | 47 | public init() {} 48 | 49 | public init(color: UIColor, alpha: CGFloat, animationType: BusyAnimationType, barWidth: CGFloat, gapWidth: CGFloat, speed: Float, transparentMaskEnabled: Bool) { 50 | self.color = color 51 | self.alpha = alpha 52 | self.animationType = animationType 53 | self.barWidth = barWidth 54 | self.gapWidth = gapWidth 55 | self.speed = speed 56 | self.transparentMaskEnabled = transparentMaskEnabled 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /BusyNavigationBar/BusyNavigationBar/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 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /BusyNavigationBar/BusyNavigationBar/UINavigationBar+Animation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBar+Animation.swift 3 | // BusyNavigationBar 4 | // 5 | // Created by Gunay Mert Karadogan on 22/7/15. 6 | // Copyright (c) 2015 Gunay Mert Karadogan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | private var BusyNavigationBarLoadingViewAssociationKey: UInt8 = 0 12 | private var BusyNavigationBarOptionsAssociationKey: UInt8 = 1 13 | private var alphaAnimationDurationOfLoadingView = 0.3 14 | 15 | extension UINavigationBar { 16 | fileprivate var busy_loadingView: UIView? { 17 | get { 18 | return objc_getAssociatedObject(self, &BusyNavigationBarLoadingViewAssociationKey) as? UIView 19 | } 20 | set(newValue) { 21 | objc_setAssociatedObject(self, &BusyNavigationBarLoadingViewAssociationKey, newValue, .OBJC_ASSOCIATION_RETAIN) 22 | } 23 | } 24 | 25 | fileprivate var busy_options: BusyNavigationBarOptions { 26 | get { 27 | return objc_getAssociatedObject(self, &BusyNavigationBarOptionsAssociationKey) as! BusyNavigationBarOptions 28 | } 29 | set(newValue) { 30 | objc_setAssociatedObject(self, &BusyNavigationBarOptionsAssociationKey, newValue, .OBJC_ASSOCIATION_RETAIN) 31 | } 32 | } 33 | 34 | open override var bounds: CGRect { 35 | didSet { 36 | if oldValue != bounds { 37 | 38 | // If busy_loadingView is in the view hierarchy 39 | if let _ = busy_loadingView?.superview { 40 | 41 | // Remove loadingView 42 | busy_loadingView?.removeFromSuperview() 43 | self.busy_loadingView = nil 44 | 45 | // Restart 46 | start(self.busy_options) 47 | } 48 | } 49 | } 50 | } 51 | 52 | public func start(_ options: BusyNavigationBarOptions? = nil) { 53 | if let loadingView = self.busy_loadingView { 54 | loadingView.removeFromSuperview() 55 | } 56 | 57 | busy_options = options ?? BusyNavigationBarOptions() 58 | 59 | insertLoadingView() 60 | 61 | UIView.animate(withDuration: alphaAnimationDurationOfLoadingView, animations: { () -> Void in 62 | self.busy_loadingView!.alpha = self.busy_options.alpha 63 | }) 64 | 65 | let animationLayer = pickAnimationLayer() 66 | animationLayer.masksToBounds = true 67 | animationLayer.position = busy_loadingView!.center 68 | 69 | if busy_options.transparentMaskEnabled { 70 | animationLayer.mask = maskLayer() 71 | } 72 | 73 | busy_loadingView!.layer.addSublayer(animationLayer) 74 | } 75 | 76 | public func stop(){ 77 | if let loadingView = self.busy_loadingView { 78 | UIView.animate(withDuration: alphaAnimationDurationOfLoadingView, animations: { () -> Void in 79 | loadingView.alpha = 0.0 80 | }, completion: { (Completed) -> Void in 81 | loadingView.removeFromSuperview() 82 | }) 83 | } 84 | } 85 | 86 | func insertLoadingView() { 87 | busy_loadingView = UIView(frame: bounds) 88 | busy_loadingView!.center.x = bounds.size.width / 2 89 | busy_loadingView!.alpha = 0.0 90 | busy_loadingView!.layer.masksToBounds = true 91 | busy_loadingView!.isUserInteractionEnabled = false 92 | insertSubview(busy_loadingView!, at: 1) 93 | } 94 | 95 | func pickAnimationLayer() -> CALayer { 96 | var animationLayer: CALayer 97 | 98 | switch busy_options.animationType { 99 | case .stripes: 100 | animationLayer = AnimationLayerCreator.stripeAnimationLayer(bounds, options: busy_options) 101 | case .bars: 102 | animationLayer = AnimationLayerCreator.barAnimation(bounds, options: busy_options) 103 | case .customLayer(let layerCreator): 104 | animationLayer = layerCreator() 105 | } 106 | 107 | return animationLayer 108 | } 109 | 110 | func maskLayer() -> CALayer { 111 | let alphaLayer = CAGradientLayer() 112 | alphaLayer.frame = bounds 113 | alphaLayer.colors = [UIColor(red: 0, green: 0, blue: 0, alpha: 0).cgColor, UIColor(red: 0, green: 0, blue: 0, alpha: 0.2).cgColor] 114 | return alphaLayer 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /BusyNavigationBar/BusyNavigationBarTests/BusyNavigationBarTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BusyNavigationBarTests.swift 3 | // BusyNavigationBarTests 4 | // 5 | // Created by Gunay Mert Karadogan on 29/7/15. 6 | // Copyright (c) 2015 Gunay Mert Karadogan. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class BusyNavigationBarTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /BusyNavigationBar/BusyNavigationBarTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /BusyNavigationBar/Example/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Example 4 | // 5 | // Created by Gunay Mert Karadogan on 29/7/15. 6 | // Copyright (c) 2015 Gunay Mert Karadogan. 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: [UIApplicationLaunchOptionsKey: 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 throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /BusyNavigationBar/Example/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /BusyNavigationBar/Example/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 39 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /BusyNavigationBar/Example/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /BusyNavigationBar/Example/Images.xcassets/swift-bird.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "swift-bird.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /BusyNavigationBar/Example/Images.xcassets/swift-bird.imageset/swift-bird.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gmertk/BusyNavigationBar/48059ab3bbf4159d71e8ce69c62c51ae284303c7/BusyNavigationBar/Example/Images.xcassets/swift-bird.imageset/swift-bird.png -------------------------------------------------------------------------------- /BusyNavigationBar/Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /BusyNavigationBar/Example/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // BusyNavigationBar 4 | // 5 | // Created by Gunay Mert Karadogan on 27/7/15. 6 | // 7 | // 8 | 9 | 10 | import UIKit 11 | //import BusyNavigationBar 12 | 13 | class ViewController: UIViewController { 14 | 15 | @IBOutlet weak var animationType: UISegmentedControl! 16 | var options = BusyNavigationBarOptions() 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | // Do any additional setup after loading the view, typically from a nib. 21 | } 22 | 23 | override func didReceiveMemoryWarning() { 24 | super.didReceiveMemoryWarning() 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | @IBAction func segmentChanged(_ sender: AnyObject) { 29 | self.options = BusyNavigationBarOptions() 30 | 31 | switch animationType.selectedSegmentIndex { 32 | case 0: 33 | options.animationType = .stripes 34 | case 1: 35 | options.animationType = .bars 36 | case 2: 37 | options.animationType = .customLayer(birdLayer) 38 | options.transparentMaskEnabled = false 39 | default: 40 | options.animationType = .stripes 41 | } 42 | 43 | self.navigationController?.navigationBar.start(options) 44 | 45 | } 46 | 47 | @IBAction func startDidTap(_ sender: AnyObject) { 48 | self.navigationController?.navigationBar.start(options) 49 | } 50 | 51 | @IBAction func stopDidTap(_ sender: AnyObject) { 52 | self.navigationController?.navigationBar.stop() 53 | } 54 | 55 | // A sample layer with sliding birds 56 | func birdLayer() -> CALayer { 57 | let bounds = self.navigationController?.navigationBar.bounds 58 | let gap: CGFloat = 100 59 | let numberOfBirds = Int(bounds!.width / gap) 60 | let image = UIImage(named: "swift-bird")?.cgImage 61 | 62 | let container = CALayer() 63 | container.bounds = bounds! 64 | container.position = CGPoint(x: 0, y:0) 65 | 66 | for i in 0.. CALayer): Your layer to be inserted in navigation bar. In this case, properties other than `transparentMaskEnabled` and `alpha` will not be used. 49 | */ 50 | options.animationType = .Stripes 51 | 52 | /// Color of the shapes. Defaults to gray. 53 | options.color = UIColor.grayColor() 54 | 55 | /// Alpha of the animation layer. Remember that there is also an additional (constant) gradient mask over the animation layer. Defaults to 0.5. 56 | options.alpha = 0.5 57 | 58 | /// Width of the bar. Defaults to 20. 59 | options.barWidth = 20 60 | 61 | /// Gap between bars. Defaults to 30. 62 | options.gapWidth = 30 63 | 64 | /// Speed of the animation. 1 corresponds to 0.5 sec. Defaults to 1. 65 | options.speed = 1 66 | 67 | /// Flag for enabling the transparent masking layer over the animation layer. 68 | options.transparentMaskEnabled = true 69 | 70 | 71 | // Start animation 72 | self.navigationController?.navigationBar.start(options) 73 | 74 | // Stop animation 75 | self.navigationController?.navigationBar.stop() 76 | ``` 77 | 78 | ## Author 79 | 80 | Günay Mert Karadoğan, mertkaradogan@gmail.com 81 | 82 | ## License 83 | 84 | BusyNavigationBar is available under the MIT license. See the LICENSE file for more info. 85 | 86 | 87 | ## More 88 | 89 | There is [a nice tutorial](http://www.thinkandbuild.it/implementing-the-periscope-app-pull-to-refresh/) about Periscope's pull-to-refresh control by @bitwaker. 90 | -------------------------------------------------------------------------------- /Screenshots/blue_stripe2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gmertk/BusyNavigationBar/48059ab3bbf4159d71e8ce69c62c51ae284303c7/Screenshots/blue_stripe2.gif -------------------------------------------------------------------------------- /Screenshots/gray_bar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gmertk/BusyNavigationBar/48059ab3bbf4159d71e8ce69c62c51ae284303c7/Screenshots/gray_bar.gif -------------------------------------------------------------------------------- /Screenshots/gray_bird.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gmertk/BusyNavigationBar/48059ab3bbf4159d71e8ce69c62c51ae284303c7/Screenshots/gray_bird.gif -------------------------------------------------------------------------------- /Screenshots/gray_stripe.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gmertk/BusyNavigationBar/48059ab3bbf4159d71e8ce69c62c51ae284303c7/Screenshots/gray_stripe.gif -------------------------------------------------------------------------------- /Screenshots/green_bar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gmertk/BusyNavigationBar/48059ab3bbf4159d71e8ce69c62c51ae284303c7/Screenshots/green_bar.gif --------------------------------------------------------------------------------