├── .gitignore ├── LICENSE ├── README.md ├── SegmentedProgressBar.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── SegmentedProgressBar ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── img1.imageset │ │ ├── A3FF6A9C-70B1-443B-B8E0-0E1AAD91750A.JPG │ │ └── Contents.json │ ├── img2.imageset │ │ ├── 22296A5D-2D03-41E7-A19A-F4899226291F.JPG │ │ └── Contents.json │ └── img3.imageset │ │ ├── 83B68D84-9C00-456A-9BA3-351CACA732CE.JPG │ │ └── Contents.json ├── Base.lproj │ └── LaunchScreen.storyboard ├── Info.plist ├── SegmentedProgressBar.swift └── ViewController.swift └── screenshot.png /.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 | *.moved-aside 24 | *.xcuserstate 25 | 26 | ## Obj-C/Swift specific 27 | *.hmap 28 | *.ipa 29 | *.dSYM.zip 30 | *.dSYM 31 | 32 | ## Playgrounds 33 | timeline.xctimeline 34 | playground.xcworkspace 35 | 36 | # Swift Package Manager 37 | # 38 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 39 | # Packages/ 40 | .build/ 41 | 42 | # CocoaPods 43 | # 44 | # We recommend against adding the Pods directory to your .gitignore. However 45 | # you should judge for yourself, the pros and cons are mentioned at: 46 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 47 | # 48 | # Pods/ 49 | 50 | # Carthage 51 | # 52 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 53 | # Carthage/Checkouts 54 | 55 | Carthage/Build 56 | 57 | # fastlane 58 | # 59 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 60 | # screenshots whenever they are needed. 61 | # For more information about the recommended setup visit: 62 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 63 | 64 | fastlane/report.xml 65 | fastlane/Preview.html 66 | fastlane/screenshots 67 | fastlane/test_output 68 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Dylan Marriott 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | [![Swift Version][swift-image]][swift-url] 3 | [![twitter: @dylan36032](http://img.shields.io/badge/twitter-%40dylan36032-blue.svg?style=flat)](https://twitter.com/dylan36032) 4 | 5 | # SegmentedProgressBar 6 | A simple little control that animates segments like Snapchat or Instagram Stories. 7 | 8 | ![Screenshot](screenshot.png) 9 | 10 | ## Requirements 11 | - iOS 8.0+ 12 | - Xcode 8 13 | 14 | ## Installation 15 | 16 | Drag and drop [`SegmentedProgressBar.swift`](https://raw.githubusercontent.com/D-32/SegmentedProgressBar/master/SegmentedProgressBar/SegmentedProgressBar.swift) into your project. That's it. 17 | 18 | ## Usage 19 | 20 | ```swift 21 | let spb = SegmentedProgressBar(numberOfSegments: 3, duration: 5) 22 | spb.frame = CGRect(x: 15, y: 15, width: view.frame.width - 30, height: 4) 23 | view.addSubview(spb) 24 | 25 | spb.startAnimation() 26 | ``` 27 | 28 | ## Additional Stuff 29 | Delegate: 30 | 31 | ```swift 32 | spb.delegate = self // has to conform to SegmentedProgressBarDelegate 33 | 34 | func segmentedProgressBarChangedIndex(index: Int) { 35 | } 36 | 37 | func segmentedProgressBarFinished() { 38 | } 39 | ``` 40 | 41 | Styling: 42 | 43 | ```swift 44 | spb.topColor = UIColor.white 45 | spb.bottomColor = UIColor.white.withAlphaComponent(0.25) 46 | spb.padding = 2 47 | ``` 48 | 49 | Pausing / Resuming 50 | 51 | ```swift 52 | spb.isPaused = true 53 | spb.isPaused = false 54 | ``` 55 | 56 | Skip / Rewind 57 | 58 | ```swift 59 | spb.skip() 60 | spb.rewind() 61 | ``` 62 | 63 | [swift-image]:https://img.shields.io/badge/swift-3.0-orange.svg 64 | [swift-url]: https://swift.org/ -------------------------------------------------------------------------------- /SegmentedProgressBar.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9A1454E41E6B1F9500195298 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A1454E31E6B1F9500195298 /* AppDelegate.swift */; }; 11 | 9A1454E61E6B1F9500195298 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A1454E51E6B1F9500195298 /* ViewController.swift */; }; 12 | 9A1454EB1E6B1F9500195298 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9A1454EA1E6B1F9500195298 /* Assets.xcassets */; }; 13 | 9A1454EE1E6B1F9500195298 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9A1454EC1E6B1F9500195298 /* LaunchScreen.storyboard */; }; 14 | 9A1454F61E6B1FDC00195298 /* SegmentedProgressBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A1454F51E6B1FDC00195298 /* SegmentedProgressBar.swift */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXFileReference section */ 18 | 9A1454E01E6B1F9500195298 /* SegmentedProgressBar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SegmentedProgressBar.app; sourceTree = BUILT_PRODUCTS_DIR; }; 19 | 9A1454E31E6B1F9500195298 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 20 | 9A1454E51E6B1F9500195298 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 21 | 9A1454EA1E6B1F9500195298 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 22 | 9A1454ED1E6B1F9500195298 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 23 | 9A1454EF1E6B1F9500195298 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 24 | 9A1454F51E6B1FDC00195298 /* SegmentedProgressBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SegmentedProgressBar.swift; sourceTree = ""; }; 25 | /* End PBXFileReference section */ 26 | 27 | /* Begin PBXFrameworksBuildPhase section */ 28 | 9A1454DD1E6B1F9500195298 /* Frameworks */ = { 29 | isa = PBXFrameworksBuildPhase; 30 | buildActionMask = 2147483647; 31 | files = ( 32 | ); 33 | runOnlyForDeploymentPostprocessing = 0; 34 | }; 35 | /* End PBXFrameworksBuildPhase section */ 36 | 37 | /* Begin PBXGroup section */ 38 | 9A1454D71E6B1F9400195298 = { 39 | isa = PBXGroup; 40 | children = ( 41 | 9A1454E21E6B1F9500195298 /* SegmentedProgressBar */, 42 | 9A1454E11E6B1F9500195298 /* Products */, 43 | ); 44 | sourceTree = ""; 45 | }; 46 | 9A1454E11E6B1F9500195298 /* Products */ = { 47 | isa = PBXGroup; 48 | children = ( 49 | 9A1454E01E6B1F9500195298 /* SegmentedProgressBar.app */, 50 | ); 51 | name = Products; 52 | sourceTree = ""; 53 | }; 54 | 9A1454E21E6B1F9500195298 /* SegmentedProgressBar */ = { 55 | isa = PBXGroup; 56 | children = ( 57 | 9A1454E31E6B1F9500195298 /* AppDelegate.swift */, 58 | 9A1454E51E6B1F9500195298 /* ViewController.swift */, 59 | 9A1454F51E6B1FDC00195298 /* SegmentedProgressBar.swift */, 60 | 9A1454EA1E6B1F9500195298 /* Assets.xcassets */, 61 | 9A1454EC1E6B1F9500195298 /* LaunchScreen.storyboard */, 62 | 9A1454EF1E6B1F9500195298 /* Info.plist */, 63 | ); 64 | path = SegmentedProgressBar; 65 | sourceTree = ""; 66 | }; 67 | /* End PBXGroup section */ 68 | 69 | /* Begin PBXNativeTarget section */ 70 | 9A1454DF1E6B1F9500195298 /* SegmentedProgressBar */ = { 71 | isa = PBXNativeTarget; 72 | buildConfigurationList = 9A1454F21E6B1F9500195298 /* Build configuration list for PBXNativeTarget "SegmentedProgressBar" */; 73 | buildPhases = ( 74 | 9A1454DC1E6B1F9500195298 /* Sources */, 75 | 9A1454DD1E6B1F9500195298 /* Frameworks */, 76 | 9A1454DE1E6B1F9500195298 /* Resources */, 77 | ); 78 | buildRules = ( 79 | ); 80 | dependencies = ( 81 | ); 82 | name = SegmentedProgressBar; 83 | productName = SegmentedProgressBar; 84 | productReference = 9A1454E01E6B1F9500195298 /* SegmentedProgressBar.app */; 85 | productType = "com.apple.product-type.application"; 86 | }; 87 | /* End PBXNativeTarget section */ 88 | 89 | /* Begin PBXProject section */ 90 | 9A1454D81E6B1F9400195298 /* Project object */ = { 91 | isa = PBXProject; 92 | attributes = { 93 | LastSwiftUpdateCheck = 0820; 94 | LastUpgradeCheck = 0820; 95 | ORGANIZATIONNAME = "Dylan Marriott"; 96 | TargetAttributes = { 97 | 9A1454DF1E6B1F9500195298 = { 98 | CreatedOnToolsVersion = 8.2.1; 99 | DevelopmentTeam = 5EFBK52YD3; 100 | ProvisioningStyle = Automatic; 101 | }; 102 | }; 103 | }; 104 | buildConfigurationList = 9A1454DB1E6B1F9400195298 /* Build configuration list for PBXProject "SegmentedProgressBar" */; 105 | compatibilityVersion = "Xcode 3.2"; 106 | developmentRegion = English; 107 | hasScannedForEncodings = 0; 108 | knownRegions = ( 109 | en, 110 | Base, 111 | ); 112 | mainGroup = 9A1454D71E6B1F9400195298; 113 | productRefGroup = 9A1454E11E6B1F9500195298 /* Products */; 114 | projectDirPath = ""; 115 | projectRoot = ""; 116 | targets = ( 117 | 9A1454DF1E6B1F9500195298 /* SegmentedProgressBar */, 118 | ); 119 | }; 120 | /* End PBXProject section */ 121 | 122 | /* Begin PBXResourcesBuildPhase section */ 123 | 9A1454DE1E6B1F9500195298 /* Resources */ = { 124 | isa = PBXResourcesBuildPhase; 125 | buildActionMask = 2147483647; 126 | files = ( 127 | 9A1454EE1E6B1F9500195298 /* LaunchScreen.storyboard in Resources */, 128 | 9A1454EB1E6B1F9500195298 /* Assets.xcassets in Resources */, 129 | ); 130 | runOnlyForDeploymentPostprocessing = 0; 131 | }; 132 | /* End PBXResourcesBuildPhase section */ 133 | 134 | /* Begin PBXSourcesBuildPhase section */ 135 | 9A1454DC1E6B1F9500195298 /* Sources */ = { 136 | isa = PBXSourcesBuildPhase; 137 | buildActionMask = 2147483647; 138 | files = ( 139 | 9A1454E61E6B1F9500195298 /* ViewController.swift in Sources */, 140 | 9A1454E41E6B1F9500195298 /* AppDelegate.swift in Sources */, 141 | 9A1454F61E6B1FDC00195298 /* SegmentedProgressBar.swift in Sources */, 142 | ); 143 | runOnlyForDeploymentPostprocessing = 0; 144 | }; 145 | /* End PBXSourcesBuildPhase section */ 146 | 147 | /* Begin PBXVariantGroup section */ 148 | 9A1454EC1E6B1F9500195298 /* LaunchScreen.storyboard */ = { 149 | isa = PBXVariantGroup; 150 | children = ( 151 | 9A1454ED1E6B1F9500195298 /* Base */, 152 | ); 153 | name = LaunchScreen.storyboard; 154 | sourceTree = ""; 155 | }; 156 | /* End PBXVariantGroup section */ 157 | 158 | /* Begin XCBuildConfiguration section */ 159 | 9A1454F01E6B1F9500195298 /* Debug */ = { 160 | isa = XCBuildConfiguration; 161 | buildSettings = { 162 | ALWAYS_SEARCH_USER_PATHS = NO; 163 | CLANG_ANALYZER_NONNULL = YES; 164 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 165 | CLANG_CXX_LIBRARY = "libc++"; 166 | CLANG_ENABLE_MODULES = YES; 167 | CLANG_ENABLE_OBJC_ARC = YES; 168 | CLANG_WARN_BOOL_CONVERSION = YES; 169 | CLANG_WARN_CONSTANT_CONVERSION = YES; 170 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 171 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 172 | CLANG_WARN_EMPTY_BODY = YES; 173 | CLANG_WARN_ENUM_CONVERSION = YES; 174 | CLANG_WARN_INFINITE_RECURSION = YES; 175 | CLANG_WARN_INT_CONVERSION = YES; 176 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 177 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 178 | CLANG_WARN_UNREACHABLE_CODE = YES; 179 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 180 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 181 | COPY_PHASE_STRIP = NO; 182 | DEBUG_INFORMATION_FORMAT = dwarf; 183 | ENABLE_STRICT_OBJC_MSGSEND = YES; 184 | ENABLE_TESTABILITY = YES; 185 | GCC_C_LANGUAGE_STANDARD = gnu99; 186 | GCC_DYNAMIC_NO_PIC = NO; 187 | GCC_NO_COMMON_BLOCKS = YES; 188 | GCC_OPTIMIZATION_LEVEL = 0; 189 | GCC_PREPROCESSOR_DEFINITIONS = ( 190 | "DEBUG=1", 191 | "$(inherited)", 192 | ); 193 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 194 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 195 | GCC_WARN_UNDECLARED_SELECTOR = YES; 196 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 197 | GCC_WARN_UNUSED_FUNCTION = YES; 198 | GCC_WARN_UNUSED_VARIABLE = YES; 199 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 200 | MTL_ENABLE_DEBUG_INFO = YES; 201 | ONLY_ACTIVE_ARCH = YES; 202 | SDKROOT = iphoneos; 203 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 204 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 205 | }; 206 | name = Debug; 207 | }; 208 | 9A1454F11E6B1F9500195298 /* Release */ = { 209 | isa = XCBuildConfiguration; 210 | buildSettings = { 211 | ALWAYS_SEARCH_USER_PATHS = NO; 212 | CLANG_ANALYZER_NONNULL = YES; 213 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 214 | CLANG_CXX_LIBRARY = "libc++"; 215 | CLANG_ENABLE_MODULES = YES; 216 | CLANG_ENABLE_OBJC_ARC = YES; 217 | CLANG_WARN_BOOL_CONVERSION = YES; 218 | CLANG_WARN_CONSTANT_CONVERSION = YES; 219 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 220 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 221 | CLANG_WARN_EMPTY_BODY = YES; 222 | CLANG_WARN_ENUM_CONVERSION = YES; 223 | CLANG_WARN_INFINITE_RECURSION = YES; 224 | CLANG_WARN_INT_CONVERSION = YES; 225 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 226 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 227 | CLANG_WARN_UNREACHABLE_CODE = YES; 228 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 229 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 230 | COPY_PHASE_STRIP = NO; 231 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 232 | ENABLE_NS_ASSERTIONS = NO; 233 | ENABLE_STRICT_OBJC_MSGSEND = YES; 234 | GCC_C_LANGUAGE_STANDARD = gnu99; 235 | GCC_NO_COMMON_BLOCKS = YES; 236 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 237 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 238 | GCC_WARN_UNDECLARED_SELECTOR = YES; 239 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 240 | GCC_WARN_UNUSED_FUNCTION = YES; 241 | GCC_WARN_UNUSED_VARIABLE = YES; 242 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 243 | MTL_ENABLE_DEBUG_INFO = NO; 244 | SDKROOT = iphoneos; 245 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 246 | VALIDATE_PRODUCT = YES; 247 | }; 248 | name = Release; 249 | }; 250 | 9A1454F31E6B1F9500195298 /* Debug */ = { 251 | isa = XCBuildConfiguration; 252 | buildSettings = { 253 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 254 | DEVELOPMENT_TEAM = 5EFBK52YD3; 255 | INFOPLIST_FILE = SegmentedProgressBar/Info.plist; 256 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 257 | PRODUCT_BUNDLE_IDENTIFIER = com.dylanmarriott.SegmentedProgressBar; 258 | PRODUCT_NAME = "$(TARGET_NAME)"; 259 | SWIFT_VERSION = 3.0; 260 | }; 261 | name = Debug; 262 | }; 263 | 9A1454F41E6B1F9500195298 /* Release */ = { 264 | isa = XCBuildConfiguration; 265 | buildSettings = { 266 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 267 | DEVELOPMENT_TEAM = 5EFBK52YD3; 268 | INFOPLIST_FILE = SegmentedProgressBar/Info.plist; 269 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 270 | PRODUCT_BUNDLE_IDENTIFIER = com.dylanmarriott.SegmentedProgressBar; 271 | PRODUCT_NAME = "$(TARGET_NAME)"; 272 | SWIFT_VERSION = 3.0; 273 | }; 274 | name = Release; 275 | }; 276 | /* End XCBuildConfiguration section */ 277 | 278 | /* Begin XCConfigurationList section */ 279 | 9A1454DB1E6B1F9400195298 /* Build configuration list for PBXProject "SegmentedProgressBar" */ = { 280 | isa = XCConfigurationList; 281 | buildConfigurations = ( 282 | 9A1454F01E6B1F9500195298 /* Debug */, 283 | 9A1454F11E6B1F9500195298 /* Release */, 284 | ); 285 | defaultConfigurationIsVisible = 0; 286 | defaultConfigurationName = Release; 287 | }; 288 | 9A1454F21E6B1F9500195298 /* Build configuration list for PBXNativeTarget "SegmentedProgressBar" */ = { 289 | isa = XCConfigurationList; 290 | buildConfigurations = ( 291 | 9A1454F31E6B1F9500195298 /* Debug */, 292 | 9A1454F41E6B1F9500195298 /* Release */, 293 | ); 294 | defaultConfigurationIsVisible = 0; 295 | }; 296 | /* End XCConfigurationList section */ 297 | }; 298 | rootObject = 9A1454D81E6B1F9400195298 /* Project object */; 299 | } 300 | -------------------------------------------------------------------------------- /SegmentedProgressBar.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SegmentedProgressBar/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SegmentedProgressBar 4 | // 5 | // Created by Dylan Marriott on 04.03.17. 6 | // Copyright © 2017 Dylan Marriott. 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 | 19 | window = UIWindow(frame: UIScreen.main.bounds) 20 | window!.rootViewController = ViewController() 21 | window!.makeKeyAndVisible() 22 | 23 | return true 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /SegmentedProgressBar/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 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /SegmentedProgressBar/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /SegmentedProgressBar/Assets.xcassets/img1.imageset/A3FF6A9C-70B1-443B-B8E0-0E1AAD91750A.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-32/SegmentedProgressBar/ef3aafd62a5e93820a922d03b430a64e90604c03/SegmentedProgressBar/Assets.xcassets/img1.imageset/A3FF6A9C-70B1-443B-B8E0-0E1AAD91750A.JPG -------------------------------------------------------------------------------- /SegmentedProgressBar/Assets.xcassets/img1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "A3FF6A9C-70B1-443B-B8E0-0E1AAD91750A.JPG", 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 | } -------------------------------------------------------------------------------- /SegmentedProgressBar/Assets.xcassets/img2.imageset/22296A5D-2D03-41E7-A19A-F4899226291F.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-32/SegmentedProgressBar/ef3aafd62a5e93820a922d03b430a64e90604c03/SegmentedProgressBar/Assets.xcassets/img2.imageset/22296A5D-2D03-41E7-A19A-F4899226291F.JPG -------------------------------------------------------------------------------- /SegmentedProgressBar/Assets.xcassets/img2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "22296A5D-2D03-41E7-A19A-F4899226291F.JPG", 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 | } -------------------------------------------------------------------------------- /SegmentedProgressBar/Assets.xcassets/img3.imageset/83B68D84-9C00-456A-9BA3-351CACA732CE.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-32/SegmentedProgressBar/ef3aafd62a5e93820a922d03b430a64e90604c03/SegmentedProgressBar/Assets.xcassets/img3.imageset/83B68D84-9C00-456A-9BA3-351CACA732CE.JPG -------------------------------------------------------------------------------- /SegmentedProgressBar/Assets.xcassets/img3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "83B68D84-9C00-456A-9BA3-351CACA732CE.JPG", 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 | } -------------------------------------------------------------------------------- /SegmentedProgressBar/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 | 27 | 28 | -------------------------------------------------------------------------------- /SegmentedProgressBar/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 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | UIViewControllerBasedStatusBarAppearance 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /SegmentedProgressBar/SegmentedProgressBar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SegmentedProgressBar.swift 3 | // SegmentedProgressBar 4 | // 5 | // Created by Dylan Marriott on 04.03.17. 6 | // Copyright © 2017 Dylan Marriott. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | protocol SegmentedProgressBarDelegate: class { 13 | func segmentedProgressBarChangedIndex(index: Int) 14 | func segmentedProgressBarFinished() 15 | } 16 | 17 | class SegmentedProgressBar: UIView { 18 | 19 | weak var delegate: SegmentedProgressBarDelegate? 20 | var topColor = UIColor.gray { 21 | didSet { 22 | self.updateColors() 23 | } 24 | } 25 | var bottomColor = UIColor.gray.withAlphaComponent(0.25) { 26 | didSet { 27 | self.updateColors() 28 | } 29 | } 30 | var padding: CGFloat = 2.0 31 | var isPaused: Bool = false { 32 | didSet { 33 | if isPaused { 34 | for segment in segments { 35 | let layer = segment.topSegmentView.layer 36 | let pausedTime = layer.convertTime(CACurrentMediaTime(), from: nil) 37 | layer.speed = 0.0 38 | layer.timeOffset = pausedTime 39 | } 40 | } else { 41 | let segment = segments[currentAnimationIndex] 42 | let layer = segment.topSegmentView.layer 43 | let pausedTime = layer.timeOffset 44 | layer.speed = 1.0 45 | layer.timeOffset = 0.0 46 | layer.beginTime = 0.0 47 | let timeSincePause = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime 48 | layer.beginTime = timeSincePause 49 | } 50 | } 51 | } 52 | 53 | private var segments = [Segment]() 54 | private let duration: TimeInterval 55 | private var hasDoneLayout = false // hacky way to prevent layouting again 56 | private var currentAnimationIndex = 0 57 | 58 | init(numberOfSegments: Int, duration: TimeInterval = 5.0) { 59 | self.duration = duration 60 | super.init(frame: CGRect.zero) 61 | 62 | for _ in 0..