├── .gitignore ├── DoneHUD.podspec ├── DoneHUD.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ ├── DoneHUD.xcscmblueprint │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ ├── a13004.xcuserdatad │ └── UserInterfaceState.xcuserstate │ └── salmanhasratkhan.xcuserdatad │ └── UserInterfaceState.xcuserstate ├── DoneHUD ├── AppDelegate.swift ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── DoneHUD.swift ├── DoneView.swift ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist └── ViewController.swift ├── DoneHUDTests ├── DoneHUDTests.swift └── Info.plist ├── DoneHUD_demo.gif ├── LICENSE ├── README.md └── Source ├── DoneHUD.swift └── DoneView.swift /.gitignore: -------------------------------------------------------------------------------- 1 | ./build/ 2 | ./build-test/ 3 | xcuserdata/ 4 | *.xccheckout 5 | *.gcno 6 | -------------------------------------------------------------------------------- /DoneHUD.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "DoneHUD" 3 | s.version = "1.0.2" 4 | s.swift_versions = "5.0" 5 | s.summary = "Done animation on HUD made with Swift" 6 | s.homepage = "https://github.com/beryu/DoneHUD" 7 | s.screenshots = "https://github.com/beryu/DoneHUD/raw/master/DoneHUD_demo.gif" 8 | s.license = { :type => "MIT", :file => "LICENSE" } 9 | s.author = { "Ryuta Kibe" => "beryu@blk.jp" } 10 | s.social_media_url = "http://twitter.com/beryu" 11 | s.platform = :ios 12 | s.ios.deployment_target = "8.0" 13 | s.source = { :git => "https://github.com/beryu/DoneHUD.git", :tag => s.version } 14 | s.source_files = "Source/*" 15 | s.requires_arc = true 16 | end 17 | 18 | -------------------------------------------------------------------------------- /DoneHUD.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 878318F91B88E21F0062D8D7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 878318F81B88E21F0062D8D7 /* AppDelegate.swift */; }; 11 | 878318FB1B88E21F0062D8D7 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 878318FA1B88E21F0062D8D7 /* ViewController.swift */; }; 12 | 878318FE1B88E21F0062D8D7 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 878318FC1B88E21F0062D8D7 /* Main.storyboard */; }; 13 | 878319001B88E21F0062D8D7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 878318FF1B88E21F0062D8D7 /* Images.xcassets */; }; 14 | 878319031B88E21F0062D8D7 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 878319011B88E21F0062D8D7 /* LaunchScreen.xib */; }; 15 | 8783190F1B88E21F0062D8D7 /* DoneHUDTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8783190E1B88E21F0062D8D7 /* DoneHUDTests.swift */; }; 16 | 8783191A1B88E2420062D8D7 /* DoneHUD.swift in Sources */ = {isa = PBXBuildFile; fileRef = 878319181B88E2420062D8D7 /* DoneHUD.swift */; }; 17 | 8783191B1B88E2420062D8D7 /* DoneView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 878319191B88E2420062D8D7 /* DoneView.swift */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXContainerItemProxy section */ 21 | 878319091B88E21F0062D8D7 /* PBXContainerItemProxy */ = { 22 | isa = PBXContainerItemProxy; 23 | containerPortal = 878318EB1B88E21E0062D8D7 /* Project object */; 24 | proxyType = 1; 25 | remoteGlobalIDString = 878318F21B88E21E0062D8D7; 26 | remoteInfo = DoneHUD; 27 | }; 28 | /* End PBXContainerItemProxy section */ 29 | 30 | /* Begin PBXFileReference section */ 31 | 878318F31B88E21E0062D8D7 /* DoneHUD.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DoneHUD.app; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | 878318F71B88E21F0062D8D7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 33 | 878318F81B88E21F0062D8D7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 34 | 878318FA1B88E21F0062D8D7 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 35 | 878318FD1B88E21F0062D8D7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 36 | 878318FF1B88E21F0062D8D7 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 37 | 878319021B88E21F0062D8D7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 38 | 878319081B88E21F0062D8D7 /* DoneHUDTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DoneHUDTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 39 | 8783190D1B88E21F0062D8D7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 40 | 8783190E1B88E21F0062D8D7 /* DoneHUDTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoneHUDTests.swift; sourceTree = ""; }; 41 | 878319181B88E2420062D8D7 /* DoneHUD.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoneHUD.swift; sourceTree = ""; }; 42 | 878319191B88E2420062D8D7 /* DoneView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoneView.swift; sourceTree = ""; }; 43 | /* End PBXFileReference section */ 44 | 45 | /* Begin PBXFrameworksBuildPhase section */ 46 | 878318F01B88E21E0062D8D7 /* Frameworks */ = { 47 | isa = PBXFrameworksBuildPhase; 48 | buildActionMask = 2147483647; 49 | files = ( 50 | ); 51 | runOnlyForDeploymentPostprocessing = 0; 52 | }; 53 | 878319051B88E21F0062D8D7 /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | ); 58 | runOnlyForDeploymentPostprocessing = 0; 59 | }; 60 | /* End PBXFrameworksBuildPhase section */ 61 | 62 | /* Begin PBXGroup section */ 63 | 878318EA1B88E21E0062D8D7 = { 64 | isa = PBXGroup; 65 | children = ( 66 | 878318F51B88E21E0062D8D7 /* DoneHUD */, 67 | 8783190B1B88E21F0062D8D7 /* DoneHUDTests */, 68 | 878318F41B88E21E0062D8D7 /* Products */, 69 | ); 70 | sourceTree = ""; 71 | }; 72 | 878318F41B88E21E0062D8D7 /* Products */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | 878318F31B88E21E0062D8D7 /* DoneHUD.app */, 76 | 878319081B88E21F0062D8D7 /* DoneHUDTests.xctest */, 77 | ); 78 | name = Products; 79 | sourceTree = ""; 80 | }; 81 | 878318F51B88E21E0062D8D7 /* DoneHUD */ = { 82 | isa = PBXGroup; 83 | children = ( 84 | 878319181B88E2420062D8D7 /* DoneHUD.swift */, 85 | 878319191B88E2420062D8D7 /* DoneView.swift */, 86 | 878318F81B88E21F0062D8D7 /* AppDelegate.swift */, 87 | 878318FA1B88E21F0062D8D7 /* ViewController.swift */, 88 | 878318FC1B88E21F0062D8D7 /* Main.storyboard */, 89 | 878318FF1B88E21F0062D8D7 /* Images.xcassets */, 90 | 878319011B88E21F0062D8D7 /* LaunchScreen.xib */, 91 | 878318F61B88E21F0062D8D7 /* Supporting Files */, 92 | ); 93 | path = DoneHUD; 94 | sourceTree = ""; 95 | }; 96 | 878318F61B88E21F0062D8D7 /* Supporting Files */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 878318F71B88E21F0062D8D7 /* Info.plist */, 100 | ); 101 | name = "Supporting Files"; 102 | sourceTree = ""; 103 | }; 104 | 8783190B1B88E21F0062D8D7 /* DoneHUDTests */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 8783190E1B88E21F0062D8D7 /* DoneHUDTests.swift */, 108 | 8783190C1B88E21F0062D8D7 /* Supporting Files */, 109 | ); 110 | path = DoneHUDTests; 111 | sourceTree = ""; 112 | }; 113 | 8783190C1B88E21F0062D8D7 /* Supporting Files */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 8783190D1B88E21F0062D8D7 /* Info.plist */, 117 | ); 118 | name = "Supporting Files"; 119 | sourceTree = ""; 120 | }; 121 | /* End PBXGroup section */ 122 | 123 | /* Begin PBXNativeTarget section */ 124 | 878318F21B88E21E0062D8D7 /* DoneHUD */ = { 125 | isa = PBXNativeTarget; 126 | buildConfigurationList = 878319121B88E21F0062D8D7 /* Build configuration list for PBXNativeTarget "DoneHUD" */; 127 | buildPhases = ( 128 | 878318EF1B88E21E0062D8D7 /* Sources */, 129 | 878318F01B88E21E0062D8D7 /* Frameworks */, 130 | 878318F11B88E21E0062D8D7 /* Resources */, 131 | ); 132 | buildRules = ( 133 | ); 134 | dependencies = ( 135 | ); 136 | name = DoneHUD; 137 | productName = DoneHUD; 138 | productReference = 878318F31B88E21E0062D8D7 /* DoneHUD.app */; 139 | productType = "com.apple.product-type.application"; 140 | }; 141 | 878319071B88E21F0062D8D7 /* DoneHUDTests */ = { 142 | isa = PBXNativeTarget; 143 | buildConfigurationList = 878319151B88E21F0062D8D7 /* Build configuration list for PBXNativeTarget "DoneHUDTests" */; 144 | buildPhases = ( 145 | 878319041B88E21F0062D8D7 /* Sources */, 146 | 878319051B88E21F0062D8D7 /* Frameworks */, 147 | 878319061B88E21F0062D8D7 /* Resources */, 148 | ); 149 | buildRules = ( 150 | ); 151 | dependencies = ( 152 | 8783190A1B88E21F0062D8D7 /* PBXTargetDependency */, 153 | ); 154 | name = DoneHUDTests; 155 | productName = DoneHUDTests; 156 | productReference = 878319081B88E21F0062D8D7 /* DoneHUDTests.xctest */; 157 | productType = "com.apple.product-type.bundle.unit-test"; 158 | }; 159 | /* End PBXNativeTarget section */ 160 | 161 | /* Begin PBXProject section */ 162 | 878318EB1B88E21E0062D8D7 /* Project object */ = { 163 | isa = PBXProject; 164 | attributes = { 165 | LastSwiftMigration = 0710; 166 | LastSwiftUpdateCheck = 0710; 167 | LastUpgradeCheck = 0900; 168 | ORGANIZATIONNAME = blk; 169 | TargetAttributes = { 170 | 878318F21B88E21E0062D8D7 = { 171 | CreatedOnToolsVersion = 6.4; 172 | LastSwiftMigration = 0800; 173 | }; 174 | 878319071B88E21F0062D8D7 = { 175 | CreatedOnToolsVersion = 6.4; 176 | LastSwiftMigration = 0800; 177 | TestTargetID = 878318F21B88E21E0062D8D7; 178 | }; 179 | }; 180 | }; 181 | buildConfigurationList = 878318EE1B88E21E0062D8D7 /* Build configuration list for PBXProject "DoneHUD" */; 182 | compatibilityVersion = "Xcode 3.2"; 183 | developmentRegion = English; 184 | hasScannedForEncodings = 0; 185 | knownRegions = ( 186 | English, 187 | en, 188 | Base, 189 | ); 190 | mainGroup = 878318EA1B88E21E0062D8D7; 191 | productRefGroup = 878318F41B88E21E0062D8D7 /* Products */; 192 | projectDirPath = ""; 193 | projectRoot = ""; 194 | targets = ( 195 | 878318F21B88E21E0062D8D7 /* DoneHUD */, 196 | 878319071B88E21F0062D8D7 /* DoneHUDTests */, 197 | ); 198 | }; 199 | /* End PBXProject section */ 200 | 201 | /* Begin PBXResourcesBuildPhase section */ 202 | 878318F11B88E21E0062D8D7 /* Resources */ = { 203 | isa = PBXResourcesBuildPhase; 204 | buildActionMask = 2147483647; 205 | files = ( 206 | 878318FE1B88E21F0062D8D7 /* Main.storyboard in Resources */, 207 | 878319031B88E21F0062D8D7 /* LaunchScreen.xib in Resources */, 208 | 878319001B88E21F0062D8D7 /* Images.xcassets in Resources */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | 878319061B88E21F0062D8D7 /* Resources */ = { 213 | isa = PBXResourcesBuildPhase; 214 | buildActionMask = 2147483647; 215 | files = ( 216 | ); 217 | runOnlyForDeploymentPostprocessing = 0; 218 | }; 219 | /* End PBXResourcesBuildPhase section */ 220 | 221 | /* Begin PBXSourcesBuildPhase section */ 222 | 878318EF1B88E21E0062D8D7 /* Sources */ = { 223 | isa = PBXSourcesBuildPhase; 224 | buildActionMask = 2147483647; 225 | files = ( 226 | 878318FB1B88E21F0062D8D7 /* ViewController.swift in Sources */, 227 | 8783191A1B88E2420062D8D7 /* DoneHUD.swift in Sources */, 228 | 8783191B1B88E2420062D8D7 /* DoneView.swift in Sources */, 229 | 878318F91B88E21F0062D8D7 /* AppDelegate.swift in Sources */, 230 | ); 231 | runOnlyForDeploymentPostprocessing = 0; 232 | }; 233 | 878319041B88E21F0062D8D7 /* Sources */ = { 234 | isa = PBXSourcesBuildPhase; 235 | buildActionMask = 2147483647; 236 | files = ( 237 | 8783190F1B88E21F0062D8D7 /* DoneHUDTests.swift in Sources */, 238 | ); 239 | runOnlyForDeploymentPostprocessing = 0; 240 | }; 241 | /* End PBXSourcesBuildPhase section */ 242 | 243 | /* Begin PBXTargetDependency section */ 244 | 8783190A1B88E21F0062D8D7 /* PBXTargetDependency */ = { 245 | isa = PBXTargetDependency; 246 | target = 878318F21B88E21E0062D8D7 /* DoneHUD */; 247 | targetProxy = 878319091B88E21F0062D8D7 /* PBXContainerItemProxy */; 248 | }; 249 | /* End PBXTargetDependency section */ 250 | 251 | /* Begin PBXVariantGroup section */ 252 | 878318FC1B88E21F0062D8D7 /* Main.storyboard */ = { 253 | isa = PBXVariantGroup; 254 | children = ( 255 | 878318FD1B88E21F0062D8D7 /* Base */, 256 | ); 257 | name = Main.storyboard; 258 | sourceTree = ""; 259 | }; 260 | 878319011B88E21F0062D8D7 /* LaunchScreen.xib */ = { 261 | isa = PBXVariantGroup; 262 | children = ( 263 | 878319021B88E21F0062D8D7 /* Base */, 264 | ); 265 | name = LaunchScreen.xib; 266 | sourceTree = ""; 267 | }; 268 | /* End PBXVariantGroup section */ 269 | 270 | /* Begin XCBuildConfiguration section */ 271 | 878319101B88E21F0062D8D7 /* Debug */ = { 272 | isa = XCBuildConfiguration; 273 | buildSettings = { 274 | ALWAYS_SEARCH_USER_PATHS = NO; 275 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 276 | CLANG_CXX_LIBRARY = "libc++"; 277 | CLANG_ENABLE_MODULES = YES; 278 | CLANG_ENABLE_OBJC_ARC = YES; 279 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 280 | CLANG_WARN_BOOL_CONVERSION = YES; 281 | CLANG_WARN_COMMA = YES; 282 | CLANG_WARN_CONSTANT_CONVERSION = YES; 283 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 284 | CLANG_WARN_EMPTY_BODY = YES; 285 | CLANG_WARN_ENUM_CONVERSION = YES; 286 | CLANG_WARN_INFINITE_RECURSION = YES; 287 | CLANG_WARN_INT_CONVERSION = YES; 288 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 289 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 290 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 291 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 292 | CLANG_WARN_STRICT_PROTOTYPES = YES; 293 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 294 | CLANG_WARN_UNREACHABLE_CODE = YES; 295 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 296 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 297 | COPY_PHASE_STRIP = NO; 298 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 299 | ENABLE_STRICT_OBJC_MSGSEND = YES; 300 | ENABLE_TESTABILITY = YES; 301 | GCC_C_LANGUAGE_STANDARD = gnu99; 302 | GCC_DYNAMIC_NO_PIC = NO; 303 | GCC_NO_COMMON_BLOCKS = YES; 304 | GCC_OPTIMIZATION_LEVEL = 0; 305 | GCC_PREPROCESSOR_DEFINITIONS = ( 306 | "DEBUG=1", 307 | "$(inherited)", 308 | ); 309 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 310 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 311 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 312 | GCC_WARN_UNDECLARED_SELECTOR = YES; 313 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 314 | GCC_WARN_UNUSED_FUNCTION = YES; 315 | GCC_WARN_UNUSED_VARIABLE = YES; 316 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 317 | MTL_ENABLE_DEBUG_INFO = YES; 318 | ONLY_ACTIVE_ARCH = YES; 319 | SDKROOT = iphoneos; 320 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 321 | SWIFT_VERSION = 5.0; 322 | }; 323 | name = Debug; 324 | }; 325 | 878319111B88E21F0062D8D7 /* Release */ = { 326 | isa = XCBuildConfiguration; 327 | buildSettings = { 328 | ALWAYS_SEARCH_USER_PATHS = NO; 329 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 330 | CLANG_CXX_LIBRARY = "libc++"; 331 | CLANG_ENABLE_MODULES = YES; 332 | CLANG_ENABLE_OBJC_ARC = YES; 333 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 334 | CLANG_WARN_BOOL_CONVERSION = YES; 335 | CLANG_WARN_COMMA = YES; 336 | CLANG_WARN_CONSTANT_CONVERSION = YES; 337 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 338 | CLANG_WARN_EMPTY_BODY = YES; 339 | CLANG_WARN_ENUM_CONVERSION = YES; 340 | CLANG_WARN_INFINITE_RECURSION = YES; 341 | CLANG_WARN_INT_CONVERSION = YES; 342 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 343 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 344 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 345 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 346 | CLANG_WARN_STRICT_PROTOTYPES = YES; 347 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 348 | CLANG_WARN_UNREACHABLE_CODE = YES; 349 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 350 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 351 | COPY_PHASE_STRIP = NO; 352 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 353 | ENABLE_NS_ASSERTIONS = NO; 354 | ENABLE_STRICT_OBJC_MSGSEND = YES; 355 | GCC_C_LANGUAGE_STANDARD = gnu99; 356 | GCC_NO_COMMON_BLOCKS = YES; 357 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 358 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 359 | GCC_WARN_UNDECLARED_SELECTOR = YES; 360 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 361 | GCC_WARN_UNUSED_FUNCTION = YES; 362 | GCC_WARN_UNUSED_VARIABLE = YES; 363 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 364 | MTL_ENABLE_DEBUG_INFO = NO; 365 | SDKROOT = iphoneos; 366 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 367 | SWIFT_VERSION = 5.0; 368 | VALIDATE_PRODUCT = YES; 369 | }; 370 | name = Release; 371 | }; 372 | 878319131B88E21F0062D8D7 /* Debug */ = { 373 | isa = XCBuildConfiguration; 374 | buildSettings = { 375 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 376 | DEVELOPMENT_TEAM = ""; 377 | INFOPLIST_FILE = DoneHUD/Info.plist; 378 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 379 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 380 | PRODUCT_BUNDLE_IDENTIFIER = "jp.blk.$(PRODUCT_NAME:rfc1034identifier)"; 381 | PRODUCT_NAME = "$(TARGET_NAME)"; 382 | SWIFT_VERSION = 5.0; 383 | }; 384 | name = Debug; 385 | }; 386 | 878319141B88E21F0062D8D7 /* Release */ = { 387 | isa = XCBuildConfiguration; 388 | buildSettings = { 389 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 390 | DEVELOPMENT_TEAM = ""; 391 | INFOPLIST_FILE = DoneHUD/Info.plist; 392 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 393 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 394 | PRODUCT_BUNDLE_IDENTIFIER = "jp.blk.$(PRODUCT_NAME:rfc1034identifier)"; 395 | PRODUCT_NAME = "$(TARGET_NAME)"; 396 | SWIFT_VERSION = 5.0; 397 | }; 398 | name = Release; 399 | }; 400 | 878319161B88E21F0062D8D7 /* Debug */ = { 401 | isa = XCBuildConfiguration; 402 | buildSettings = { 403 | BUNDLE_LOADER = "$(TEST_HOST)"; 404 | FRAMEWORK_SEARCH_PATHS = ( 405 | "$(SDKROOT)/Developer/Library/Frameworks", 406 | "$(inherited)", 407 | ); 408 | GCC_PREPROCESSOR_DEFINITIONS = ( 409 | "DEBUG=1", 410 | "$(inherited)", 411 | ); 412 | INFOPLIST_FILE = DoneHUDTests/Info.plist; 413 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 414 | PRODUCT_BUNDLE_IDENTIFIER = "jp.blk.$(PRODUCT_NAME:rfc1034identifier)"; 415 | PRODUCT_NAME = "$(TARGET_NAME)"; 416 | SWIFT_VERSION = 5.0; 417 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DoneHUD.app/DoneHUD"; 418 | }; 419 | name = Debug; 420 | }; 421 | 878319171B88E21F0062D8D7 /* Release */ = { 422 | isa = XCBuildConfiguration; 423 | buildSettings = { 424 | BUNDLE_LOADER = "$(TEST_HOST)"; 425 | FRAMEWORK_SEARCH_PATHS = ( 426 | "$(SDKROOT)/Developer/Library/Frameworks", 427 | "$(inherited)", 428 | ); 429 | INFOPLIST_FILE = DoneHUDTests/Info.plist; 430 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 431 | PRODUCT_BUNDLE_IDENTIFIER = "jp.blk.$(PRODUCT_NAME:rfc1034identifier)"; 432 | PRODUCT_NAME = "$(TARGET_NAME)"; 433 | SWIFT_VERSION = 5.0; 434 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DoneHUD.app/DoneHUD"; 435 | }; 436 | name = Release; 437 | }; 438 | /* End XCBuildConfiguration section */ 439 | 440 | /* Begin XCConfigurationList section */ 441 | 878318EE1B88E21E0062D8D7 /* Build configuration list for PBXProject "DoneHUD" */ = { 442 | isa = XCConfigurationList; 443 | buildConfigurations = ( 444 | 878319101B88E21F0062D8D7 /* Debug */, 445 | 878319111B88E21F0062D8D7 /* Release */, 446 | ); 447 | defaultConfigurationIsVisible = 0; 448 | defaultConfigurationName = Release; 449 | }; 450 | 878319121B88E21F0062D8D7 /* Build configuration list for PBXNativeTarget "DoneHUD" */ = { 451 | isa = XCConfigurationList; 452 | buildConfigurations = ( 453 | 878319131B88E21F0062D8D7 /* Debug */, 454 | 878319141B88E21F0062D8D7 /* Release */, 455 | ); 456 | defaultConfigurationIsVisible = 0; 457 | defaultConfigurationName = Release; 458 | }; 459 | 878319151B88E21F0062D8D7 /* Build configuration list for PBXNativeTarget "DoneHUDTests" */ = { 460 | isa = XCConfigurationList; 461 | buildConfigurations = ( 462 | 878319161B88E21F0062D8D7 /* Debug */, 463 | 878319171B88E21F0062D8D7 /* Release */, 464 | ); 465 | defaultConfigurationIsVisible = 0; 466 | defaultConfigurationName = Release; 467 | }; 468 | /* End XCConfigurationList section */ 469 | }; 470 | rootObject = 878318EB1B88E21E0062D8D7 /* Project object */; 471 | } 472 | -------------------------------------------------------------------------------- /DoneHUD.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DoneHUD.xcodeproj/project.xcworkspace/xcshareddata/DoneHUD.xcscmblueprint: -------------------------------------------------------------------------------- 1 | { 2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "A28881E26623F05F7FB79A245DF9B6B2334C17C3", 3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { 4 | 5 | }, 6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { 7 | "A28881E26623F05F7FB79A245DF9B6B2334C17C3" : 9223372036854775807, 8 | "BD6B3C3C273361C3A5F0C96A267A9369818B0FBD" : 9223372036854775807 9 | }, 10 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "4E486D1F-CAF1-4915-AE42-0BDDEFCCFE1B", 11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { 12 | "A28881E26623F05F7FB79A245DF9B6B2334C17C3" : "DoneHUD\/", 13 | "BD6B3C3C273361C3A5F0C96A267A9369818B0FBD" : "" 14 | }, 15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "DoneHUD", 16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204, 17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "DoneHUD.xcodeproj", 18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ 19 | { 20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/salmankhann\/DoneHUD.git", 21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "A28881E26623F05F7FB79A245DF9B6B2334C17C3" 23 | }, 24 | { 25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/chemjournal.visualstudio.com\/DefaultCollection\/Octup\/_git\/iOS", 26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "BD6B3C3C273361C3A5F0C96A267A9369818B0FBD" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /DoneHUD.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /DoneHUD.xcodeproj/project.xcworkspace/xcuserdata/a13004.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beryu/DoneHUD/c595acf0123e11d5b74d84d41aa2e6de276156e4/DoneHUD.xcodeproj/project.xcworkspace/xcuserdata/a13004.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /DoneHUD.xcodeproj/project.xcworkspace/xcuserdata/salmanhasratkhan.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beryu/DoneHUD/c595acf0123e11d5b74d84d41aa2e6de276156e4/DoneHUD.xcodeproj/project.xcworkspace/xcuserdata/salmanhasratkhan.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /DoneHUD/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // DoneHUD 4 | // 5 | // Created by Ryuta Kibe on 2015/08/23. 6 | // Copyright (c) 2015年 blk. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | } 17 | 18 | -------------------------------------------------------------------------------- /DoneHUD/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 | -------------------------------------------------------------------------------- /DoneHUD/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 32 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /DoneHUD/DoneHUD.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DoneHUD.swift 3 | // DoneHUD 4 | // 5 | // Created by Ryuta Kibe on 2015/08/23. 6 | // Copyright (c) 2015 blk. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class DoneHUD: NSObject { 12 | fileprivate static let sharedObject = DoneHUD() 13 | let doneView = DoneView() 14 | 15 | public static func showInView(_ view: UIView) { 16 | DoneHUD.sharedObject.showInView(view, message: nil) 17 | } 18 | 19 | public static func showInView(_ view: UIView, message: String?) { 20 | DoneHUD.sharedObject.showInView(view, message: message) 21 | } 22 | 23 | fileprivate func showInView(_ view: UIView, message: String?) { 24 | // Set size of done view 25 | let doneViewWidth = min(view.frame.width, view.frame.height) / 2 26 | var originX: CGFloat, originY: CGFloat 27 | if (UIDevice.current.systemVersion as NSString).floatValue >= 8.0 { 28 | originX = (view.frame.width - doneViewWidth) / 2 29 | originY = (view.frame.height - doneViewWidth) / 2 30 | } else { 31 | let isLandscape = UIDevice.current.orientation.isLandscape 32 | originX = ((isLandscape ? view.frame.height : view.frame.width) - doneViewWidth) / 2 33 | originY = ((isLandscape ? view.frame.width : view.frame.height) - doneViewWidth) / 2 34 | } 35 | let doneViewFrame = CGRect( 36 | x: originX, 37 | y: originY, 38 | width: doneViewWidth, 39 | height: doneViewWidth) 40 | self.doneView.layer.cornerRadius = 8 41 | self.doneView.frame = doneViewFrame 42 | 43 | // Set message 44 | self.doneView.setMessage(message) 45 | 46 | // Start animation 47 | self.doneView.alpha = 0 48 | view.addSubview(self.doneView) 49 | UIView.animate(withDuration: 0.2, animations: { () -> Void in 50 | self.doneView.alpha = 1 51 | }, completion: { (result: Bool) -> Void in 52 | self.doneView.drawCheck({ () -> Void in 53 | let delayTime = DispatchTime.now() + Double(Int64(0.5 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC) 54 | DispatchQueue.main.asyncAfter(deadline: delayTime) { 55 | UIView.animate(withDuration: 0.2, animations: { () -> Void in 56 | self.doneView.alpha = 0 57 | }, completion: { (result: Bool) -> Void in 58 | self.doneView.removeFromSuperview() 59 | self.doneView.clear() 60 | }) 61 | } 62 | }) 63 | }) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /DoneHUD/DoneView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DoneView.swift 3 | // DoneHUD 4 | // 5 | // Created by Ryuta Kibe on 2015/08/22. 6 | // Copyright (c) 2015 blk. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class DoneView: UIView { 12 | 13 | // MARK: - private variables 14 | 15 | fileprivate let lineLayer: CAShapeLayer = CAShapeLayer() 16 | fileprivate var message: String? = nil 17 | fileprivate var messageLabel: UILabel? = nil 18 | fileprivate var blurView: UIView? = nil 19 | 20 | // MARK: - public methods 21 | 22 | public init() { 23 | super.init(frame: CGRect.zero) 24 | self.initialize() 25 | } 26 | 27 | public override init(frame: CGRect) { 28 | super.init(frame: frame) 29 | self.initialize() 30 | } 31 | 32 | public required init?(coder aDecoder: NSCoder) { 33 | super.init(coder: aDecoder) 34 | self.initialize() 35 | } 36 | 37 | open func setMessage(_ message: String?) { 38 | self.message = message 39 | if let message = self.message { 40 | if self.messageLabel == nil { 41 | let messageLabel = UILabel() 42 | self.messageLabel = messageLabel 43 | messageLabel.numberOfLines = 1 44 | messageLabel.textAlignment = .center 45 | messageLabel.lineBreakMode = .byTruncatingTail 46 | messageLabel.textColor = UIColor.black 47 | self.addSubview(messageLabel) 48 | } 49 | if let messageLabel = self.messageLabel { 50 | messageLabel.text = message 51 | messageLabel.frame = CGRect( 52 | x: 8, 53 | y: self.frame.height / 5 * 4 - 10, 54 | width: self.frame.width - 16, 55 | height: 20) 56 | } 57 | } 58 | } 59 | 60 | open func drawCheck(_ completion: (() -> Void)?) { 61 | let canvasFrame = CGRect( 62 | x: self.frame.width / 4, 63 | y: message == nil ? self.frame.height / 3 : self.frame.height / 5 * 2, 64 | width: self.frame.width / 2, 65 | height: self.frame.height / 3) 66 | let path = UIBezierPath() 67 | path.move( 68 | to: CGPoint(x: canvasFrame.origin.x, y: canvasFrame.origin.y + canvasFrame.height / 2)) 69 | path.addLine( 70 | to: CGPoint(x: canvasFrame.origin.x + canvasFrame.width / 3, y: canvasFrame.origin.y)) 71 | path.addLine( 72 | to: CGPoint(x: canvasFrame.origin.x + canvasFrame.width, y: canvasFrame.origin.y + canvasFrame.height)) 73 | self.lineLayer.frame = self.bounds 74 | self.lineLayer.isGeometryFlipped = true 75 | self.lineLayer.path = path.cgPath 76 | 77 | self.layer.addSublayer(self.lineLayer) 78 | self.animate(completion) 79 | } 80 | 81 | open func clear() { 82 | self.lineLayer.removeFromSuperlayer() 83 | self.lineLayer.removeAllAnimations() 84 | self.lineLayer.path = nil 85 | 86 | self.messageLabel?.removeFromSuperview() 87 | self.messageLabel = nil 88 | self.message = nil 89 | } 90 | 91 | override open func layoutSubviews() { 92 | super.layoutSubviews() 93 | self.blurView?.frame = self.bounds 94 | } 95 | 96 | // MARK: - private methods 97 | 98 | fileprivate func initialize() { 99 | // Initialize properties 100 | self.clipsToBounds = true 101 | 102 | // Set default setting to line 103 | self.lineLayer.fillColor = UIColor.clear.cgColor 104 | self.lineLayer.anchorPoint = CGPoint(x: 0, y: 0) 105 | self.lineLayer.lineJoin = .round 106 | self.lineLayer.lineCap = .round 107 | self.lineLayer.contentsScale = self.layer.contentsScale 108 | self.lineLayer.lineWidth = 8 109 | self.lineLayer.strokeColor = UIColor.black.cgColor 110 | 111 | // Generate blur view 112 | var blurView: UIView 113 | if #available(iOS 8.0, *) { 114 | blurView = UIVisualEffectView(effect: UIBlurEffect(style: .extraLight)) 115 | } else { 116 | blurView = UIView() 117 | blurView.backgroundColor = UIColor(white: 1, alpha: 0.8) 118 | } 119 | self.blurView = blurView 120 | self.insertSubview(blurView, at: 0) 121 | blurView.frame = self.bounds 122 | } 123 | 124 | fileprivate func animate(_ completion: (() -> Void)?) { 125 | let pathAnimation = CABasicAnimation(keyPath: "strokeEnd") 126 | pathAnimation.duration = 0.2 127 | pathAnimation.fromValue = NSNumber(value: 0 as Float) 128 | pathAnimation.toValue = NSNumber(value: 1 as Float) 129 | CATransaction.begin() 130 | if let completion = completion { 131 | CATransaction.setCompletionBlock(completion) 132 | } 133 | self.lineLayer.add(pathAnimation, forKey:"strokeEndAnimation") 134 | CATransaction.commit() 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /DoneHUD/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 | } -------------------------------------------------------------------------------- /DoneHUD/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 | -------------------------------------------------------------------------------- /DoneHUD/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // DoneHUD 4 | // 5 | // Created by Ryuta Kibe on 2015/08/22. 6 | // Copyright (c) 2015年 blk. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | @IBAction func showButtonWasTapped() { 14 | DoneHUD.showInView(self.view) 15 | } 16 | 17 | @IBAction func showWithMessageButtonWasTapped() { 18 | DoneHUD.showInView(self.view, message: "Done") 19 | } 20 | 21 | override var preferredStatusBarStyle : UIStatusBarStyle { 22 | return .lightContent 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /DoneHUDTests/DoneHUDTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DoneHUDTests.swift 3 | // DoneHUDTests 4 | // 5 | // Created by Ryuta Kibe on 2015/08/23. 6 | // Copyright (c) 2015年 blk. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class DoneHUDTests: 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 | -------------------------------------------------------------------------------- /DoneHUDTests/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 | -------------------------------------------------------------------------------- /DoneHUD_demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beryu/DoneHUD/c595acf0123e11d5b74d84d41aa2e6de276156e4/DoneHUD_demo.gif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Ryuta Kibe (beryu@blk.jp) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DoneHUD 2 | ![Platform](https://cocoapod-badges.herokuapp.com/p/DoneHUD/badge.svg) 3 | ![License](https://img.shields.io/cocoapods/l/DoneHUD.svg?style=flat) 4 | ![CocoaPods](https://cocoapod-badges.herokuapp.com/v/DoneHUD/badge.svg) 5 | 6 | Done animation on HUD made with Swift 7 | 8 | ![demo](DoneHUD_demo.gif) 9 | 10 | ## Installation 11 | 12 | ### CocoaPods 13 | 14 | ```ruby 15 | pod 'DoneHUD' 16 | ``` 17 | 18 | ### Manually 19 | 20 | Add the [DoneHUD.swift](https://github.com/beryu/DoneHUD/blob/master/Source/DoneHUD.swift) and [DoneView.swift](https://github.com/beryu/DoneHUD/blob/master/Source/DoneView.swift) file to your project. 21 | 22 | ## Usage 23 | ```swift 24 | // Just show check animation 25 | DoneHUD.showInView(view) 26 | ``` 27 | 28 | ```swift 29 | // Show check animation with message "Done" 30 | DoneHUD.showInView(view, message: "Done") 31 | ``` 32 | 33 | ## Requirements 34 | * Swift 5.0 35 | * iOS 8.0 36 | * ARC 37 | 38 | If you want to use even iOS7.0, please to import the code directly. 39 | 40 | ## License 41 | The MIT License (MIT) 42 | 43 | Copyright (c) 2017 Ryuta Kibe (beryu@blk.jp) 44 | 45 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 46 | 47 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 48 | 49 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 50 | -------------------------------------------------------------------------------- /Source/DoneHUD.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DoneHUD.swift 3 | // DoneHUD 4 | // 5 | // Created by Ryuta Kibe on 2015/08/23. 6 | // Copyright (c) 2015 blk. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class DoneHUD: NSObject { 12 | fileprivate static let sharedObject = DoneHUD() 13 | let doneView = DoneView() 14 | 15 | public static func showInView(_ view: UIView) { 16 | DoneHUD.sharedObject.showInView(view, message: nil) 17 | } 18 | 19 | public static func showInView(_ view: UIView, message: String?) { 20 | DoneHUD.sharedObject.showInView(view, message: message) 21 | } 22 | 23 | fileprivate func showInView(_ view: UIView, message: String?) { 24 | // Set size of done view 25 | let doneViewWidth = min(view.frame.width, view.frame.height) / 2 26 | var originX: CGFloat, originY: CGFloat 27 | if (UIDevice.current.systemVersion as NSString).floatValue >= 8.0 { 28 | originX = (view.frame.width - doneViewWidth) / 2 29 | originY = (view.frame.height - doneViewWidth) / 2 30 | } else { 31 | let isLandscape = UIDevice.current.orientation.isLandscape 32 | originX = ((isLandscape ? view.frame.height : view.frame.width) - doneViewWidth) / 2 33 | originY = ((isLandscape ? view.frame.width : view.frame.height) - doneViewWidth) / 2 34 | } 35 | let doneViewFrame = CGRect( 36 | x: originX, 37 | y: originY, 38 | width: doneViewWidth, 39 | height: doneViewWidth) 40 | self.doneView.layer.cornerRadius = 8 41 | self.doneView.frame = doneViewFrame 42 | 43 | // Set message 44 | self.doneView.setMessage(message) 45 | 46 | // Start animation 47 | self.doneView.alpha = 0 48 | view.addSubview(self.doneView) 49 | UIView.animate(withDuration: 0.2, animations: { () -> Void in 50 | self.doneView.alpha = 1 51 | }, completion: { (result: Bool) -> Void in 52 | self.doneView.drawCheck({ () -> Void in 53 | let delayTime = DispatchTime.now() + Double(Int64(0.5 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC) 54 | DispatchQueue.main.asyncAfter(deadline: delayTime) { 55 | UIView.animate(withDuration: 0.2, animations: { () -> Void in 56 | self.doneView.alpha = 0 57 | }, completion: { (result: Bool) -> Void in 58 | self.doneView.removeFromSuperview() 59 | self.doneView.clear() 60 | }) 61 | } 62 | }) 63 | }) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Source/DoneView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DoneView.swift 3 | // DoneHUD 4 | // 5 | // Created by Ryuta Kibe on 2015/08/22. 6 | // Copyright (c) 2015 blk. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | open class DoneView: UIView { 12 | 13 | // MARK: - private variables 14 | 15 | fileprivate let lineLayer: CAShapeLayer = CAShapeLayer() 16 | fileprivate var message: String? = nil 17 | fileprivate var messageLabel: UILabel? = nil 18 | fileprivate var blurView: UIView? = nil 19 | 20 | // MARK: - public methods 21 | 22 | public init() { 23 | super.init(frame: CGRect.zero) 24 | self.initialize() 25 | } 26 | 27 | public override init(frame: CGRect) { 28 | super.init(frame: frame) 29 | self.initialize() 30 | } 31 | 32 | public required init?(coder aDecoder: NSCoder) { 33 | super.init(coder: aDecoder) 34 | self.initialize() 35 | } 36 | 37 | open func setMessage(_ message: String?) { 38 | self.message = message 39 | if let message = self.message { 40 | if self.messageLabel == nil { 41 | let messageLabel = UILabel() 42 | self.messageLabel = messageLabel 43 | messageLabel.numberOfLines = 1 44 | messageLabel.textAlignment = .center 45 | messageLabel.lineBreakMode = .byTruncatingTail 46 | messageLabel.textColor = UIColor.black 47 | self.addSubview(messageLabel) 48 | } 49 | if let messageLabel = self.messageLabel { 50 | messageLabel.text = message 51 | messageLabel.frame = CGRect( 52 | x: 8, 53 | y: self.frame.height / 5 * 4 - 10, 54 | width: self.frame.width - 16, 55 | height: 20) 56 | } 57 | } 58 | } 59 | 60 | open func drawCheck(_ completion: (() -> Void)?) { 61 | let canvasFrame = CGRect( 62 | x: self.frame.width / 4, 63 | y: message == nil ? self.frame.height / 3 : self.frame.height / 5 * 2, 64 | width: self.frame.width / 2, 65 | height: self.frame.height / 3) 66 | let path = UIBezierPath() 67 | path.move( 68 | to: CGPoint(x: canvasFrame.origin.x, y: canvasFrame.origin.y + canvasFrame.height / 2)) 69 | path.addLine( 70 | to: CGPoint(x: canvasFrame.origin.x + canvasFrame.width / 3, y: canvasFrame.origin.y)) 71 | path.addLine( 72 | to: CGPoint(x: canvasFrame.origin.x + canvasFrame.width, y: canvasFrame.origin.y + canvasFrame.height)) 73 | self.lineLayer.frame = self.bounds 74 | self.lineLayer.isGeometryFlipped = true 75 | self.lineLayer.path = path.cgPath 76 | 77 | self.layer.addSublayer(self.lineLayer) 78 | self.animate(completion) 79 | } 80 | 81 | open func clear() { 82 | self.lineLayer.removeFromSuperlayer() 83 | self.lineLayer.removeAllAnimations() 84 | self.lineLayer.path = nil 85 | 86 | self.messageLabel?.removeFromSuperview() 87 | self.messageLabel = nil 88 | self.message = nil 89 | } 90 | 91 | override open func layoutSubviews() { 92 | super.layoutSubviews() 93 | self.blurView?.frame = self.bounds 94 | } 95 | 96 | // MARK: - private methods 97 | 98 | fileprivate func initialize() { 99 | // Initialize properties 100 | self.clipsToBounds = true 101 | 102 | // Set default setting to line 103 | self.lineLayer.fillColor = UIColor.clear.cgColor 104 | self.lineLayer.anchorPoint = CGPoint(x: 0, y: 0) 105 | self.lineLayer.lineJoin = .round 106 | self.lineLayer.lineCap = .round 107 | self.lineLayer.contentsScale = self.layer.contentsScale 108 | self.lineLayer.lineWidth = 8 109 | self.lineLayer.strokeColor = UIColor.black.cgColor 110 | 111 | // Generate blur view 112 | var blurView: UIView 113 | if #available(iOS 8.0, *) { 114 | blurView = UIVisualEffectView(effect: UIBlurEffect(style: .extraLight)) 115 | } else { 116 | blurView = UIView() 117 | blurView.backgroundColor = UIColor(white: 1, alpha: 0.8) 118 | } 119 | self.blurView = blurView 120 | self.insertSubview(blurView, at: 0) 121 | blurView.frame = self.bounds 122 | } 123 | 124 | fileprivate func animate(_ completion: (() -> Void)?) { 125 | let pathAnimation = CABasicAnimation(keyPath: "strokeEnd") 126 | pathAnimation.duration = 0.2 127 | pathAnimation.fromValue = NSNumber(value: 0 as Float) 128 | pathAnimation.toValue = NSNumber(value: 1 as Float) 129 | CATransaction.begin() 130 | if let completion = completion { 131 | CATransaction.setCompletionBlock(completion) 132 | } 133 | self.lineLayer.add(pathAnimation, forKey:"strokeEndAnimation") 134 | CATransaction.commit() 135 | } 136 | } 137 | --------------------------------------------------------------------------------