├── .gitignore ├── Cartfile ├── Cartfile.resolved ├── Carthage ├── Build │ └── iOS │ │ └── PKHUD.framework │ │ ├── Assets.car │ │ ├── Headers │ │ ├── PKHUD-Swift.h │ │ └── PKHUD.h │ │ ├── Info.plist │ │ ├── Modules │ │ ├── PKHUD.swiftmodule │ │ │ ├── arm.swiftdoc │ │ │ ├── arm.swiftmodule │ │ │ ├── arm64.swiftdoc │ │ │ ├── arm64.swiftmodule │ │ │ ├── i386.swiftdoc │ │ │ ├── i386.swiftmodule │ │ │ ├── x86_64.swiftdoc │ │ │ └── x86_64.swiftmodule │ │ └── module.modulemap │ │ └── PKHUD └── Checkouts │ └── PKHUD │ ├── .gitignore │ ├── Carthage │ └── Build │ ├── Demo │ ├── AppDelegate.swift │ ├── DemoViewController.swift │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── LaunchImage.launchimage │ │ │ └── Contents.json │ │ ├── background.imageset │ │ │ ├── Contents.json │ │ │ └── background@2x.png │ │ └── progress.imageset │ │ │ ├── Contents.json │ │ │ └── progress.pdf │ ├── Info.plist │ ├── Launch Screen.storyboard │ └── Storyboard.storyboard │ ├── LICENSE │ ├── PKHUD.podspec │ ├── PKHUD.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── PKHUD.xcscheme │ ├── PKHUD │ ├── FrameView.swift │ ├── HUD.swift │ ├── Images.xcassets │ │ ├── Contents.json │ │ ├── checkmark.imageset │ │ │ ├── Contents.json │ │ │ └── checkmark.pdf │ │ ├── cross.imageset │ │ │ ├── Contents.json │ │ │ └── cross.pdf │ │ ├── progress_activity.imageset │ │ │ ├── Contents.json │ │ │ └── progress.pdf │ │ └── progress_circular.imageset │ │ │ ├── Contents.json │ │ │ └── progress_circular.pdf │ ├── Info.plist │ ├── PKHUD.h │ ├── PKHUD.swift │ ├── PKHUDAnimating.swift │ ├── PKHUDAnimation.swift │ ├── PKHUDAssets.swift │ ├── PKHUDErrorView.swift │ ├── PKHUDProgressView.swift │ ├── PKHUDRotatingImageView.swift │ ├── PKHUDSquareBaseView.swift │ ├── PKHUDSuccessView.swift │ ├── PKHUDSystemActivityIndicatorView.swift │ ├── PKHUDTextView.swift │ ├── PKHUDWideBaseView.swift │ ├── Window.swift │ └── WindowRootViewController.swift │ ├── README.md │ └── README_hero.png ├── Dust.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ ├── Dust.xccheckout │ │ └── Dust.xcscmblueprint │ └── xcuserdata │ │ └── joeblau.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── joeblau.xcuserdatad │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ │ ├── Dust.xcscheme │ │ └── xcschememanagement.plist │ └── josephblau.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── Dust.xcscheme │ └── xcschememanagement.plist ├── Dust ├── AppDelegate.swift ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── CAEmitterLayer.swift ├── Images.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-60@2x.png │ │ ├── Icon-60@3x.png │ │ ├── Icon-76.png │ │ ├── Icon-76@2x.png │ │ ├── Icon-83.5@2x.png │ │ ├── Icon-Small-40@2x-1.png │ │ ├── Icon-Small-40@2x.png │ │ ├── Icon-Small-60.png │ │ ├── Icon-Small-60@2x.png │ │ ├── Icon-Small.png │ │ ├── Icon-Small@2x-1.png │ │ ├── Icon-Small@2x.png │ │ └── Icon-Small@3x.png │ ├── Contents.json │ ├── Dust.imageset │ │ ├── Contents.json │ │ ├── Dust.png │ │ ├── Dust@2x.png │ │ └── Dust@3x.png │ ├── connect.imageset │ │ ├── Contents.json │ │ └── connect.pdf │ ├── disconnect.imageset │ │ ├── Contents.json │ │ └── disconnect.pdf │ ├── double-tap.imageset │ │ ├── Contents.json │ │ └── double-tap.pdf │ ├── free-drag.imageset │ │ ├── Contents.json │ │ └── free-drag.pdf │ └── particle.imageset │ │ ├── Contents.json │ │ ├── particle.png │ │ └── particle@2x.png ├── Info.plist ├── LaunchViewController.swift ├── MeshNetwork.swift └── ViewController.swift ├── DustTests ├── DustTests.swift └── Info.plist ├── LICENSE ├── README.md ├── dustparticles.gif └── gh-assets ├── Assets └── App Icon │ ├── Icon-60@2x.png │ ├── Icon-60@3x.png │ ├── Icon-76.png │ ├── Icon-76@2x.png │ ├── Icon-83.5@2x.png │ ├── Icon-Small-40@2x.png │ ├── Icon-Small-60.png │ ├── Icon-Small-60@2x.png │ ├── Icon-Small-60@3x.png │ ├── Icon-Small.png │ ├── Icon-Small@2x.png │ ├── Icon-Small@3x.png │ ├── iTunesArtwork.png │ └── iTunesArtwork@2x.png ├── double-tap.pdf ├── dust.sketch ├── free-drag.pdf └── github-header.svg /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/swift 3 | 4 | ### Swift ### 5 | # Xcode 6 | # 7 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 8 | 9 | ## Build generated 10 | build/ 11 | DerivedData/ 12 | 13 | ## Various settings 14 | *.pbxuser 15 | !default.pbxuser 16 | *.mode1v3 17 | !default.mode1v3 18 | *.mode2v3 19 | !default.mode2v3 20 | *.perspectivev3 21 | !default.perspectivev3 22 | xcuserdata/ 23 | 24 | ## Other 25 | *.moved-aside 26 | *.xcuserstate 27 | 28 | ## Obj-C/Swift specific 29 | *.hmap 30 | *.ipa 31 | *.dSYM.zip 32 | *.dSYM 33 | 34 | ## Playgrounds 35 | timeline.xctimeline 36 | playground.xcworkspace 37 | 38 | # Swift Package Manager 39 | # 40 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 41 | # Packages/ 42 | .build/ 43 | 44 | # CocoaPods 45 | # 46 | # We recommend against adding the Pods directory to your .gitignore. However 47 | # you should judge for yourself, the pros and cons are mentioned at: 48 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 49 | # 50 | # Pods/ 51 | 52 | # Carthage 53 | # 54 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 55 | # Carthage/Checkouts 56 | 57 | Carthage/Build 58 | 59 | # fastlane 60 | # 61 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 62 | # screenshots whenever they are needed. 63 | # For more information about the recommended setup visit: 64 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 65 | 66 | fastlane/report.xml 67 | fastlane/Preview.html 68 | fastlane/screenshots 69 | fastlane/test_output 70 | -------------------------------------------------------------------------------- /Cartfile: -------------------------------------------------------------------------------- 1 | github "pkluz/PKHUD" ~> 4.0 2 | -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "pkluz/PKHUD" "4.1.0" 2 | -------------------------------------------------------------------------------- /Carthage/Build/iOS/PKHUD.framework/Assets.car: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Build/iOS/PKHUD.framework/Assets.car -------------------------------------------------------------------------------- /Carthage/Build/iOS/PKHUD.framework/Headers/PKHUD-Swift.h: -------------------------------------------------------------------------------- 1 | // Generated by Apple Swift version 3.0.1 (swiftlang-800.0.58.6 clang-800.0.42.1) 2 | #pragma clang diagnostic push 3 | 4 | #if defined(__has_include) && __has_include() 5 | # include 6 | #endif 7 | 8 | #pragma clang diagnostic ignored "-Wauto-import" 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #if !defined(SWIFT_TYPEDEFS) 15 | # define SWIFT_TYPEDEFS 1 16 | # if defined(__has_include) && __has_include() 17 | # include 18 | # elif !defined(__cplusplus) || __cplusplus < 201103L 19 | typedef uint_least16_t char16_t; 20 | typedef uint_least32_t char32_t; 21 | # endif 22 | typedef float swift_float2 __attribute__((__ext_vector_type__(2))); 23 | typedef float swift_float3 __attribute__((__ext_vector_type__(3))); 24 | typedef float swift_float4 __attribute__((__ext_vector_type__(4))); 25 | typedef double swift_double2 __attribute__((__ext_vector_type__(2))); 26 | typedef double swift_double3 __attribute__((__ext_vector_type__(3))); 27 | typedef double swift_double4 __attribute__((__ext_vector_type__(4))); 28 | typedef int swift_int2 __attribute__((__ext_vector_type__(2))); 29 | typedef int swift_int3 __attribute__((__ext_vector_type__(3))); 30 | typedef int swift_int4 __attribute__((__ext_vector_type__(4))); 31 | typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2))); 32 | typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3))); 33 | typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); 34 | #endif 35 | 36 | #if !defined(SWIFT_PASTE) 37 | # define SWIFT_PASTE_HELPER(x, y) x##y 38 | # define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y) 39 | #endif 40 | #if !defined(SWIFT_METATYPE) 41 | # define SWIFT_METATYPE(X) Class 42 | #endif 43 | #if !defined(SWIFT_CLASS_PROPERTY) 44 | # if __has_feature(objc_class_property) 45 | # define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__ 46 | # else 47 | # define SWIFT_CLASS_PROPERTY(...) 48 | # endif 49 | #endif 50 | 51 | #if defined(__has_attribute) && __has_attribute(objc_runtime_name) 52 | # define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X))) 53 | #else 54 | # define SWIFT_RUNTIME_NAME(X) 55 | #endif 56 | #if defined(__has_attribute) && __has_attribute(swift_name) 57 | # define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X))) 58 | #else 59 | # define SWIFT_COMPILE_NAME(X) 60 | #endif 61 | #if defined(__has_attribute) && __has_attribute(objc_method_family) 62 | # define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X))) 63 | #else 64 | # define SWIFT_METHOD_FAMILY(X) 65 | #endif 66 | #if defined(__has_attribute) && __has_attribute(noescape) 67 | # define SWIFT_NOESCAPE __attribute__((noescape)) 68 | #else 69 | # define SWIFT_NOESCAPE 70 | #endif 71 | #if !defined(SWIFT_CLASS_EXTRA) 72 | # define SWIFT_CLASS_EXTRA 73 | #endif 74 | #if !defined(SWIFT_PROTOCOL_EXTRA) 75 | # define SWIFT_PROTOCOL_EXTRA 76 | #endif 77 | #if !defined(SWIFT_ENUM_EXTRA) 78 | # define SWIFT_ENUM_EXTRA 79 | #endif 80 | #if !defined(SWIFT_CLASS) 81 | # if defined(__has_attribute) && __has_attribute(objc_subclassing_restricted) 82 | # define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA 83 | # define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA 84 | # else 85 | # define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA 86 | # define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA 87 | # endif 88 | #endif 89 | 90 | #if !defined(SWIFT_PROTOCOL) 91 | # define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA 92 | # define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA 93 | #endif 94 | 95 | #if !defined(SWIFT_EXTENSION) 96 | # define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__) 97 | #endif 98 | 99 | #if !defined(OBJC_DESIGNATED_INITIALIZER) 100 | # if defined(__has_attribute) && __has_attribute(objc_designated_initializer) 101 | # define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) 102 | # else 103 | # define OBJC_DESIGNATED_INITIALIZER 104 | # endif 105 | #endif 106 | #if !defined(SWIFT_ENUM) 107 | # define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum SWIFT_ENUM_EXTRA _name : _type 108 | # if defined(__has_feature) && __has_feature(generalized_swift_name) 109 | # define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_EXTRA _name : _type 110 | # else 111 | # define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) SWIFT_ENUM(_type, _name) 112 | # endif 113 | #endif 114 | #if !defined(SWIFT_UNAVAILABLE) 115 | # define SWIFT_UNAVAILABLE __attribute__((unavailable)) 116 | #endif 117 | #if defined(__has_feature) && __has_feature(modules) 118 | @import ObjectiveC; 119 | @import Foundation; 120 | @import UIKit; 121 | @import CoreGraphics; 122 | #endif 123 | 124 | #pragma clang diagnostic ignored "-Wproperty-attribute-mismatch" 125 | #pragma clang diagnostic ignored "-Wduplicate-method-arg" 126 | @class UIView; 127 | @class UIVisualEffect; 128 | 129 | /** 130 | The PKHUD object controls showing and hiding of the HUD, as well as its contents and touch response behavior. 131 | */ 132 | SWIFT_CLASS("_TtC5PKHUD5PKHUD") 133 | @interface PKHUD : NSObject 134 | @property (nonatomic, strong) UIView * _Nullable viewToPresentOn; 135 | SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, strong) PKHUD * _Nonnull sharedHUD;) 136 | + (PKHUD * _Nonnull)sharedHUD; 137 | - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER; 138 | - (nonnull instancetype)initWithViewToPresentOn:(UIView * _Nonnull)view; 139 | @property (nonatomic) BOOL dimsBackground; 140 | @property (nonatomic) BOOL userInteractionOnUnderlyingViewsEnabled; 141 | @property (nonatomic, readonly) BOOL isVisible; 142 | @property (nonatomic, strong) UIView * _Nonnull contentView; 143 | @property (nonatomic, strong) UIVisualEffect * _Nullable effect; 144 | - (void)showOnView:(UIView * _Nullable)view; 145 | - (void)hideWithAnimated:(BOOL)anim completion:(void (^ _Nullable)(BOOL))completion; 146 | - (void)hide:(BOOL)animated completion:(void (^ _Nullable)(BOOL))completion; 147 | - (void)hideAfterDelay:(NSTimeInterval)delay completion:(void (^ _Nullable)(BOOL))completion; 148 | @end 149 | 150 | @class UIImage; 151 | 152 | /** 153 | PKHUDAssets provides a set of default images, that can be supplied to the PKHUD’s content views. 154 | */ 155 | SWIFT_CLASS("_TtC5PKHUD11PKHUDAssets") 156 | @interface PKHUDAssets : NSObject 157 | SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, strong) UIImage * _Nonnull crossImage;) 158 | + (UIImage * _Nonnull)crossImage; 159 | SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, strong) UIImage * _Nonnull checkmarkImage;) 160 | + (UIImage * _Nonnull)checkmarkImage; 161 | SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, strong) UIImage * _Nonnull progressActivityImage;) 162 | + (UIImage * _Nonnull)progressActivityImage; 163 | SWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, strong) UIImage * _Nonnull progressCircularImage;) 164 | + (UIImage * _Nonnull)progressCircularImage; 165 | - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER; 166 | @end 167 | 168 | @class NSCoder; 169 | @class UIImageView; 170 | @class UILabel; 171 | 172 | /** 173 | PKHUDSquareBaseView provides a square view, which you can subclass and add additional views to. 174 | */ 175 | SWIFT_CLASS("_TtC5PKHUD19PKHUDSquareBaseView") 176 | @interface PKHUDSquareBaseView : UIView 177 | - (nonnull instancetype)initWithFrame:(CGRect)frame OBJC_DESIGNATED_INITIALIZER; 178 | - (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER; 179 | - (nonnull instancetype)initWithImage:(UIImage * _Nullable)image title:(NSString * _Nullable)title subtitle:(NSString * _Nullable)subtitle OBJC_DESIGNATED_INITIALIZER; 180 | @property (nonatomic, readonly, strong) UIImageView * _Nonnull imageView; 181 | @property (nonatomic, readonly, strong) UILabel * _Nonnull titleLabel; 182 | @property (nonatomic, readonly, strong) UILabel * _Nonnull subtitleLabel; 183 | - (void)layoutSubviews; 184 | @end 185 | 186 | 187 | /** 188 | PKHUDErrorView provides an animated error (cross) view. 189 | */ 190 | SWIFT_CLASS("_TtC5PKHUD14PKHUDErrorView") 191 | @interface PKHUDErrorView : PKHUDSquareBaseView 192 | - (nonnull instancetype)initWithTitle:(NSString * _Nullable)title subtitle:(NSString * _Nullable)subtitle OBJC_DESIGNATED_INITIALIZER; 193 | - (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER; 194 | - (nonnull instancetype)initWithFrame:(CGRect)frame SWIFT_UNAVAILABLE; 195 | - (nonnull instancetype)initWithImage:(UIImage * _Nullable)image title:(NSString * _Nullable)title subtitle:(NSString * _Nullable)subtitle SWIFT_UNAVAILABLE; 196 | @end 197 | 198 | 199 | /** 200 | PKHUDProgressView provides an indeterminate progress view. 201 | */ 202 | SWIFT_CLASS("_TtC5PKHUD17PKHUDProgressView") 203 | @interface PKHUDProgressView : PKHUDSquareBaseView 204 | - (nonnull instancetype)initWithTitle:(NSString * _Nullable)title subtitle:(NSString * _Nullable)subtitle OBJC_DESIGNATED_INITIALIZER; 205 | - (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER; 206 | - (nonnull instancetype)initWithFrame:(CGRect)frame SWIFT_UNAVAILABLE; 207 | - (nonnull instancetype)initWithImage:(UIImage * _Nullable)image title:(NSString * _Nullable)title subtitle:(NSString * _Nullable)subtitle SWIFT_UNAVAILABLE; 208 | @end 209 | 210 | 211 | /** 212 | PKHUDRotatingImageView provides a content view that rotates the supplies image automatically. 213 | */ 214 | SWIFT_CLASS("_TtC5PKHUD22PKHUDRotatingImageView") 215 | @interface PKHUDRotatingImageView : PKHUDSquareBaseView 216 | - (nonnull instancetype)initWithFrame:(CGRect)frame OBJC_DESIGNATED_INITIALIZER; 217 | - (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER; 218 | - (nonnull instancetype)initWithImage:(UIImage * _Nullable)image title:(NSString * _Nullable)title subtitle:(NSString * _Nullable)subtitle OBJC_DESIGNATED_INITIALIZER; 219 | @end 220 | 221 | 222 | 223 | /** 224 | PKHUDCheckmarkView provides an animated success (checkmark) view. 225 | */ 226 | SWIFT_CLASS("_TtC5PKHUD16PKHUDSuccessView") 227 | @interface PKHUDSuccessView : PKHUDSquareBaseView 228 | - (nonnull instancetype)initWithTitle:(NSString * _Nullable)title subtitle:(NSString * _Nullable)subtitle OBJC_DESIGNATED_INITIALIZER; 229 | - (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER; 230 | - (void)startAnimation; 231 | - (void)stopAnimation; 232 | - (nonnull instancetype)initWithFrame:(CGRect)frame SWIFT_UNAVAILABLE; 233 | - (nonnull instancetype)initWithImage:(UIImage * _Nullable)image title:(NSString * _Nullable)title subtitle:(NSString * _Nullable)subtitle SWIFT_UNAVAILABLE; 234 | @end 235 | 236 | 237 | /** 238 | PKHUDSystemActivityIndicatorView provides the system UIActivityIndicatorView as an alternative. 239 | */ 240 | SWIFT_CLASS("_TtC5PKHUD32PKHUDSystemActivityIndicatorView") 241 | @interface PKHUDSystemActivityIndicatorView : PKHUDSquareBaseView 242 | - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER; 243 | - (nonnull instancetype)initWithFrame:(CGRect)frame OBJC_DESIGNATED_INITIALIZER; 244 | - (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER; 245 | - (void)layoutSubviews; 246 | - (nonnull instancetype)initWithImage:(UIImage * _Nullable)image title:(NSString * _Nullable)title subtitle:(NSString * _Nullable)subtitle SWIFT_UNAVAILABLE; 247 | @end 248 | 249 | 250 | /** 251 | PKHUDWideBaseView provides a wide base view, which you can subclass and add additional views to. 252 | */ 253 | SWIFT_CLASS("_TtC5PKHUD17PKHUDWideBaseView") 254 | @interface PKHUDWideBaseView : UIView 255 | - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER; 256 | - (nonnull instancetype)initWithFrame:(CGRect)frame OBJC_DESIGNATED_INITIALIZER; 257 | - (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER; 258 | @end 259 | 260 | 261 | /** 262 | PKHUDTextView provides a wide, three line text view, which you can use to display information. 263 | */ 264 | SWIFT_CLASS("_TtC5PKHUD13PKHUDTextView") 265 | @interface PKHUDTextView : PKHUDWideBaseView 266 | - (nonnull instancetype)initWithText:(NSString * _Nullable)text OBJC_DESIGNATED_INITIALIZER; 267 | - (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER; 268 | - (void)layoutSubviews; 269 | @property (nonatomic, readonly, strong) UILabel * _Nonnull titleLabel; 270 | - (nonnull instancetype)init SWIFT_UNAVAILABLE; 271 | - (nonnull instancetype)initWithFrame:(CGRect)frame SWIFT_UNAVAILABLE; 272 | @end 273 | 274 | 275 | #pragma clang diagnostic pop 276 | -------------------------------------------------------------------------------- /Carthage/Build/iOS/PKHUD.framework/Headers/PKHUD.h: -------------------------------------------------------------------------------- 1 | // 2 | // PKHUD.h 3 | // PKHUD 4 | // 5 | // Created by Philip Kluz on 6/17/14. 6 | // Copyright (c) 2016 NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | @import UIKit; 11 | 12 | //! Project version number for PKHUD. 13 | FOUNDATION_EXPORT double PKHUDVersionNumber; 14 | 15 | //! Project version string for PKHUD. 16 | FOUNDATION_EXPORT const unsigned char PKHUDVersionString[]; 17 | -------------------------------------------------------------------------------- /Carthage/Build/iOS/PKHUD.framework/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Build/iOS/PKHUD.framework/Info.plist -------------------------------------------------------------------------------- /Carthage/Build/iOS/PKHUD.framework/Modules/PKHUD.swiftmodule/arm.swiftdoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Build/iOS/PKHUD.framework/Modules/PKHUD.swiftmodule/arm.swiftdoc -------------------------------------------------------------------------------- /Carthage/Build/iOS/PKHUD.framework/Modules/PKHUD.swiftmodule/arm.swiftmodule: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Build/iOS/PKHUD.framework/Modules/PKHUD.swiftmodule/arm.swiftmodule -------------------------------------------------------------------------------- /Carthage/Build/iOS/PKHUD.framework/Modules/PKHUD.swiftmodule/arm64.swiftdoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Build/iOS/PKHUD.framework/Modules/PKHUD.swiftmodule/arm64.swiftdoc -------------------------------------------------------------------------------- /Carthage/Build/iOS/PKHUD.framework/Modules/PKHUD.swiftmodule/arm64.swiftmodule: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Build/iOS/PKHUD.framework/Modules/PKHUD.swiftmodule/arm64.swiftmodule -------------------------------------------------------------------------------- /Carthage/Build/iOS/PKHUD.framework/Modules/PKHUD.swiftmodule/i386.swiftdoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Build/iOS/PKHUD.framework/Modules/PKHUD.swiftmodule/i386.swiftdoc -------------------------------------------------------------------------------- /Carthage/Build/iOS/PKHUD.framework/Modules/PKHUD.swiftmodule/i386.swiftmodule: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Build/iOS/PKHUD.framework/Modules/PKHUD.swiftmodule/i386.swiftmodule -------------------------------------------------------------------------------- /Carthage/Build/iOS/PKHUD.framework/Modules/PKHUD.swiftmodule/x86_64.swiftdoc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Build/iOS/PKHUD.framework/Modules/PKHUD.swiftmodule/x86_64.swiftdoc -------------------------------------------------------------------------------- /Carthage/Build/iOS/PKHUD.framework/Modules/PKHUD.swiftmodule/x86_64.swiftmodule: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Build/iOS/PKHUD.framework/Modules/PKHUD.swiftmodule/x86_64.swiftmodule -------------------------------------------------------------------------------- /Carthage/Build/iOS/PKHUD.framework/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module PKHUD { 2 | umbrella header "PKHUD.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | 8 | module PKHUD.Swift { 9 | header "PKHUD-Swift.h" 10 | } 11 | -------------------------------------------------------------------------------- /Carthage/Build/iOS/PKHUD.framework/PKHUD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Build/iOS/PKHUD.framework/PKHUD -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/.gitignore: -------------------------------------------------------------------------------- 1 | # Mac OS X Finder and whatnot 2 | .DS_Store 3 | *.swp 4 | *~.nib 5 | 6 | # XCode (and ancestors) per-user config (very noisy, and not relevant) 7 | *.mode1 8 | *.mode1v3 9 | *.mode2v3 10 | *.perspective 11 | *.perspectivev3 12 | *.pbxuser 13 | *.xcworkspace 14 | *.xccheckout 15 | *.xcuserstate 16 | 17 | # XCode 4 18 | xcuserdata 19 | 20 | # build products 21 | build/ 22 | DerivedData/ 23 | 24 | # Other source repository archive directories (protects when importing) 25 | .hg 26 | .svn 27 | CVS 28 | 29 | # temporary script folders/files 30 | ThirdParty/boost/* 31 | 32 | # Eclipse Workspace 33 | .metadata 34 | 35 | # Maya temporary 36 | .mayaSwatches/ 37 | UserInterfaceState.xcuserstate 38 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/Carthage/Build: -------------------------------------------------------------------------------- 1 | ../../../../Carthage/Build -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/Demo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // PKHUD Demo 4 | // 5 | // Created by Philip Kluz on 6/18/14. 6 | // Copyright (c) 2016 NSExceptional. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | var window: UIWindow? 14 | } 15 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/Demo/DemoViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DemoViewController.swift 3 | // PKHUD Demo 4 | // 5 | // Created by Philip Kluz on 6/18/14. 6 | // Copyright (c) 2016 NSExceptional. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import PKHUD 11 | 12 | class DemoViewController: UIViewController { 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | 17 | HUD.dimsBackground = false 18 | HUD.allowsInteraction = false 19 | } 20 | 21 | @IBAction func showAnimatedSuccessHUD(_ sender: AnyObject) { 22 | HUD.flash(.success, delay: 2.0) 23 | } 24 | 25 | @IBAction func showAnimatedErrorHUD(_ sender: AnyObject) { 26 | HUD.show(.error) 27 | HUD.hide(afterDelay: 2.0) 28 | } 29 | 30 | @IBAction func showAnimatedProgressHUD(_ sender: AnyObject) { 31 | HUD.show(.progress) 32 | 33 | // Now some long running task starts... 34 | delay(2.0) { 35 | // ...and once it finishes we flash the HUD for a second. 36 | HUD.flash(.success, delay: 1.0) 37 | } 38 | } 39 | 40 | @IBAction func showCustomProgressHUD(_ sender: AnyObject) { 41 | HUD.flash(.rotatingImage(UIImage(named: "progress")), delay: 2.0) 42 | } 43 | 44 | @IBAction func showAnimatedStatusProgressHUD(_ sender: AnyObject) { 45 | HUD.flash(.labeledProgress(title: "Title", subtitle: "Subtitle"), delay: 2.0) 46 | } 47 | 48 | @IBAction func showTextHUD(_ sender: AnyObject) { 49 | HUD.flash(.label("Requesting Licence…"), delay: 2.0) { _ in 50 | print("License Obtained.") 51 | } 52 | } 53 | 54 | /* 55 | 56 | Please note that the above demonstrates the "porcelain" interface - a more concise and clean way to work with the HUD. 57 | If you need more options and flexbility, feel free to use the underlying "plumbing". E.g.: 58 | 59 | PKHUD.sharedHUD.show() 60 | PKHUD.sharedHUD.contentView = PKHUDSuccessView(title: "Success!", subtitle: nil) 61 | PKHUD.sharedHUD.hide(afterDelay: 2.0) 62 | */ 63 | 64 | override var supportedInterfaceOrientations : UIInterfaceOrientationMask { 65 | return UIInterfaceOrientationMask.allButUpsideDown 66 | } 67 | 68 | override var preferredStatusBarStyle : UIStatusBarStyle { 69 | return .lightContent 70 | } 71 | 72 | func delay(_ delay:Double, closure:@escaping ()->()) { 73 | DispatchQueue.main.asyncAfter( 74 | deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/Demo/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 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "83.5x83.5", 66 | "scale" : "2x" 67 | } 68 | ], 69 | "info" : { 70 | "version" : 1, 71 | "author" : "xcode" 72 | } 73 | } -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/Demo/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/Demo/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/Demo/Images.xcassets/background.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "background@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/Demo/Images.xcassets/background.imageset/background@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Checkouts/PKHUD/Demo/Images.xcassets/background.imageset/background@2x.png -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/Demo/Images.xcassets/progress.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "progress.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/Demo/Images.xcassets/progress.imageset/progress.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Checkouts/PKHUD/Demo/Images.xcassets/progress.imageset/progress.pdf -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/Demo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | Launch Screen 27 | UIMainStoryboardFile 28 | Storyboard 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | UIInterfaceOrientationPortraitUpsideDown 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/Demo/Launch Screen.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 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/Demo/Storyboard.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 | 41 | 56 | 71 | 86 | 101 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Philip Kluz (Philip.Kluz@gmail.com) 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. -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'PKHUD' 3 | s.module_name = 'PKHUD' 4 | s.version = '4.0.0' 5 | s.summary = 'A Swift 3 based reimplementation of the Apple HUD (Volume, Ringer, Rotation,…) for iOS 8 and up' 6 | s.homepage = 'https://github.com/pkluz/PKHUD' 7 | s.license = 'MIT' 8 | s.author = { 'Philip Kluz' => 'Philip.Kluz@gmail.com' } 9 | s.platform = :ios, '8.0' 10 | s.ios.deployment_target = '8.0' 11 | s.requires_arc = true 12 | s.source = { :git => 'https://github.com/pkluz/PKHUD.git', :tag => s.version.to_s } 13 | s.source_files = 'PKHUD/**/*.{h,swift}' 14 | s.resources = 'PKHUD/*.xcassets' 15 | end 16 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD.xcodeproj/xcshareddata/xcschemes/PKHUD.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/FrameView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HUDView.swift 3 | // PKHUD 4 | // 5 | // Created by Philip Kluz on 6/16/14. 6 | // Copyright (c) 2016 NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | import UIKit 11 | 12 | /// Provides the general look and feel of the PKHUD, into which the eventual content is inserted. 13 | internal class FrameView: UIVisualEffectView { 14 | 15 | internal init() { 16 | super.init(effect: UIBlurEffect(style: .light)) 17 | commonInit() 18 | } 19 | 20 | required init?(coder aDecoder: NSCoder) { 21 | super.init(coder: aDecoder) 22 | commonInit() 23 | } 24 | 25 | fileprivate func commonInit() { 26 | backgroundColor = UIColor(white: 0.8, alpha: 0.36) 27 | layer.cornerRadius = 9.0 28 | layer.masksToBounds = true 29 | 30 | contentView.addSubview(self.content) 31 | 32 | let offset = 20.0 33 | 34 | let motionEffectsX = UIInterpolatingMotionEffect(keyPath: "center.x", type: .tiltAlongHorizontalAxis) 35 | motionEffectsX.maximumRelativeValue = offset 36 | motionEffectsX.minimumRelativeValue = -offset 37 | 38 | let motionEffectsY = UIInterpolatingMotionEffect(keyPath: "center.y", type: .tiltAlongVerticalAxis) 39 | motionEffectsY.maximumRelativeValue = offset 40 | motionEffectsY.minimumRelativeValue = -offset 41 | 42 | let group = UIMotionEffectGroup() 43 | group.motionEffects = [motionEffectsX, motionEffectsY] 44 | 45 | addMotionEffect(group) 46 | } 47 | 48 | fileprivate var _content = UIView() 49 | internal var content: UIView { 50 | get { 51 | return _content 52 | } 53 | set { 54 | _content.removeFromSuperview() 55 | _content = newValue 56 | _content.alpha = 0.85 57 | _content.clipsToBounds = true 58 | _content.contentMode = .center 59 | frame.size = _content.bounds.size 60 | addSubview(_content) 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/HUD.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HUD.swift 3 | // PKHUD 4 | // 5 | // Created by Eugene Tartakovsky on 29/01/16. 6 | // Copyright © 2016 Eugene Tartakovsky, NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | import UIKit 11 | 12 | public enum HUDContentType { 13 | case success 14 | case error 15 | case progress 16 | case image(UIImage?) 17 | case rotatingImage(UIImage?) 18 | 19 | case labeledSuccess(title: String?, subtitle: String?) 20 | case labeledError(title: String?, subtitle: String?) 21 | case labeledProgress(title: String?, subtitle: String?) 22 | case labeledImage(image: UIImage?, title: String?, subtitle: String?) 23 | case labeledRotatingImage(image: UIImage?, title: String?, subtitle: String?) 24 | 25 | case label(String?) 26 | case systemActivity 27 | } 28 | 29 | public final class HUD { 30 | 31 | // MARK: Properties 32 | public static var dimsBackground: Bool { 33 | get { return PKHUD.sharedHUD.dimsBackground } 34 | set { PKHUD.sharedHUD.dimsBackground = newValue } 35 | } 36 | 37 | public static var allowsInteraction: Bool { 38 | get { return PKHUD.sharedHUD.userInteractionOnUnderlyingViewsEnabled } 39 | set { PKHUD.sharedHUD.userInteractionOnUnderlyingViewsEnabled = newValue } 40 | } 41 | 42 | public static var isVisible: Bool { return PKHUD.sharedHUD.isVisible } 43 | 44 | // MARK: Public methods, PKHUD based 45 | public static func show(_ content: HUDContentType, onView view: UIView? = nil) { 46 | PKHUD.sharedHUD.contentView = contentView(content) 47 | PKHUD.sharedHUD.show(onView: view) 48 | } 49 | 50 | public static func hide(_ completion: ((Bool) -> Void)? = nil) { 51 | PKHUD.sharedHUD.hide(animated: false, completion: completion) 52 | } 53 | 54 | public static func hide(animated: Bool, completion: ((Bool) -> Void)? = nil) { 55 | PKHUD.sharedHUD.hide(animated: animated, completion: completion) 56 | } 57 | 58 | public static func hide(afterDelay delay: TimeInterval, completion: ((Bool) -> Void)? = nil) { 59 | PKHUD.sharedHUD.hide(afterDelay: delay, completion: completion) 60 | } 61 | 62 | // MARK: Public methods, HUD based 63 | public static func flash(_ content: HUDContentType, onView view: UIView? = nil) { 64 | HUD.show(content, onView: view) 65 | HUD.hide(animated: true, completion: nil) 66 | } 67 | 68 | public static func flash(_ content: HUDContentType, onView view: UIView? = nil, delay: TimeInterval, completion: ((Bool) -> Void)? = nil) { 69 | HUD.show(content, onView: view) 70 | HUD.hide(afterDelay: delay, completion: completion) 71 | } 72 | 73 | // MARK: Private methods 74 | fileprivate static func contentView(_ content: HUDContentType) -> UIView { 75 | switch content { 76 | case .success: 77 | return PKHUDSuccessView() 78 | case .error: 79 | return PKHUDErrorView() 80 | case .progress(): 81 | return PKHUDProgressView() 82 | case let .image(image): 83 | return PKHUDSquareBaseView(image: image) 84 | case let .rotatingImage(image): 85 | return PKHUDRotatingImageView(image: image) 86 | 87 | case let .labeledSuccess(title, subtitle): 88 | return PKHUDSuccessView(title: title, subtitle: subtitle) 89 | case let .labeledError(title, subtitle): 90 | return PKHUDErrorView(title: title, subtitle: subtitle) 91 | case let .labeledProgress(title, subtitle): 92 | return PKHUDProgressView(title: title, subtitle: subtitle) 93 | case let .labeledImage(image, title, subtitle): 94 | return PKHUDSquareBaseView(image: image, title: title, subtitle: subtitle) 95 | case let .labeledRotatingImage(image, title, subtitle): 96 | return PKHUDRotatingImageView(image: image, title: title, subtitle: subtitle) 97 | 98 | 99 | case let .label(text): 100 | return PKHUDTextView(text: text) 101 | case .systemActivity: 102 | return PKHUDSystemActivityIndicatorView() 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/Images.xcassets/checkmark.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "checkmark.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/Images.xcassets/checkmark.imageset/checkmark.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Checkouts/PKHUD/PKHUD/Images.xcassets/checkmark.imageset/checkmark.pdf -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/Images.xcassets/cross.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "cross.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/Images.xcassets/cross.imageset/cross.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Checkouts/PKHUD/PKHUD/Images.xcassets/cross.imageset/cross.pdf -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/Images.xcassets/progress_activity.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "progress.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/Images.xcassets/progress_activity.imageset/progress.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Checkouts/PKHUD/PKHUD/Images.xcassets/progress_activity.imageset/progress.pdf -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/Images.xcassets/progress_circular.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "progress_circular.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | }, 12 | "properties" : { 13 | "template-rendering-intent" : "original" 14 | } 15 | } -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/Images.xcassets/progress_circular.imageset/progress_circular.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Checkouts/PKHUD/PKHUD/Images.xcassets/progress_circular.imageset/progress_circular.pdf -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/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 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/PKHUD.h: -------------------------------------------------------------------------------- 1 | // 2 | // PKHUD.h 3 | // PKHUD 4 | // 5 | // Created by Philip Kluz on 6/17/14. 6 | // Copyright (c) 2016 NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | @import UIKit; 11 | 12 | //! Project version number for PKHUD. 13 | FOUNDATION_EXPORT double PKHUDVersionNumber; 14 | 15 | //! Project version string for PKHUD. 16 | FOUNDATION_EXPORT const unsigned char PKHUDVersionString[]; 17 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/PKHUD.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HUD.swift 3 | // PKHUD 4 | // 5 | // Created by Philip Kluz on 6/13/14. 6 | // Copyright (c) 2016 NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | import UIKit 11 | 12 | /// The PKHUD object controls showing and hiding of the HUD, as well as its contents and touch response behavior. 13 | open class PKHUD: NSObject { 14 | 15 | fileprivate struct Constants { 16 | static let sharedHUD = PKHUD() 17 | } 18 | 19 | public var viewToPresentOn: UIView? = nil 20 | 21 | fileprivate let container = ContainerView() 22 | fileprivate var hideTimer: Timer? 23 | 24 | public typealias TimerAction = (Bool) -> Void 25 | fileprivate var timerActions = [String: TimerAction]() 26 | 27 | // MARK: Public 28 | 29 | open class var sharedHUD: PKHUD { 30 | return Constants.sharedHUD 31 | } 32 | 33 | public override init () { 34 | super.init() 35 | NotificationCenter.default.addObserver(self, 36 | selector: #selector(PKHUD.willEnterForeground(_:)), 37 | name: NSNotification.Name.UIApplicationWillEnterForeground, 38 | object: nil) 39 | userInteractionOnUnderlyingViewsEnabled = false 40 | container.frameView.autoresizingMask = [ .flexibleLeftMargin, 41 | .flexibleRightMargin, 42 | .flexibleTopMargin, 43 | .flexibleBottomMargin ] 44 | } 45 | 46 | public convenience init(viewToPresentOn view: UIView) { 47 | self.init() 48 | viewToPresentOn = view 49 | } 50 | 51 | deinit { 52 | NotificationCenter.default.removeObserver(self) 53 | } 54 | 55 | open var dimsBackground = true 56 | open var userInteractionOnUnderlyingViewsEnabled: Bool { 57 | get { 58 | return !container.isUserInteractionEnabled 59 | } 60 | set { 61 | container.isUserInteractionEnabled = !newValue 62 | } 63 | } 64 | 65 | open var isVisible: Bool { 66 | return !container.isHidden 67 | } 68 | 69 | open var contentView: UIView { 70 | get { 71 | return container.frameView.content 72 | } 73 | set { 74 | container.frameView.content = newValue 75 | startAnimatingContentView() 76 | } 77 | } 78 | 79 | open var effect: UIVisualEffect? { 80 | get { 81 | return container.frameView.effect 82 | } 83 | set { 84 | container.frameView.effect = newValue 85 | } 86 | } 87 | 88 | open func show(onView view: UIView? = nil) { 89 | let view:UIView = view ?? viewToPresentOn ?? UIApplication.shared.keyWindow! 90 | if(!view.subviews.contains(container)) { 91 | view.addSubview(container) 92 | container.frame.origin = CGPoint.zero 93 | container.frame.size = view.frame.size 94 | container.autoresizingMask = [ .flexibleHeight, .flexibleWidth ] 95 | } 96 | container.showFrameView() 97 | if dimsBackground { 98 | container.showBackground(animated: true) 99 | } 100 | 101 | startAnimatingContentView() 102 | } 103 | 104 | open func hide(animated anim: Bool = true, completion: TimerAction? = nil) { 105 | container.hideFrameView(animated: anim, completion: completion) 106 | stopAnimatingContentView() 107 | } 108 | 109 | open func hide(_ animated: Bool, completion: TimerAction? = nil) { 110 | hide(animated: animated, completion: completion) 111 | } 112 | 113 | open func hide(afterDelay delay: TimeInterval, completion: TimerAction? = nil) { 114 | let key = UUID().uuidString 115 | let userInfo = ["timerActionKey": key] 116 | if let completion = completion { 117 | timerActions[key] = completion 118 | } 119 | 120 | hideTimer?.invalidate() 121 | hideTimer = Timer.scheduledTimer(timeInterval: delay, 122 | target: self, 123 | selector: #selector(PKHUD.performDelayedHide(_:)), 124 | userInfo: userInfo, 125 | repeats: false) 126 | } 127 | 128 | // MARK: Internal 129 | 130 | internal func willEnterForeground(_ notification: Notification?) { 131 | self.startAnimatingContentView() 132 | } 133 | 134 | internal func performDelayedHide(_ timer: Timer? = nil) { 135 | let userInfo = timer?.userInfo as? Dictionary 136 | let key = userInfo?["timerActionKey"] as? String 137 | var completion: TimerAction? 138 | 139 | if let key = key, let action = timerActions[key] { 140 | completion = action 141 | timerActions[key] = nil 142 | } 143 | 144 | hide(animated: true, completion: completion); 145 | } 146 | 147 | internal func startAnimatingContentView() { 148 | if let animatingContentView = contentView as? PKHUDAnimating, isVisible { 149 | animatingContentView.startAnimation() 150 | } 151 | } 152 | 153 | internal func stopAnimatingContentView() { 154 | if let animatingContentView = contentView as? PKHUDAnimating { 155 | animatingContentView.stopAnimation?() 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/PKHUDAnimating.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PKHUDAnimatingContentView.swift 3 | // PKHUD 4 | // 5 | // Created by Philip Kluz on 9/27/15. 6 | // Copyright (c) 2016 NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | import UIKit 11 | 12 | @objc protocol PKHUDAnimating { 13 | 14 | func startAnimation() 15 | @objc optional func stopAnimation() 16 | } 17 | 18 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/PKHUDAnimation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PKHUDAnimation.swift 3 | // PKHUD 4 | // 5 | // Created by Piergiuseppe Longo on 06/01/16. 6 | // Copyright © 2016 Piergiuseppe Longo, NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | import Foundation 11 | import QuartzCore 12 | 13 | public final class PKHUDAnimation { 14 | 15 | static let discreteRotation: CAAnimation = { 16 | let animation = CAKeyframeAnimation(keyPath: "transform.rotation.z") 17 | animation.values = [ 18 | NSNumber(value: 0.0 as Float), 19 | NSNumber(value: 1.0 * Float(M_PI) / 6.0 as Float), 20 | NSNumber(value: 2.0 * Float(M_PI) / 6.0 as Float), 21 | NSNumber(value: 3.0 * Float(M_PI) / 6.0 as Float), 22 | NSNumber(value: 4.0 * Float(M_PI) / 6.0 as Float), 23 | NSNumber(value: 5.0 * Float(M_PI) / 6.0 as Float), 24 | NSNumber(value: 6.0 * Float(M_PI) / 6.0 as Float), 25 | NSNumber(value: 7.0 * Float(M_PI) / 6.0 as Float), 26 | NSNumber(value: 8.0 * Float(M_PI) / 6.0 as Float), 27 | NSNumber(value: 9.0 * Float(M_PI) / 6.0 as Float), 28 | NSNumber(value: 10.0 * Float(M_PI) / 6.0 as Float), 29 | NSNumber(value: 11.0 * Float(M_PI) / 6.0 as Float), 30 | NSNumber(value: 2.0 * Float(M_PI) as Float) 31 | ] 32 | animation.keyTimes = [ 33 | NSNumber(value: 0.0 as Float), 34 | NSNumber(value: 1.0 / 12.0 as Float), 35 | NSNumber(value: 2.0 / 12.0 as Float), 36 | NSNumber(value: 3.0 / 12.0 as Float), 37 | NSNumber(value: 4.0 / 12.0 as Float), 38 | NSNumber(value: 5.0 / 12.0 as Float), 39 | NSNumber(value: 0.5 as Float), 40 | NSNumber(value: 7.0 / 12.0 as Float), 41 | NSNumber(value: 8.0 / 12.0 as Float), 42 | NSNumber(value: 9.0 / 12.0 as Float), 43 | NSNumber(value: 10.0 / 12.0 as Float), 44 | NSNumber(value: 11.0 / 12.0 as Float), 45 | NSNumber(value: 1.0 as Float) 46 | ] 47 | animation.duration = 1.2 48 | animation.calculationMode = "discrete" 49 | animation.repeatCount = Float(INT_MAX) 50 | return animation 51 | }() 52 | 53 | 54 | static let continuousRotation: CAAnimation = { 55 | let animation = CABasicAnimation(keyPath: "transform.rotation.z") 56 | animation.fromValue = 0 57 | animation.toValue = 2.0 * M_PI 58 | animation.duration = 1.2 59 | animation.repeatCount = Float(INT_MAX) 60 | return animation 61 | }() 62 | } 63 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/PKHUDAssets.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PKHUD.Assets.swift 3 | // PKHUD 4 | // 5 | // Created by Philip Kluz on 6/18/14. 6 | // Copyright (c) 2016 NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | import UIKit 11 | 12 | /// PKHUDAssets provides a set of default images, that can be supplied to the PKHUD's content views. 13 | open class PKHUDAssets: NSObject { 14 | 15 | open class var crossImage: UIImage { return PKHUDAssets.bundledImage(named: "cross") } 16 | open class var checkmarkImage: UIImage { return PKHUDAssets.bundledImage(named: "checkmark") } 17 | open class var progressActivityImage: UIImage { return PKHUDAssets.bundledImage(named: "progress_activity") } 18 | open class var progressCircularImage: UIImage { return PKHUDAssets.bundledImage(named: "progress_circular") } 19 | 20 | internal class func bundledImage(named name: String) -> UIImage { 21 | let bundle = Bundle(for: PKHUDAssets.self) 22 | let image = UIImage(named: name, in:bundle, compatibleWith:nil) 23 | if let image = image { 24 | return image 25 | } 26 | 27 | return UIImage() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/PKHUDErrorView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PKHUDErrorAnimation.swift 3 | // PKHUD 4 | // 5 | // Created by Philip Kluz on 9/27/15. 6 | // Copyright (c) 2016 NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | import UIKit 11 | 12 | /// PKHUDErrorView provides an animated error (cross) view. 13 | open class PKHUDErrorView: PKHUDSquareBaseView, PKHUDAnimating { 14 | 15 | var dashOneLayer = PKHUDErrorView.generateDashLayer() 16 | var dashTwoLayer = PKHUDErrorView.generateDashLayer() 17 | 18 | class func generateDashLayer() -> CAShapeLayer { 19 | let dash = CAShapeLayer() 20 | dash.frame = CGRect(x: 0.0, y: 0.0, width: 88.0, height: 88.0) 21 | dash.path = { 22 | let path = UIBezierPath() 23 | path.move(to: CGPoint(x: 0.0, y: 44.0)) 24 | path.addLine(to: CGPoint(x: 88.0, y: 44.0)) 25 | return path.cgPath 26 | }() 27 | dash.lineCap = kCALineCapRound 28 | dash.lineJoin = kCALineJoinRound 29 | dash.fillColor = nil 30 | dash.strokeColor = UIColor(red: 0.15, green: 0.15, blue: 0.15, alpha: 1.0).cgColor 31 | dash.lineWidth = 6 32 | dash.fillMode = kCAFillModeForwards 33 | return dash 34 | } 35 | 36 | public init(title: String? = nil, subtitle: String? = nil) { 37 | super.init(title: title, subtitle: subtitle) 38 | layer.addSublayer(dashOneLayer) 39 | layer.addSublayer(dashTwoLayer) 40 | dashOneLayer.position = layer.position 41 | dashTwoLayer.position = layer.position 42 | } 43 | 44 | public required init?(coder aDecoder: NSCoder) { 45 | super.init(coder: aDecoder) 46 | layer.addSublayer(dashOneLayer) 47 | layer.addSublayer(dashTwoLayer) 48 | dashOneLayer.position = layer.position 49 | dashTwoLayer.position = layer.position 50 | } 51 | 52 | func rotationAnimation(_ angle: CGFloat) -> CABasicAnimation { 53 | var animation : CABasicAnimation 54 | if #available(iOS 9.0, *) { 55 | let springAnimation = CASpringAnimation(keyPath:"transform.rotation.z") 56 | springAnimation.damping = 1.5 57 | springAnimation.mass = 0.22 58 | springAnimation.initialVelocity = 0.5 59 | animation = springAnimation 60 | } else { 61 | animation = CABasicAnimation(keyPath:"transform.rotation.z") 62 | } 63 | 64 | animation.fromValue = 0.0 65 | animation.toValue = angle * CGFloat(M_PI / 180.0) 66 | animation.duration = 1.0 67 | animation.timingFunction = CAMediaTimingFunction(name:kCAMediaTimingFunctionEaseInEaseOut) 68 | return animation 69 | } 70 | 71 | func startAnimation() { 72 | let dashOneAnimation = rotationAnimation(-45.0) 73 | let dashTwoAnimation = rotationAnimation(45.0) 74 | 75 | dashOneLayer.transform = CATransform3DMakeRotation(-45 * CGFloat(M_PI/180), 0.0, 0.0, 1.0) 76 | dashTwoLayer.transform = CATransform3DMakeRotation(45 * CGFloat(M_PI/180), 0.0, 0.0, 1.0) 77 | 78 | dashOneLayer.add(dashOneAnimation, forKey: "dashOneAnimation") 79 | dashTwoLayer.add(dashTwoAnimation, forKey: "dashTwoAnimation") 80 | } 81 | 82 | func stopAnimation() { 83 | dashOneLayer.removeAnimation(forKey: "dashOneAnimation") 84 | dashTwoLayer.removeAnimation(forKey: "dashTwoAnimation") 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/PKHUDProgressView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PKHUDProgressVIew.swift 3 | // PKHUD 4 | // 5 | // Created by Philip Kluz on 6/12/15. 6 | // Copyright (c) 2016 NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | import UIKit 11 | import QuartzCore 12 | 13 | /// PKHUDProgressView provides an indeterminate progress view. 14 | open class PKHUDProgressView: PKHUDSquareBaseView, PKHUDAnimating { 15 | 16 | public init(title: String? = nil, subtitle: String? = nil) { 17 | super.init(image: PKHUDAssets.progressActivityImage, title: title, subtitle: subtitle) 18 | } 19 | 20 | public required init?(coder aDecoder: NSCoder) { 21 | super.init(coder: aDecoder) 22 | } 23 | 24 | func startAnimation() { 25 | imageView.layer.add(PKHUDAnimation.discreteRotation, forKey: "progressAnimation") 26 | } 27 | 28 | func stopAnimation() { 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/PKHUDRotatingImageView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PKHUDRotatingImageView.swift 3 | // PKHUD 4 | // 5 | // Created by Mark Koh on 1/14/16. 6 | // Copyright © 2016 NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | import UIKit 11 | import QuartzCore 12 | 13 | /// PKHUDRotatingImageView provides a content view that rotates the supplies image automatically. 14 | open class PKHUDRotatingImageView: PKHUDSquareBaseView, PKHUDAnimating { 15 | 16 | func startAnimation() { 17 | imageView.layer.add(PKHUDAnimation.continuousRotation, forKey: "progressAnimation") 18 | } 19 | 20 | func stopAnimation() { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/PKHUDSquareBaseView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PKHUDSquareBaseView.swift 3 | // PKHUD 4 | // 5 | // Created by Philip Kluz on 6/12/15. 6 | // Copyright (c) 2016 NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | import UIKit 11 | 12 | /// PKHUDSquareBaseView provides a square view, which you can subclass and add additional views to. 13 | open class PKHUDSquareBaseView: UIView { 14 | 15 | static let defaultSquareBaseViewFrame = CGRect(origin: CGPoint.zero, size: CGSize(width: 156.0, height: 156.0)) 16 | 17 | public override init(frame: CGRect) { 18 | super.init(frame: frame) 19 | } 20 | 21 | public required init?(coder aDecoder: NSCoder) { 22 | super.init(coder: aDecoder) 23 | } 24 | 25 | public init(image: UIImage? = nil, title: String? = nil, subtitle: String? = nil) { 26 | super.init(frame: PKHUDSquareBaseView.defaultSquareBaseViewFrame) 27 | self.imageView.image = image 28 | titleLabel.text = title 29 | subtitleLabel.text = subtitle 30 | 31 | addSubview(imageView) 32 | addSubview(titleLabel) 33 | addSubview(subtitleLabel) 34 | } 35 | 36 | open let imageView: UIImageView = { 37 | let imageView = UIImageView() 38 | imageView.alpha = 0.85 39 | imageView.clipsToBounds = true 40 | imageView.contentMode = .center 41 | return imageView 42 | }() 43 | 44 | open let titleLabel: UILabel = { 45 | let label = UILabel() 46 | label.textAlignment = .center 47 | label.font = UIFont.boldSystemFont(ofSize: 17.0) 48 | label.textColor = UIColor.black.withAlphaComponent(0.85) 49 | label.adjustsFontSizeToFitWidth = true 50 | label.minimumScaleFactor = 0.25 51 | return label 52 | }() 53 | 54 | open let subtitleLabel: UILabel = { 55 | let label = UILabel() 56 | label.textAlignment = .center 57 | label.font = UIFont.systemFont(ofSize: 14.0) 58 | label.textColor = UIColor.black.withAlphaComponent(0.7) 59 | label.adjustsFontSizeToFitWidth = true 60 | label.numberOfLines = 2 61 | label.adjustsFontSizeToFitWidth = true 62 | label.minimumScaleFactor = 0.25 63 | return label 64 | }() 65 | 66 | open override func layoutSubviews() { 67 | super.layoutSubviews() 68 | 69 | let viewWidth = bounds.size.width 70 | let viewHeight = bounds.size.height 71 | 72 | let halfHeight = CGFloat(ceilf(CFloat(viewHeight / 2.0))) 73 | let quarterHeight = CGFloat(ceilf(CFloat(viewHeight / 4.0))) 74 | let threeQuarterHeight = CGFloat(ceilf(CFloat(viewHeight / 4.0 * 3.0))) 75 | 76 | titleLabel.frame = CGRect(origin: CGPoint.zero, size: CGSize(width: viewWidth, height: quarterHeight)) 77 | imageView.frame = CGRect(origin: CGPoint(x:0.0, y:quarterHeight), size: CGSize(width: viewWidth, height: halfHeight)) 78 | subtitleLabel.frame = CGRect(origin: CGPoint(x:0.0, y:threeQuarterHeight), size: CGSize(width: viewWidth, height: quarterHeight)) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/PKHUDSuccessView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PKHUDCheckmarkView.swift 3 | // PKHUD 4 | // 5 | // Created by Philip Kluz on 9/27/15. 6 | // Copyright (c) 2016 NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | import UIKit 11 | 12 | /// PKHUDCheckmarkView provides an animated success (checkmark) view. 13 | open class PKHUDSuccessView: PKHUDSquareBaseView, PKHUDAnimating { 14 | 15 | var checkmarkShapeLayer: CAShapeLayer = { 16 | let checkmarkPath = UIBezierPath() 17 | checkmarkPath.move(to: CGPoint(x: 4.0, y: 27.0)) 18 | checkmarkPath.addLine(to: CGPoint(x: 34.0, y: 56.0)) 19 | checkmarkPath.addLine(to: CGPoint(x: 88.0, y: 0.0)) 20 | 21 | let layer = CAShapeLayer() 22 | layer.frame = CGRect(x: 3.0, y: 3.0, width: 88.0, height: 56.0) 23 | layer.path = checkmarkPath.cgPath 24 | layer.fillMode = kCAFillModeForwards 25 | layer.lineCap = kCALineCapRound 26 | layer.lineJoin = kCALineJoinRound 27 | layer.fillColor = nil 28 | layer.strokeColor = UIColor(red: 0.15, green: 0.15, blue: 0.15, alpha: 1.0).cgColor 29 | layer.lineWidth = 6.0 30 | return layer 31 | }() 32 | 33 | public init(title: String? = nil, subtitle: String? = nil) { 34 | super.init(title: title, subtitle: subtitle) 35 | layer.addSublayer(checkmarkShapeLayer) 36 | checkmarkShapeLayer.position = layer.position 37 | } 38 | 39 | 40 | public required init?(coder aDecoder: NSCoder) { 41 | super.init(coder: aDecoder) 42 | layer.addSublayer(checkmarkShapeLayer) 43 | checkmarkShapeLayer.position = layer.position 44 | } 45 | 46 | open func startAnimation() { 47 | let checkmarkStrokeAnimation = CAKeyframeAnimation(keyPath:"strokeEnd") 48 | checkmarkStrokeAnimation.values = [0, 1] 49 | checkmarkStrokeAnimation.keyTimes = [0, 1] 50 | checkmarkStrokeAnimation.duration = 0.35 51 | 52 | checkmarkShapeLayer.add(checkmarkStrokeAnimation, forKey:"checkmarkStrokeAnim") 53 | } 54 | 55 | open func stopAnimation() { 56 | checkmarkShapeLayer.removeAnimation(forKey: "checkmarkStrokeAnimation") 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/PKHUDSystemActivityIndicatorView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PKHUDSystemActivityIndicatorView.swift 3 | // PKHUD 4 | // 5 | // Created by Philip Kluz on 6/12/15. 6 | // Copyright (c) 2016 NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | import UIKit 11 | 12 | /// PKHUDSystemActivityIndicatorView provides the system UIActivityIndicatorView as an alternative. 13 | public final class PKHUDSystemActivityIndicatorView: PKHUDSquareBaseView, PKHUDAnimating { 14 | 15 | public init() { 16 | super.init(frame: PKHUDSquareBaseView.defaultSquareBaseViewFrame) 17 | commonInit() 18 | } 19 | 20 | public override init(frame: CGRect) { 21 | super.init(frame: frame) 22 | commonInit() 23 | } 24 | 25 | public required init?(coder aDecoder: NSCoder) { 26 | super.init(coder: aDecoder) 27 | commonInit() 28 | } 29 | 30 | func commonInit () { 31 | backgroundColor = UIColor.clear 32 | alpha = 0.8 33 | 34 | self.addSubview(activityIndicatorView) 35 | } 36 | 37 | public override func layoutSubviews() { 38 | super.layoutSubviews() 39 | activityIndicatorView.center = self.center 40 | } 41 | 42 | let activityIndicatorView: UIActivityIndicatorView = { 43 | let activity = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge) 44 | activity.color = UIColor.black 45 | return activity 46 | }() 47 | 48 | func startAnimation() { 49 | activityIndicatorView.startAnimating() 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/PKHUDTextView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PKHUDTextView.swift 3 | // PKHUD 4 | // 5 | // Created by Philip Kluz on 6/12/15. 6 | // Copyright (c) 2016 NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | import UIKit 11 | 12 | /// PKHUDTextView provides a wide, three line text view, which you can use to display information. 13 | open class PKHUDTextView: PKHUDWideBaseView { 14 | 15 | public init(text: String?) { 16 | super.init() 17 | commonInit(text) 18 | } 19 | 20 | public required init?(coder aDecoder: NSCoder) { 21 | super.init(coder: aDecoder) 22 | commonInit("") 23 | } 24 | 25 | func commonInit(_ text: String?) { 26 | titleLabel.text = text 27 | addSubview(titleLabel) 28 | } 29 | 30 | open override func layoutSubviews() { 31 | super.layoutSubviews() 32 | 33 | let padding: CGFloat = 10.0 34 | titleLabel.frame = bounds.insetBy(dx: padding, dy: padding) 35 | } 36 | 37 | open let titleLabel: UILabel = { 38 | let label = UILabel() 39 | label.textAlignment = .center 40 | label.font = UIFont.boldSystemFont(ofSize: 17.0) 41 | label.textColor = UIColor.black.withAlphaComponent(0.85) 42 | label.adjustsFontSizeToFitWidth = true 43 | label.numberOfLines = 3 44 | return label 45 | }() 46 | } 47 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/PKHUDWideBaseView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PKHUDWideBaseView.swift 3 | // PKHUD 4 | // 5 | // Created by Philip Kluz on 6/12/15. 6 | // Copyright (c) 2016 NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | import UIKit 11 | 12 | /// PKHUDWideBaseView provides a wide base view, which you can subclass and add additional views to. 13 | open class PKHUDWideBaseView: UIView { 14 | 15 | static let defaultWideBaseViewFrame = CGRect(origin: CGPoint.zero, size: CGSize(width: 265.0, height: 90.0)) 16 | 17 | public init() { 18 | super.init(frame: PKHUDWideBaseView.defaultWideBaseViewFrame) 19 | } 20 | 21 | public override init(frame: CGRect) { 22 | super.init(frame: frame) 23 | } 24 | 25 | public required init?(coder aDecoder: NSCoder) { 26 | super.init(coder: aDecoder) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/Window.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HUDWindow.swift 3 | // PKHUD 4 | // 5 | // Created by Philip Kluz on 6/16/14. 6 | // Copyright (c) 2016 NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | import UIKit 11 | 12 | /// The window used to display the PKHUD within. Placed atop the applications main window. 13 | internal class ContainerView: UIView { 14 | 15 | internal let frameView: FrameView 16 | internal init(frameView: FrameView = FrameView()) { 17 | self.frameView = frameView 18 | super.init(frame: CGRect.zero) 19 | commonInit() 20 | } 21 | 22 | required init?(coder aDecoder: NSCoder) { 23 | frameView = FrameView() 24 | super.init(coder: aDecoder) 25 | commonInit() 26 | } 27 | 28 | fileprivate func commonInit() { 29 | backgroundColor = UIColor.clear 30 | 31 | addSubview(backgroundView) 32 | addSubview(frameView) 33 | } 34 | 35 | internal override func layoutSubviews() { 36 | super.layoutSubviews() 37 | 38 | frameView.center = center 39 | backgroundView.frame = bounds 40 | } 41 | 42 | internal func showFrameView() { 43 | layer.removeAllAnimations() 44 | frameView.center = center 45 | frameView.alpha = 1.0 46 | isHidden = false 47 | } 48 | 49 | fileprivate var willHide = false 50 | 51 | internal func hideFrameView(animated anim: Bool, completion: ((Bool) -> Void)? = nil) { 52 | let finalize: (_ finished: Bool) -> (Void) = { finished in 53 | self.isHidden = true 54 | self.removeFromSuperview() 55 | self.willHide = false 56 | 57 | completion?(finished) 58 | } 59 | 60 | if isHidden { 61 | return 62 | } 63 | 64 | willHide = true 65 | 66 | if anim { 67 | UIView.animate(withDuration: 0.8, animations: { 68 | self.frameView.alpha = 0.0 69 | self.hideBackground(animated: false) 70 | }, completion: { bool in finalize(true) } ) 71 | } else { 72 | self.frameView.alpha = 0.0 73 | finalize(true) 74 | } 75 | } 76 | 77 | fileprivate let backgroundView: UIView = { 78 | let view = UIView() 79 | view.backgroundColor = UIColor(white:0.0, alpha:0.25) 80 | view.alpha = 0.0 81 | return view 82 | }() 83 | 84 | internal func showBackground(animated anim: Bool) { 85 | if anim { 86 | UIView.animate(withDuration: 0.175, animations: { 87 | self.backgroundView.alpha = 1.0 88 | }) 89 | } else { 90 | backgroundView.alpha = 1.0 91 | } 92 | } 93 | 94 | internal func hideBackground(animated anim: Bool) { 95 | if anim { 96 | UIView.animate(withDuration: 0.65, animations: { 97 | self.backgroundView.alpha = 0.0 98 | }) 99 | } else { 100 | backgroundView.alpha = 0.0 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/PKHUD/WindowRootViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PKHUD.WindowRootViewController.swift 3 | // PKHUD 4 | // 5 | // Created by Philip Kluz on 6/18/14. 6 | // Copyright (c) 2016 NSExceptional. All rights reserved. 7 | // Licensed under the MIT license. 8 | // 9 | 10 | import UIKit 11 | 12 | /// Serves as a configuration relay controller, tapping into the main window's rootViewController settings. 13 | internal class WindowRootViewController: UIViewController { 14 | 15 | internal override var supportedInterfaceOrientations : UIInterfaceOrientationMask { 16 | if let rootViewController = UIApplication.shared.delegate?.window??.rootViewController { 17 | return rootViewController.supportedInterfaceOrientations 18 | } else { 19 | return UIInterfaceOrientationMask.portrait 20 | } 21 | } 22 | 23 | internal override var preferredStatusBarStyle : UIStatusBarStyle { 24 | return self.presentingViewController?.preferredStatusBarStyle ?? UIApplication.shared.statusBarStyle 25 | } 26 | 27 | internal override var prefersStatusBarHidden : Bool { 28 | return self.presentingViewController?.prefersStatusBarHidden ?? UIApplication.shared.isStatusBarHidden 29 | } 30 | 31 | internal override var preferredStatusBarUpdateAnimation : UIStatusBarAnimation { 32 | if let rootViewController = UIApplication.shared.delegate?.window??.rootViewController { 33 | return rootViewController.preferredStatusBarUpdateAnimation 34 | } else { 35 | return .none 36 | } 37 | } 38 | 39 | internal override var shouldAutorotate : Bool { 40 | if let rootViewController = UIApplication.shared.delegate?.window??.rootViewController { 41 | return rootViewController.shouldAutorotate 42 | } else { 43 | return false 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/README.md: -------------------------------------------------------------------------------- 1 | [![License](https://img.shields.io/cocoapods/l/PKHUD.svg?style=flat)](https://cocoapods.org/pods/PKHUD) 2 | [![Platform](https://img.shields.io/cocoapods/p/PKHUD.svg?style=flat)](http://cocoadocs.org/docsets/PKHUD/3.2.1/) 3 | [![CocoaPod](https://img.shields.io/cocoapods/v/PKHUD.svg?style=flat)](https://cocoapods.org/pods/PKHUD) 4 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 5 | ![](https://img.shields.io/badge/Swift 3-compatible-4BC51D.svg?style=flat-square) 6 | 7 | ![PKHUD - Swift and easy](https://raw.githubusercontent.com/pkluz/PKHUD/master/README_hero.png) 8 | 9 | 10 | 11 |
12 |
13 |
14 | A **Swift** based reimplementation of the Apple HUD (Volume, Ringer, Rotation,…) **for iOS 8** and up. 15 |
16 |
17 | ## Features 18 | - Official iOS 8 blur effect via **UIVisualEffectsView**. 19 | - Proper **rotation support**. 20 | - Size / **Device agnostic**. 21 | - Works on top of presented view controllers, alerts,... 22 | - Comes with several *free* resources - Checkmark, Cross, Progress Indicator,… 23 | - …as well as **animated** ones. 24 | - Builds as an **iOS 8 framework**. 25 | 26 | ![PKHUD.gif](https://cloud.githubusercontent.com/assets/1275218/10124182/09f4c406-654f-11e5-9cab-0f2e6f470887.gif) 27 | 28 | ## Installation 29 | **The recommended way is to use CocoaPods.** 30 | 31 | ### CocoaPods 32 | 33 | To install PKHUD for Swift 2 using CocoaPods, include the following in your Podfile 34 | 35 | ```ruby 36 | pod 'PKHUD', '~> 3.0' 37 | ``` 38 | 39 | To install PKHUD for Swift 3.x using CocoaPods, include the following in your Podfile 40 | 41 | ```ruby 42 | pod 'PKHUD', '~> 4.0' 43 | ``` 44 | 45 | ### Carthage 46 | 47 | [Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. 48 | 49 | You can install Carthage with [Homebrew](http://brew.sh/) using the following command: 50 | 51 | ```bash 52 | $ brew update 53 | $ brew install carthage 54 | ``` 55 | 56 | To integrate PKHUD into your Xcode project using Carthage, specify it in your `Cartfile`: 57 | 58 | ```ogdl 59 | github "pkluz/PKHUD" ~> 4.0 60 | ``` 61 | 62 | Run `carthage update` to build the framework and drag the built `PKHUD.framework` into your Xcode project. 63 | 64 | ## How To 65 | 66 | After adding the framework to your project, you need to import the module 67 | ```swift 68 | import PKHUD 69 | ``` 70 | 71 | Now, you can proceed to show an arbitrary HUD (and have it automatically disappear a second later) like this: 72 | ```swift 73 | HUD.flash(.Success, delay: 1.0) 74 | ``` 75 | 76 | _or_ with a completion handler: 77 | 78 | ```swift 79 | HUD.flash(.Success, delay: 1.0) { finished in 80 | // Completion Handler 81 | } 82 | ``` 83 | 84 | alternatively, you can use the more verbose and flexible “plumbing” API: 85 | 86 | ```swift 87 | PKHUD.sharedHUD.contentView = PKHUDSuccessView() 88 | PKHUD.sharedHUD.show() 89 | PKHUD.sharedHUD.hide(afterDelay: 1.0) { success in 90 | // Completion Handler 91 | } 92 | ``` 93 | 94 | You can also hot-swap content views - this can prove useful if you want to display a progress HUD first and transform it into a success or error HUD after an asynchronous operation has finished. 95 | ```swift 96 | HUD.show(.Progress) 97 | 98 | // Now some long running task starts... 99 | delay(2.0) { 100 | // ...and once it finishes we flash the HUD for a second. 101 | HUD.flash(.Success, delay: 1.0) 102 | } 103 | ``` 104 | 105 | Please note that there are _multiple_ types of content views that ship with PKHUD. You can find them as separate files in the project folder as well as in the `ContentViews` group in Xcode. 106 | 107 | ## Communication _(Hat Tip AlamoFire)_ 108 | 109 | - If you **need help**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/pkhud). (Tag 'pkhud') 110 | - If you'd like to **ask a general question**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/pkhud). 111 | - If you **found a bug**, open an issue. 112 | - If you **have a feature request**, open an issue. 113 | - If you **want to contribute**, submit a pull request. 114 | 115 | ## Customization 116 | 117 | There are two properties at your disposal to customize general behavior. 118 | 119 | - `PKHUD.sharedHUD.dimsBackground: Bool` defines whether the background is slightly dimmed when the HUD is shown. 120 | 121 | - `PKHUD.sharedHUD.userInteractionOnUnderlyingViewsEnabled: Bool` defines whether the underlying views respond to touches while the HUD is shown. 122 | 123 | Additionally you are free to create you own custom content views. They can descend from any `UIView` type or the predefined base classes `PKHUDSquareBaseView` and `PKHUDWideBaseView`. 124 | 125 | **Note**: It's neither possible to customize the general look and feel, nor do I plan to add that feature. You are free to provide any content views you wish but the blurring, corner radius and shading will remain the same. 126 | 127 | ## License 128 | 129 | The MIT License (MIT) 130 | 131 | Copyright (c) 2015 Philip Kluz (Philip.Kluz@gmail.com) 132 | 133 | Permission is hereby granted, free of charge, to any person obtaining a copy 134 | of this software and associated documentation files (the "Software"), to deal 135 | in the Software without restriction, including without limitation the rights 136 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 137 | copies of the Software, and to permit persons to whom the Software is 138 | furnished to do so, subject to the following conditions: 139 | 140 | The above copyright notice and this permission notice shall be included in all 141 | copies or substantial portions of the Software. 142 | 143 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 144 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 145 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 146 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 147 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 148 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 149 | SOFTWARE. 150 | -------------------------------------------------------------------------------- /Carthage/Checkouts/PKHUD/README_hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Carthage/Checkouts/PKHUD/README_hero.png -------------------------------------------------------------------------------- /Dust.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E64333B019C3693300BFDD88 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E64333AF19C3693300BFDD88 /* AppDelegate.swift */; }; 11 | E64333B219C3693300BFDD88 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E64333B119C3693300BFDD88 /* ViewController.swift */; }; 12 | E64333B519C3693300BFDD88 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E64333B319C3693300BFDD88 /* Main.storyboard */; }; 13 | E64333B719C3693300BFDD88 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E64333B619C3693300BFDD88 /* Images.xcassets */; }; 14 | E64333BA19C3693300BFDD88 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = E64333B819C3693300BFDD88 /* LaunchScreen.xib */; }; 15 | E64333C619C3693300BFDD88 /* DustTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E64333C519C3693300BFDD88 /* DustTests.swift */; }; 16 | E64FBD701DFB960400C21F68 /* PKHUD.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E64FBD6F1DFB960400C21F68 /* PKHUD.framework */; }; 17 | E64FBD711DFB960400C21F68 /* PKHUD.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E64FBD6F1DFB960400C21F68 /* PKHUD.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 18 | E68F58DD1A388B9900A1BBBB /* MultipeerConnectivity.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E629225219C3696C00CB692F /* MultipeerConnectivity.framework */; }; 19 | E68F58EA1A3897AC00A1BBBB /* CAEmitterLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E68F58E91A3897AC00A1BBBB /* CAEmitterLayer.swift */; }; 20 | E6B661521A26EAF00062D7BC /* MeshNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6B661511A26EAF00062D7BC /* MeshNetwork.swift */; }; 21 | E6DCBE051A808DCF0012E1BC /* LaunchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6DCBE041A808DCF0012E1BC /* LaunchViewController.swift */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | E64333C019C3693300BFDD88 /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = E64333A219C3693300BFDD88 /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = E64333A919C3693300BFDD88; 30 | remoteInfo = Dust; 31 | }; 32 | /* End PBXContainerItemProxy section */ 33 | 34 | /* Begin PBXCopyFilesBuildPhase section */ 35 | E681C4B51A813E9B00CAC0B3 /* Embed Frameworks */ = { 36 | isa = PBXCopyFilesBuildPhase; 37 | buildActionMask = 2147483647; 38 | dstPath = ""; 39 | dstSubfolderSpec = 10; 40 | files = ( 41 | E64FBD711DFB960400C21F68 /* PKHUD.framework in Embed Frameworks */, 42 | ); 43 | name = "Embed Frameworks"; 44 | runOnlyForDeploymentPostprocessing = 0; 45 | }; 46 | /* End PBXCopyFilesBuildPhase section */ 47 | 48 | /* Begin PBXFileReference section */ 49 | E629225219C3696C00CB692F /* MultipeerConnectivity.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MultipeerConnectivity.framework; path = System/Library/Frameworks/MultipeerConnectivity.framework; sourceTree = SDKROOT; }; 50 | E64333AA19C3693300BFDD88 /* Dust.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Dust.app; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | E64333AE19C3693300BFDD88 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | E64333AF19C3693300BFDD88 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 53 | E64333B119C3693300BFDD88 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 54 | E64333B419C3693300BFDD88 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 55 | E64333B619C3693300BFDD88 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 56 | E64333B919C3693300BFDD88 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 57 | E64333BF19C3693300BFDD88 /* DustTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DustTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | E64333C419C3693300BFDD88 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 59 | E64333C519C3693300BFDD88 /* DustTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DustTests.swift; sourceTree = ""; }; 60 | E64FBD6F1DFB960400C21F68 /* PKHUD.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PKHUD.framework; path = Carthage/Build/iOS/PKHUD.framework; sourceTree = ""; }; 61 | E68F58E91A3897AC00A1BBBB /* CAEmitterLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CAEmitterLayer.swift; sourceTree = ""; }; 62 | E6B661511A26EAF00062D7BC /* MeshNetwork.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MeshNetwork.swift; sourceTree = ""; }; 63 | E6DCBE041A808DCF0012E1BC /* LaunchViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LaunchViewController.swift; sourceTree = ""; }; 64 | /* End PBXFileReference section */ 65 | 66 | /* Begin PBXFrameworksBuildPhase section */ 67 | E64333A719C3693300BFDD88 /* Frameworks */ = { 68 | isa = PBXFrameworksBuildPhase; 69 | buildActionMask = 2147483647; 70 | files = ( 71 | E68F58DD1A388B9900A1BBBB /* MultipeerConnectivity.framework in Frameworks */, 72 | E64FBD701DFB960400C21F68 /* PKHUD.framework in Frameworks */, 73 | ); 74 | runOnlyForDeploymentPostprocessing = 0; 75 | }; 76 | E64333BC19C3693300BFDD88 /* Frameworks */ = { 77 | isa = PBXFrameworksBuildPhase; 78 | buildActionMask = 2147483647; 79 | files = ( 80 | ); 81 | runOnlyForDeploymentPostprocessing = 0; 82 | }; 83 | /* End PBXFrameworksBuildPhase section */ 84 | 85 | /* Begin PBXGroup section */ 86 | E64333A119C3693300BFDD88 = { 87 | isa = PBXGroup; 88 | children = ( 89 | E64333AC19C3693300BFDD88 /* Dust */, 90 | E64333C219C3693300BFDD88 /* DustTests */, 91 | E68F58DC1A388B6100A1BBBB /* Frameworks */, 92 | E64333AB19C3693300BFDD88 /* Products */, 93 | ); 94 | sourceTree = ""; 95 | }; 96 | E64333AB19C3693300BFDD88 /* Products */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | E64333AA19C3693300BFDD88 /* Dust.app */, 100 | E64333BF19C3693300BFDD88 /* DustTests.xctest */, 101 | ); 102 | name = Products; 103 | sourceTree = ""; 104 | }; 105 | E64333AC19C3693300BFDD88 /* Dust */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | E64333AF19C3693300BFDD88 /* AppDelegate.swift */, 109 | E64333B119C3693300BFDD88 /* ViewController.swift */, 110 | E6DCBE041A808DCF0012E1BC /* LaunchViewController.swift */, 111 | E6B661511A26EAF00062D7BC /* MeshNetwork.swift */, 112 | E68F58E91A3897AC00A1BBBB /* CAEmitterLayer.swift */, 113 | E64333B319C3693300BFDD88 /* Main.storyboard */, 114 | E64333B619C3693300BFDD88 /* Images.xcassets */, 115 | E64333B819C3693300BFDD88 /* LaunchScreen.xib */, 116 | E64333AD19C3693300BFDD88 /* Supporting Files */, 117 | ); 118 | path = Dust; 119 | sourceTree = ""; 120 | }; 121 | E64333AD19C3693300BFDD88 /* Supporting Files */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | E64333AE19C3693300BFDD88 /* Info.plist */, 125 | ); 126 | name = "Supporting Files"; 127 | sourceTree = ""; 128 | }; 129 | E64333C219C3693300BFDD88 /* DustTests */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | E64333C519C3693300BFDD88 /* DustTests.swift */, 133 | E64333C319C3693300BFDD88 /* Supporting Files */, 134 | ); 135 | path = DustTests; 136 | sourceTree = ""; 137 | }; 138 | E64333C319C3693300BFDD88 /* Supporting Files */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | E64333C419C3693300BFDD88 /* Info.plist */, 142 | ); 143 | name = "Supporting Files"; 144 | sourceTree = ""; 145 | }; 146 | E68F58DC1A388B6100A1BBBB /* Frameworks */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | E64FBD6F1DFB960400C21F68 /* PKHUD.framework */, 150 | E629225219C3696C00CB692F /* MultipeerConnectivity.framework */, 151 | ); 152 | name = Frameworks; 153 | sourceTree = ""; 154 | }; 155 | /* End PBXGroup section */ 156 | 157 | /* Begin PBXNativeTarget section */ 158 | E64333A919C3693300BFDD88 /* Dust */ = { 159 | isa = PBXNativeTarget; 160 | buildConfigurationList = E64333C919C3693300BFDD88 /* Build configuration list for PBXNativeTarget "Dust" */; 161 | buildPhases = ( 162 | E64333A619C3693300BFDD88 /* Sources */, 163 | E64333A719C3693300BFDD88 /* Frameworks */, 164 | E64333A819C3693300BFDD88 /* Resources */, 165 | E681C4B51A813E9B00CAC0B3 /* Embed Frameworks */, 166 | ); 167 | buildRules = ( 168 | ); 169 | dependencies = ( 170 | ); 171 | name = Dust; 172 | productName = Dust; 173 | productReference = E64333AA19C3693300BFDD88 /* Dust.app */; 174 | productType = "com.apple.product-type.application"; 175 | }; 176 | E64333BE19C3693300BFDD88 /* DustTests */ = { 177 | isa = PBXNativeTarget; 178 | buildConfigurationList = E64333CC19C3693300BFDD88 /* Build configuration list for PBXNativeTarget "DustTests" */; 179 | buildPhases = ( 180 | E64333BB19C3693300BFDD88 /* Sources */, 181 | E64333BC19C3693300BFDD88 /* Frameworks */, 182 | E64333BD19C3693300BFDD88 /* Resources */, 183 | ); 184 | buildRules = ( 185 | ); 186 | dependencies = ( 187 | E64333C119C3693300BFDD88 /* PBXTargetDependency */, 188 | ); 189 | name = DustTests; 190 | productName = DustTests; 191 | productReference = E64333BF19C3693300BFDD88 /* DustTests.xctest */; 192 | productType = "com.apple.product-type.bundle.unit-test"; 193 | }; 194 | /* End PBXNativeTarget section */ 195 | 196 | /* Begin PBXProject section */ 197 | E64333A219C3693300BFDD88 /* Project object */ = { 198 | isa = PBXProject; 199 | attributes = { 200 | LastUpgradeCheck = 0810; 201 | ORGANIZATIONNAME = joeblau; 202 | TargetAttributes = { 203 | E64333A919C3693300BFDD88 = { 204 | CreatedOnToolsVersion = 6.0; 205 | DevelopmentTeam = K78G42H4U2; 206 | LastSwiftMigration = 0810; 207 | }; 208 | E64333BE19C3693300BFDD88 = { 209 | CreatedOnToolsVersion = 6.0; 210 | LastSwiftMigration = 0810; 211 | TestTargetID = E64333A919C3693300BFDD88; 212 | }; 213 | }; 214 | }; 215 | buildConfigurationList = E64333A519C3693300BFDD88 /* Build configuration list for PBXProject "Dust" */; 216 | compatibilityVersion = "Xcode 3.2"; 217 | developmentRegion = English; 218 | hasScannedForEncodings = 0; 219 | knownRegions = ( 220 | en, 221 | Base, 222 | ); 223 | mainGroup = E64333A119C3693300BFDD88; 224 | productRefGroup = E64333AB19C3693300BFDD88 /* Products */; 225 | projectDirPath = ""; 226 | projectRoot = ""; 227 | targets = ( 228 | E64333A919C3693300BFDD88 /* Dust */, 229 | E64333BE19C3693300BFDD88 /* DustTests */, 230 | ); 231 | }; 232 | /* End PBXProject section */ 233 | 234 | /* Begin PBXResourcesBuildPhase section */ 235 | E64333A819C3693300BFDD88 /* Resources */ = { 236 | isa = PBXResourcesBuildPhase; 237 | buildActionMask = 2147483647; 238 | files = ( 239 | E64333B519C3693300BFDD88 /* Main.storyboard in Resources */, 240 | E64333BA19C3693300BFDD88 /* LaunchScreen.xib in Resources */, 241 | E64333B719C3693300BFDD88 /* Images.xcassets in Resources */, 242 | ); 243 | runOnlyForDeploymentPostprocessing = 0; 244 | }; 245 | E64333BD19C3693300BFDD88 /* Resources */ = { 246 | isa = PBXResourcesBuildPhase; 247 | buildActionMask = 2147483647; 248 | files = ( 249 | ); 250 | runOnlyForDeploymentPostprocessing = 0; 251 | }; 252 | /* End PBXResourcesBuildPhase section */ 253 | 254 | /* Begin PBXSourcesBuildPhase section */ 255 | E64333A619C3693300BFDD88 /* Sources */ = { 256 | isa = PBXSourcesBuildPhase; 257 | buildActionMask = 2147483647; 258 | files = ( 259 | E68F58EA1A3897AC00A1BBBB /* CAEmitterLayer.swift in Sources */, 260 | E6DCBE051A808DCF0012E1BC /* LaunchViewController.swift in Sources */, 261 | E64333B219C3693300BFDD88 /* ViewController.swift in Sources */, 262 | E64333B019C3693300BFDD88 /* AppDelegate.swift in Sources */, 263 | E6B661521A26EAF00062D7BC /* MeshNetwork.swift in Sources */, 264 | ); 265 | runOnlyForDeploymentPostprocessing = 0; 266 | }; 267 | E64333BB19C3693300BFDD88 /* Sources */ = { 268 | isa = PBXSourcesBuildPhase; 269 | buildActionMask = 2147483647; 270 | files = ( 271 | E64333C619C3693300BFDD88 /* DustTests.swift in Sources */, 272 | ); 273 | runOnlyForDeploymentPostprocessing = 0; 274 | }; 275 | /* End PBXSourcesBuildPhase section */ 276 | 277 | /* Begin PBXTargetDependency section */ 278 | E64333C119C3693300BFDD88 /* PBXTargetDependency */ = { 279 | isa = PBXTargetDependency; 280 | target = E64333A919C3693300BFDD88 /* Dust */; 281 | targetProxy = E64333C019C3693300BFDD88 /* PBXContainerItemProxy */; 282 | }; 283 | /* End PBXTargetDependency section */ 284 | 285 | /* Begin PBXVariantGroup section */ 286 | E64333B319C3693300BFDD88 /* Main.storyboard */ = { 287 | isa = PBXVariantGroup; 288 | children = ( 289 | E64333B419C3693300BFDD88 /* Base */, 290 | ); 291 | name = Main.storyboard; 292 | sourceTree = ""; 293 | }; 294 | E64333B819C3693300BFDD88 /* LaunchScreen.xib */ = { 295 | isa = PBXVariantGroup; 296 | children = ( 297 | E64333B919C3693300BFDD88 /* Base */, 298 | ); 299 | name = LaunchScreen.xib; 300 | sourceTree = ""; 301 | }; 302 | /* End PBXVariantGroup section */ 303 | 304 | /* Begin XCBuildConfiguration section */ 305 | E64333C719C3693300BFDD88 /* Debug */ = { 306 | isa = XCBuildConfiguration; 307 | buildSettings = { 308 | ALWAYS_SEARCH_USER_PATHS = NO; 309 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 310 | CLANG_CXX_LIBRARY = "libc++"; 311 | CLANG_ENABLE_MODULES = YES; 312 | CLANG_ENABLE_OBJC_ARC = YES; 313 | CLANG_WARN_BOOL_CONVERSION = YES; 314 | CLANG_WARN_CONSTANT_CONVERSION = YES; 315 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 316 | CLANG_WARN_EMPTY_BODY = YES; 317 | CLANG_WARN_ENUM_CONVERSION = YES; 318 | CLANG_WARN_INFINITE_RECURSION = YES; 319 | CLANG_WARN_INT_CONVERSION = YES; 320 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 321 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 322 | CLANG_WARN_UNREACHABLE_CODE = YES; 323 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 324 | CODE_SIGN_IDENTITY = "iPhone Developer"; 325 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 326 | COPY_PHASE_STRIP = NO; 327 | ENABLE_STRICT_OBJC_MSGSEND = YES; 328 | ENABLE_TESTABILITY = YES; 329 | GCC_C_LANGUAGE_STANDARD = gnu99; 330 | GCC_DYNAMIC_NO_PIC = NO; 331 | GCC_NO_COMMON_BLOCKS = YES; 332 | GCC_OPTIMIZATION_LEVEL = 0; 333 | GCC_PREPROCESSOR_DEFINITIONS = ( 334 | "DEBUG=1", 335 | "$(inherited)", 336 | ); 337 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 338 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 339 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 340 | GCC_WARN_UNDECLARED_SELECTOR = YES; 341 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 342 | GCC_WARN_UNUSED_FUNCTION = YES; 343 | GCC_WARN_UNUSED_VARIABLE = YES; 344 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 345 | MTL_ENABLE_DEBUG_INFO = YES; 346 | ONLY_ACTIVE_ARCH = YES; 347 | SDKROOT = iphoneos; 348 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 349 | TARGETED_DEVICE_FAMILY = "1,2"; 350 | }; 351 | name = Debug; 352 | }; 353 | E64333C819C3693300BFDD88 /* Release */ = { 354 | isa = XCBuildConfiguration; 355 | buildSettings = { 356 | ALWAYS_SEARCH_USER_PATHS = NO; 357 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 358 | CLANG_CXX_LIBRARY = "libc++"; 359 | CLANG_ENABLE_MODULES = YES; 360 | CLANG_ENABLE_OBJC_ARC = YES; 361 | CLANG_WARN_BOOL_CONVERSION = YES; 362 | CLANG_WARN_CONSTANT_CONVERSION = YES; 363 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 364 | CLANG_WARN_EMPTY_BODY = YES; 365 | CLANG_WARN_ENUM_CONVERSION = YES; 366 | CLANG_WARN_INFINITE_RECURSION = YES; 367 | CLANG_WARN_INT_CONVERSION = YES; 368 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 369 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 370 | CLANG_WARN_UNREACHABLE_CODE = YES; 371 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 372 | CODE_SIGN_IDENTITY = "iPhone Developer"; 373 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 374 | COPY_PHASE_STRIP = YES; 375 | ENABLE_NS_ASSERTIONS = NO; 376 | ENABLE_STRICT_OBJC_MSGSEND = YES; 377 | GCC_C_LANGUAGE_STANDARD = gnu99; 378 | GCC_NO_COMMON_BLOCKS = YES; 379 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 380 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 381 | GCC_WARN_UNDECLARED_SELECTOR = YES; 382 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 383 | GCC_WARN_UNUSED_FUNCTION = YES; 384 | GCC_WARN_UNUSED_VARIABLE = YES; 385 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 386 | MTL_ENABLE_DEBUG_INFO = NO; 387 | SDKROOT = iphoneos; 388 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 389 | TARGETED_DEVICE_FAMILY = "1,2"; 390 | VALIDATE_PRODUCT = YES; 391 | }; 392 | name = Release; 393 | }; 394 | E64333CA19C3693300BFDD88 /* Debug */ = { 395 | isa = XCBuildConfiguration; 396 | buildSettings = { 397 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 398 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 399 | CODE_SIGN_IDENTITY = "iPhone Developer"; 400 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 401 | FRAMEWORK_SEARCH_PATHS = ( 402 | "$(inherited)", 403 | "$(PROJECT_DIR)", 404 | "$(PROJECT_DIR)/Dust", 405 | "$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/PKHUD-dfbeczlgtctjtpdeoyugbzevbvpr/Build/Products/Debug-iphoneos", 406 | "$(PROJECT_DIR)/Carthage/Build/iOS", 407 | ); 408 | INFOPLIST_FILE = Dust/Info.plist; 409 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 410 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 411 | PRODUCT_BUNDLE_IDENTIFIER = "com.joeblau.$(PRODUCT_NAME:rfc1034identifier)"; 412 | PRODUCT_NAME = "$(TARGET_NAME)"; 413 | PROVISIONING_PROFILE = ""; 414 | SWIFT_VERSION = 3.0; 415 | }; 416 | name = Debug; 417 | }; 418 | E64333CB19C3693300BFDD88 /* Release */ = { 419 | isa = XCBuildConfiguration; 420 | buildSettings = { 421 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 422 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 423 | CODE_SIGN_IDENTITY = "iPhone Developer"; 424 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 425 | FRAMEWORK_SEARCH_PATHS = ( 426 | "$(inherited)", 427 | "$(PROJECT_DIR)", 428 | "$(PROJECT_DIR)/Dust", 429 | "$(USER_LIBRARY_DIR)/Developer/Xcode/DerivedData/PKHUD-dfbeczlgtctjtpdeoyugbzevbvpr/Build/Products/Debug-iphoneos", 430 | "$(PROJECT_DIR)/Carthage/Build/iOS", 431 | ); 432 | INFOPLIST_FILE = Dust/Info.plist; 433 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 434 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 435 | PRODUCT_BUNDLE_IDENTIFIER = "com.joeblau.$(PRODUCT_NAME:rfc1034identifier)"; 436 | PRODUCT_NAME = "$(TARGET_NAME)"; 437 | PROVISIONING_PROFILE = ""; 438 | SWIFT_VERSION = 3.0; 439 | }; 440 | name = Release; 441 | }; 442 | E64333CD19C3693300BFDD88 /* Debug */ = { 443 | isa = XCBuildConfiguration; 444 | buildSettings = { 445 | BUNDLE_LOADER = "$(TEST_HOST)"; 446 | FRAMEWORK_SEARCH_PATHS = ( 447 | "$(SDKROOT)/Developer/Library/Frameworks", 448 | "$(inherited)", 449 | ); 450 | GCC_PREPROCESSOR_DEFINITIONS = ( 451 | "DEBUG=1", 452 | "$(inherited)", 453 | ); 454 | INFOPLIST_FILE = DustTests/Info.plist; 455 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 456 | PRODUCT_BUNDLE_IDENTIFIER = "com.joeblau.$(PRODUCT_NAME:rfc1034identifier)"; 457 | PRODUCT_NAME = "$(TARGET_NAME)"; 458 | SWIFT_VERSION = 3.0; 459 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Dust.app/Dust"; 460 | }; 461 | name = Debug; 462 | }; 463 | E64333CE19C3693300BFDD88 /* Release */ = { 464 | isa = XCBuildConfiguration; 465 | buildSettings = { 466 | BUNDLE_LOADER = "$(TEST_HOST)"; 467 | FRAMEWORK_SEARCH_PATHS = ( 468 | "$(SDKROOT)/Developer/Library/Frameworks", 469 | "$(inherited)", 470 | ); 471 | INFOPLIST_FILE = DustTests/Info.plist; 472 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 473 | PRODUCT_BUNDLE_IDENTIFIER = "com.joeblau.$(PRODUCT_NAME:rfc1034identifier)"; 474 | PRODUCT_NAME = "$(TARGET_NAME)"; 475 | SWIFT_VERSION = 3.0; 476 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Dust.app/Dust"; 477 | }; 478 | name = Release; 479 | }; 480 | /* End XCBuildConfiguration section */ 481 | 482 | /* Begin XCConfigurationList section */ 483 | E64333A519C3693300BFDD88 /* Build configuration list for PBXProject "Dust" */ = { 484 | isa = XCConfigurationList; 485 | buildConfigurations = ( 486 | E64333C719C3693300BFDD88 /* Debug */, 487 | E64333C819C3693300BFDD88 /* Release */, 488 | ); 489 | defaultConfigurationIsVisible = 0; 490 | defaultConfigurationName = Release; 491 | }; 492 | E64333C919C3693300BFDD88 /* Build configuration list for PBXNativeTarget "Dust" */ = { 493 | isa = XCConfigurationList; 494 | buildConfigurations = ( 495 | E64333CA19C3693300BFDD88 /* Debug */, 496 | E64333CB19C3693300BFDD88 /* Release */, 497 | ); 498 | defaultConfigurationIsVisible = 0; 499 | defaultConfigurationName = Release; 500 | }; 501 | E64333CC19C3693300BFDD88 /* Build configuration list for PBXNativeTarget "DustTests" */ = { 502 | isa = XCConfigurationList; 503 | buildConfigurations = ( 504 | E64333CD19C3693300BFDD88 /* Debug */, 505 | E64333CE19C3693300BFDD88 /* Release */, 506 | ); 507 | defaultConfigurationIsVisible = 0; 508 | defaultConfigurationName = Release; 509 | }; 510 | /* End XCConfigurationList section */ 511 | }; 512 | rootObject = E64333A219C3693300BFDD88 /* Project object */; 513 | } 514 | -------------------------------------------------------------------------------- /Dust.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Dust.xcodeproj/project.xcworkspace/xcshareddata/Dust.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 247A4383-6D1C-4AA5-8AC8-1769FB96780B 9 | IDESourceControlProjectName 10 | Dust 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 4EA48C4418C0D37C936EB709C50F03661DB187D9 14 | github.com:pkluz/PKHUD.git 15 | 5ACCDF85FC48F2B46433C61E9A834BF249BA78BB 16 | github.com:joeblau/Dust.git 17 | 18 | IDESourceControlProjectPath 19 | Dust.xcodeproj 20 | IDESourceControlProjectRelativeInstallPathDictionary 21 | 22 | 4EA48C4418C0D37C936EB709C50F03661DB187D9 23 | ../../../../../workspaces/github/swiftxcode/PKHUD 24 | 5ACCDF85FC48F2B46433C61E9A834BF249BA78BB 25 | ../.. 26 | 27 | IDESourceControlProjectURL 28 | github.com:joeblau/Dust.git 29 | IDESourceControlProjectVersion 30 | 111 31 | IDESourceControlProjectWCCIdentifier 32 | 5ACCDF85FC48F2B46433C61E9A834BF249BA78BB 33 | IDESourceControlProjectWCConfigurations 34 | 35 | 36 | IDESourceControlRepositoryExtensionIdentifierKey 37 | public.vcs.git 38 | IDESourceControlWCCIdentifierKey 39 | 5ACCDF85FC48F2B46433C61E9A834BF249BA78BB 40 | IDESourceControlWCCName 41 | Dust 42 | 43 | 44 | IDESourceControlRepositoryExtensionIdentifierKey 45 | public.vcs.git 46 | IDESourceControlWCCIdentifierKey 47 | 4EA48C4418C0D37C936EB709C50F03661DB187D9 48 | IDESourceControlWCCName 49 | PKHUD 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Dust.xcodeproj/project.xcworkspace/xcshareddata/Dust.xcscmblueprint: -------------------------------------------------------------------------------- 1 | { 2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "5ACCDF85FC48F2B46433C61E9A834BF249BA78BB", 3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { 4 | 5 | }, 6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { 7 | "5ACCDF85FC48F2B46433C61E9A834BF249BA78BB" : 0, 8 | "4EA48C4418C0D37C936EB709C50F03661DB187D9" : 0 9 | }, 10 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "247A4383-6D1C-4AA5-8AC8-1769FB96780B", 11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { 12 | "5ACCDF85FC48F2B46433C61E9A834BF249BA78BB" : "Dust-iOS\/", 13 | "4EA48C4418C0D37C936EB709C50F03661DB187D9" : "workspaces\/github\/swiftxcode\/PKHUD" 14 | }, 15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "Dust", 16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204, 17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Dust.xcodeproj", 18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ 19 | { 20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:pkluz\/PKHUD.git", 21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "4EA48C4418C0D37C936EB709C50F03661DB187D9" 23 | }, 24 | { 25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:joeblau\/Dust.git", 26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "5ACCDF85FC48F2B46433C61E9A834BF249BA78BB" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /Dust.xcodeproj/project.xcworkspace/xcuserdata/joeblau.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust.xcodeproj/project.xcworkspace/xcuserdata/joeblau.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Dust.xcodeproj/xcuserdata/joeblau.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 18 | 19 | 20 | 22 | 32 | 33 | 34 | 36 | 46 | 47 | 48 | 50 | 60 | 61 | 62 | 64 | 74 | 75 | 76 | 78 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /Dust.xcodeproj/xcuserdata/joeblau.xcuserdatad/xcschemes/Dust.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 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 94 | 100 | 101 | 102 | 103 | 105 | 106 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /Dust.xcodeproj/xcuserdata/joeblau.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Dust.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | E64333A919C3693300BFDD88 16 | 17 | primary 18 | 19 | 20 | E64333BE19C3693300BFDD88 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Dust.xcodeproj/xcuserdata/josephblau.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /Dust.xcodeproj/xcuserdata/josephblau.xcuserdatad/xcschemes/Dust.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 71 | 77 | 78 | 79 | 80 | 81 | 87 | 88 | 89 | 90 | 91 | 92 | 102 | 104 | 110 | 111 | 112 | 113 | 114 | 115 | 121 | 123 | 129 | 130 | 131 | 132 | 134 | 135 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /Dust.xcodeproj/xcuserdata/josephblau.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Dust.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | PKHUD.xcscheme 13 | 14 | orderHint 15 | 1 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | E64333A919C3693300BFDD88 21 | 22 | primary 23 | 24 | 25 | E64333BE19C3693300BFDD88 26 | 27 | primary 28 | 29 | 30 | E681C4831A813DA100CAC0B3 31 | 32 | primary 33 | 34 | 35 | E681C48D1A813DA200CAC0B3 36 | 37 | primary 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Dust/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Dust 4 | // 5 | // Created by Joe Blau on 9/12/14. 6 | // Copyright (c) 2014 joeblau. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 17 | return true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Dust/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Dust/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 42 | 48 | 49 | 50 | 51 | 55 | 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 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /Dust/CAEmitterLayer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CAEmitterLayer.swift 3 | // Dust 4 | // 5 | // Created by Joe Blau on 12/10/14. 6 | // Copyright (c) 2014 joeblau. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension CAEmitterLayer { 12 | convenience init(emitterColor: UIColor!) { 13 | self.init() 14 | emitterPosition = CGPoint(x: -100,y: -100) 15 | emitterSize = CGSize(width: 60.0,height: 1) 16 | emitterMode = kCAEmitterLayerOutline 17 | emitterShape = kCAEmitterLayerPoint 18 | renderMode = kCAEmitterLayerAdditive 19 | shadowOpacity = 0.0 20 | shadowRadius = 0.0 21 | shadowOffset = CGSize(width: 0,height: 0) 22 | shadowColor = UIColor.white.cgColor 23 | 24 | let emitterCell = CAEmitterCell() 25 | emitterCell.name = "dustCell" 26 | emitterCell.beginTime = CACurrentMediaTime() 27 | emitterCell.birthRate = 1000 28 | emitterCell.lifetime = 6.0 29 | emitterCell.lifetimeRange = 0.5 30 | emitterCell.color = emitterColor.cgColor 31 | emitterCell.redSpeed = 0.000 32 | emitterCell.greenSpeed = 0.000 33 | emitterCell.blueSpeed = 0.000 34 | emitterCell.alphaSpeed = 0.000 35 | emitterCell.redRange = 0.581 36 | emitterCell.greenRange = 0.000 37 | emitterCell.blueRange = 0.000 38 | emitterCell.alphaRange = 0.000 39 | emitterCell.contents = UIImage(named: "particle")?.cgImage 40 | emitterCell.emissionRange = CGFloat(2.000*M_PI) 41 | emitterCell.emissionLatitude = CGFloat(0.000*M_PI) 42 | emitterCell.emissionLongitude = CGFloat(0.000*M_PI) 43 | emitterCell.velocity = 1 44 | emitterCell.velocityRange = 1 45 | emitterCell.xAcceleration = 0 46 | emitterCell.yAcceleration = 0 47 | emitterCell.spin = CGFloat(0.0*M_PI) 48 | emitterCell.spinRange = CGFloat(0.01*M_PI) 49 | emitterCell.scale = 3.0/UIScreen.main.scale 50 | emitterCell.scaleSpeed = 0.0 51 | emitterCell.scaleRange = 5.0 52 | 53 | emitterCells = [emitterCell] 54 | } 55 | 56 | func getEmitterCell(_ idx: Int) -> CAEmitterCell { 57 | return emitterCells![idx] as CAEmitterCell 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Dust/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "size" : "20x20", 10 | "idiom" : "iphone", 11 | "filename" : "Icon-Small-60.png", 12 | "scale" : "3x" 13 | }, 14 | { 15 | "size" : "29x29", 16 | "idiom" : "iphone", 17 | "filename" : "Icon-Small@2x.png", 18 | "scale" : "2x" 19 | }, 20 | { 21 | "size" : "29x29", 22 | "idiom" : "iphone", 23 | "filename" : "Icon-Small@3x.png", 24 | "scale" : "3x" 25 | }, 26 | { 27 | "size" : "40x40", 28 | "idiom" : "iphone", 29 | "filename" : "Icon-Small-40@2x.png", 30 | "scale" : "2x" 31 | }, 32 | { 33 | "size" : "40x40", 34 | "idiom" : "iphone", 35 | "filename" : "Icon-Small-60@2x.png", 36 | "scale" : "3x" 37 | }, 38 | { 39 | "size" : "60x60", 40 | "idiom" : "iphone", 41 | "filename" : "Icon-60@2x.png", 42 | "scale" : "2x" 43 | }, 44 | { 45 | "size" : "60x60", 46 | "idiom" : "iphone", 47 | "filename" : "Icon-60@3x.png", 48 | "scale" : "3x" 49 | }, 50 | { 51 | "idiom" : "ipad", 52 | "size" : "20x20", 53 | "scale" : "1x" 54 | }, 55 | { 56 | "idiom" : "ipad", 57 | "size" : "20x20", 58 | "scale" : "2x" 59 | }, 60 | { 61 | "size" : "29x29", 62 | "idiom" : "ipad", 63 | "filename" : "Icon-Small.png", 64 | "scale" : "1x" 65 | }, 66 | { 67 | "size" : "29x29", 68 | "idiom" : "ipad", 69 | "filename" : "Icon-Small@2x-1.png", 70 | "scale" : "2x" 71 | }, 72 | { 73 | "idiom" : "ipad", 74 | "size" : "40x40", 75 | "scale" : "1x" 76 | }, 77 | { 78 | "size" : "40x40", 79 | "idiom" : "ipad", 80 | "filename" : "Icon-Small-40@2x-1.png", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "size" : "76x76", 85 | "idiom" : "ipad", 86 | "filename" : "Icon-76.png", 87 | "scale" : "1x" 88 | }, 89 | { 90 | "size" : "76x76", 91 | "idiom" : "ipad", 92 | "filename" : "Icon-76@2x.png", 93 | "scale" : "2x" 94 | }, 95 | { 96 | "size" : "83.5x83.5", 97 | "idiom" : "ipad", 98 | "filename" : "Icon-83.5@2x.png", 99 | "scale" : "2x" 100 | } 101 | ], 102 | "info" : { 103 | "version" : 1, 104 | "author" : "xcode" 105 | } 106 | } -------------------------------------------------------------------------------- /Dust/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /Dust/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/AppIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /Dust/Images.xcassets/AppIcon.appiconset/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/AppIcon.appiconset/Icon-76.png -------------------------------------------------------------------------------- /Dust/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/AppIcon.appiconset/Icon-76@2x.png -------------------------------------------------------------------------------- /Dust/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/AppIcon.appiconset/Icon-83.5@2x.png -------------------------------------------------------------------------------- /Dust/Images.xcassets/AppIcon.appiconset/Icon-Small-40@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/AppIcon.appiconset/Icon-Small-40@2x-1.png -------------------------------------------------------------------------------- /Dust/Images.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/AppIcon.appiconset/Icon-Small-40@2x.png -------------------------------------------------------------------------------- /Dust/Images.xcassets/AppIcon.appiconset/Icon-Small-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/AppIcon.appiconset/Icon-Small-60.png -------------------------------------------------------------------------------- /Dust/Images.xcassets/AppIcon.appiconset/Icon-Small-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/AppIcon.appiconset/Icon-Small-60@2x.png -------------------------------------------------------------------------------- /Dust/Images.xcassets/AppIcon.appiconset/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/AppIcon.appiconset/Icon-Small.png -------------------------------------------------------------------------------- /Dust/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/AppIcon.appiconset/Icon-Small@2x-1.png -------------------------------------------------------------------------------- /Dust/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/AppIcon.appiconset/Icon-Small@2x.png -------------------------------------------------------------------------------- /Dust/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/AppIcon.appiconset/Icon-Small@3x.png -------------------------------------------------------------------------------- /Dust/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Dust/Images.xcassets/Dust.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "Dust.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "Dust@2x.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "Dust@3x.png" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Dust/Images.xcassets/Dust.imageset/Dust.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/Dust.imageset/Dust.png -------------------------------------------------------------------------------- /Dust/Images.xcassets/Dust.imageset/Dust@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/Dust.imageset/Dust@2x.png -------------------------------------------------------------------------------- /Dust/Images.xcassets/Dust.imageset/Dust@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/Dust.imageset/Dust@3x.png -------------------------------------------------------------------------------- /Dust/Images.xcassets/connect.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "connect.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Dust/Images.xcassets/connect.imageset/connect.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/connect.imageset/connect.pdf -------------------------------------------------------------------------------- /Dust/Images.xcassets/disconnect.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "disconnect.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Dust/Images.xcassets/disconnect.imageset/disconnect.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/disconnect.imageset/disconnect.pdf -------------------------------------------------------------------------------- /Dust/Images.xcassets/double-tap.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "double-tap.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Dust/Images.xcassets/double-tap.imageset/double-tap.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/double-tap.imageset/double-tap.pdf -------------------------------------------------------------------------------- /Dust/Images.xcassets/free-drag.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "free-drag.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /Dust/Images.xcassets/free-drag.imageset/free-drag.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/free-drag.imageset/free-drag.pdf -------------------------------------------------------------------------------- /Dust/Images.xcassets/particle.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "particle.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "particle@2x.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Dust/Images.xcassets/particle.imageset/particle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/particle.imageset/particle.png -------------------------------------------------------------------------------- /Dust/Images.xcassets/particle.imageset/particle@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/Dust/Images.xcassets/particle.imageset/particle@2x.png -------------------------------------------------------------------------------- /Dust/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 | 2 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UIStatusBarHidden 34 | 35 | UIStatusBarStyle 36 | UIStatusBarStyleLightContent 37 | UIStatusBarTintParameters 38 | 39 | UINavigationBar 40 | 41 | Style 42 | UIBarStyleDefault 43 | Translucent 44 | 45 | 46 | 47 | UISupportedInterfaceOrientations 48 | 49 | UIInterfaceOrientationPortrait 50 | UIInterfaceOrientationLandscapeRight 51 | UIInterfaceOrientationLandscapeLeft 52 | 53 | UISupportedInterfaceOrientations~ipad 54 | 55 | UIInterfaceOrientationPortrait 56 | UIInterfaceOrientationPortraitUpsideDown 57 | UIInterfaceOrientationLandscapeLeft 58 | UIInterfaceOrientationLandscapeRight 59 | 60 | UIViewControllerBasedStatusBarAppearance 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /Dust/LaunchViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LaunchViewController.swift 3 | // Dust 4 | // 5 | // Created by Joe Blau on 2/2/15. 6 | // Copyright (c) 2015 joeblau. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | final class LaunchViewController: UIViewController { 12 | private var emitters = [CAEmitterLayer]() 13 | private var dispatchToken: Int = 0 14 | @IBOutlet weak var visualEffectView: UIVisualEffectView! 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | UIApplication.shared.setStatusBarHidden(true, with: .fade) 19 | 20 | let tapGesture = UITapGestureRecognizer(target: self, action: #selector(LaunchViewController.handleTapGesture(_:))) 21 | tapGesture.numberOfTapsRequired = 1 22 | view.addGestureRecognizer(tapGesture) 23 | 24 | _ = DustColors.colors.map { 25 | let (x,y,width,height) = (CGFloat(-20.0),CGFloat(-20.0),self.view.bounds.width+40.0,self.view.bounds.height+40.0) 26 | let oneSixth = CGFloat(width/6) 27 | 28 | let launchEmitter = CAEmitterLayer(emitterColor: $0.uiColor) 29 | launchEmitter.emitterShape = kCAEmitterLayerRectangle 30 | launchEmitter.emitterPosition = CGPoint(x: (CGFloat($0.rawValue) * oneSixth) + x + (oneSixth/2), y: (height/2) + y) 31 | launchEmitter.emitterMode = kCAEmitterLayerVolume 32 | launchEmitter.emitterSize = CGSize(width: width/6, height: height) 33 | launchEmitter.seed = arc4random() 34 | let emitterCell = launchEmitter.getEmitterCell(0) 35 | 36 | emitterCell.birthRate = 0.01 * Float(width/6) * Float(height) * Float(UIScreen.main.scale) 37 | emitterCell.lifetimeRange = 3 38 | emitterCell.emissionRange = CGFloat(2.000*M_PI) 39 | emitterCell.emissionLatitude = CGFloat(-1.000*M_PI) 40 | emitterCell.emissionLongitude = CGFloat(-1.000*M_PI) 41 | emitterCell.velocity = 40 42 | emitterCell.velocityRange = 70 43 | emitterCell.scale = 5.0/UIScreen.main.scale 44 | emitterCell.scaleRange = 2.0 45 | 46 | emitters.append(launchEmitter) 47 | view.layer.insertSublayer(launchEmitter, at: 0) 48 | } 49 | } 50 | 51 | func drawAppIcon() { 52 | let dustView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 250)) 53 | 54 | let dPath = UIBezierPath() 55 | dPath.move(to: CGPoint(x: 68.73, y: 200)) 56 | dPath.addCurve(to: CGPoint(x: 137.04, y: 174.37), controlPoint1: CGPoint(x: 98.97, y: 199.25), controlPoint2: CGPoint(x: 121.74, y: 190.71)) 57 | dPath.addCurve(to: CGPoint(x: 160, y: 100), controlPoint1: CGPoint(x: 152.35, y: 158.03), controlPoint2: CGPoint(x: 160, y: 133.24)) 58 | dPath.addCurve(to: CGPoint(x: 137.04, y: 25.63), controlPoint1: CGPoint(x: 160, y: 66.76), controlPoint2: CGPoint(x: 152.35, y: 41.97)) 59 | dPath.addCurve(to: CGPoint(x: 68.73, y: 0), controlPoint1: CGPoint(x: 121.74, y: 9.29), controlPoint2: CGPoint(x: 98.97, y: 0.75)) 60 | dPath.addLine(to: CGPoint(x: 0, y: 0)) 61 | dPath.addLine(to: CGPoint(x: 0, y: 60)) 62 | UIColor.black.setFill() 63 | dPath.fill() 64 | 65 | let danimation = createAnimation(dPath) 66 | let dEmitter = CAEmitterLayer(emitterColor: DustColors(rawValue: 0)?.uiColor) 67 | dEmitter.getEmitterCell(0).scale = 3 68 | 69 | dEmitter.add(danimation, forKey: "dkey") 70 | dustView.layer.addSublayer(dEmitter) 71 | 72 | dustView.center = view.center 73 | self.view.addSubview(dustView) 74 | } 75 | 76 | func createAnimation(_ path: UIBezierPath) -> CAKeyframeAnimation { 77 | let animation = CAKeyframeAnimation(keyPath: "emitterPosition") 78 | animation.duration = 3.0 79 | animation.path = path.cgPath 80 | return animation 81 | } 82 | 83 | func handleTapGesture(_ gestureRecognizer: UIPanGestureRecognizer) { 84 | UIView.animate(withDuration: 0.3, animations: { 85 | self.visualEffectView.alpha = 0.0 86 | }) 87 | 88 | for emitter in emitters { 89 | emitter.lifetime = 0 90 | } 91 | 92 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(6.0 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: { 93 | self.performSegue(withIdentifier: "startDust", sender: self) 94 | }) 95 | } 96 | 97 | override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 98 | UIApplication.shared.setStatusBarHidden(true, with: .fade) 99 | 100 | for (idx, emitter) in emitters.enumerated() { 101 | let (x,y,width,height) = (CGFloat(-20.0),CGFloat(-20.0),size.width+40.0,size.height+40.0) 102 | let oneSixth = CGFloat(width/6) 103 | 104 | emitter.emitterPosition = CGPoint(x: (CGFloat(idx) * oneSixth) + x + (oneSixth/2), y: (height/2) + y) 105 | emitter.emitterSize = CGSize(width: width/6, height: height) 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /Dust/MeshNetwork.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MeshNetwork.swift 3 | // Dust 4 | // 5 | // Created by Joe Blau on 11/26/14. 6 | // Copyright (c) 2014 joeblau. All rights reserved. 7 | // 8 | 9 | import MultipeerConnectivity 10 | 11 | // Added @objc in order to support optional protocol methods 12 | @objc protocol MeshNetworkDelegate { 13 | // Required 14 | func meshNetwork(_ meshNetwork: MeshNetwork, peer: MCPeerID, changedState state: MCSessionState, currentPeers: [AnyObject]) 15 | func meshNetwork(_ meshNetwork: MeshNetwork, failedToJoinMesh error: Error) 16 | 17 | // Optional 18 | @objc optional func meshNetwork(_ meshNetwork: MeshNetwork, didReceiveData data: Data, fromPeer peerdID: MCPeerID) 19 | @objc optional func meshNetwork(_ meshNetowrk: MeshNetwork, didReceiveStream stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) 20 | @objc optional func meshNetwork(_ meshNetwork: MeshNetwork, didStartReceivingResourceWithName resourceName: NSString, fromPeer peerID: MCPeerID, withProgress progress: Progress) 21 | @objc optional func meshNetwork(_ meshNetwork: MeshNetwork, didFinishReceivingResourceWithName resourceName: NSString, fromPeer peerID: MCPeerID, atURL localURL: URL, withError error: NSError) 22 | } 23 | 24 | final class MeshNetwork: NSObject, MCSessionDelegate, MCNearbyServiceAdvertiserDelegate, MCNearbyServiceBrowserDelegate { 25 | 26 | var delegate: MeshNetworkDelegate! 27 | 28 | private var connected = false 29 | private var acceptingPeers = false 30 | private let serviceType: String 31 | private let displayName: String 32 | private var _session: MCSession! 33 | private var _peerID: MCPeerID! 34 | private var _serviceAdvertiser: MCNearbyServiceAdvertiser! 35 | private var _serviceBrowser: MCNearbyServiceBrowser! 36 | 37 | // MARK: - Life Cycle 38 | 39 | init(serviceType: String = "Dust-Service", displayName: String = UIDevice.current.name) { 40 | self.serviceType = serviceType 41 | self.displayName = displayName 42 | super.init() 43 | } 44 | 45 | func joinMesh() { 46 | if !acceptingPeers { 47 | serviceAdvertiser.startAdvertisingPeer() 48 | serviceBrowser.startBrowsingForPeers() 49 | (connected, acceptingPeers) = (true, true) 50 | } 51 | } 52 | 53 | func stopAcceptingPeers() { 54 | serviceAdvertiser.stopAdvertisingPeer() 55 | serviceBrowser.stopBrowsingForPeers() 56 | acceptingPeers = false 57 | } 58 | 59 | func leaveMesh() { 60 | stopAcceptingPeers() 61 | session.disconnect() 62 | } 63 | 64 | // MARK: - Communication 65 | func sendData(_ data: Data, peerIDs: [MCPeerID], mode: MCSessionSendDataMode) { 66 | do { 67 | try session.send(data, toPeers: peerIDs, with: .reliable) 68 | } catch { 69 | debugPrint(error) 70 | } 71 | } 72 | 73 | func startStreamWith(_ name: String!, peerID: MCPeerID!, error: NSErrorPointer!) -> OutputStream { 74 | return try! self.session.startStream(withName: name, toPeer: peerID) 75 | } 76 | 77 | func sendResourceAtURL(_ resourceURL: URL, resourceName: String, peerID: MCPeerID, completionHandler: ((NSError?) -> Void)!) -> Progress { 78 | return self.session.sendResource(at: resourceURL, withName: resourceName, toPeer: peerID, withCompletionHandler: completionHandler as! ((Error?) -> Void)?)! 79 | } 80 | 81 | // MARK: - Properties 82 | var connectedPeers: [MCPeerID] { 83 | return self.session.connectedPeers 84 | } 85 | 86 | var session: MCSession! { 87 | _session = _session ?? MCSession(peer: self.peerID, securityIdentity: nil, encryptionPreference: .none) 88 | _session.delegate = _session.delegate ?? self 89 | return _session 90 | } 91 | 92 | var peerID: MCPeerID! { 93 | _peerID = _peerID ?? MCPeerID(displayName: self.displayName) 94 | return _peerID 95 | } 96 | var serviceAdvertiser: MCNearbyServiceAdvertiser! { 97 | _serviceAdvertiser = _serviceAdvertiser ?? MCNearbyServiceAdvertiser(peer: self.peerID, discoveryInfo: nil, serviceType: self.serviceType) 98 | _serviceAdvertiser.delegate = _serviceAdvertiser.delegate ?? self 99 | return _serviceAdvertiser 100 | } 101 | 102 | var serviceBrowser: MCNearbyServiceBrowser! { 103 | _serviceBrowser = _serviceBrowser ?? MCNearbyServiceBrowser(peer: self.peerID, serviceType: self.serviceType) 104 | _serviceBrowser.delegate = _serviceBrowser.delegate ?? self 105 | return _serviceBrowser 106 | } 107 | 108 | // MARK: - Session Delegate 109 | func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) { 110 | DispatchQueue.main.async(execute: { () -> Void in 111 | self.delegate.meshNetwork(self, peer: peerID, changedState: state, currentPeers: self.session.connectedPeers) 112 | }) 113 | } 114 | 115 | func session(_ session: MCSession, didReceive data: Data, fromPeer peerID: MCPeerID) { 116 | DispatchQueue.main.async(execute: { () -> Void in 117 | self.delegate.meshNetwork!(self, didReceiveData: data, fromPeer: peerID) 118 | }) 119 | } 120 | 121 | func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) { 122 | DispatchQueue.main.async(execute: { () -> Void in 123 | self.delegate.meshNetwork!(self, didReceiveStream: stream, withName: streamName, fromPeer: peerID) 124 | }) 125 | 126 | } 127 | 128 | func session(_ session: MCSession, didStartReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, with progress: Progress) { 129 | DispatchQueue.main.async(execute: { () -> Void in 130 | self.delegate.meshNetwork!(self, didStartReceivingResourceWithName: resourceName as NSString, fromPeer: peerID, withProgress: progress) 131 | }) 132 | } 133 | 134 | func session(_ session: MCSession, didFinishReceivingResourceWithName resourceName: String, fromPeer peerID: MCPeerID, at localURL: URL, withError error: Error?) { 135 | DispatchQueue.main.async(execute: { () -> Void in 136 | self.delegate.meshNetwork!(self, didFinishReceivingResourceWithName: resourceName as NSString, fromPeer: peerID, atURL: localURL, withError: error as! NSError) 137 | }) 138 | } 139 | 140 | func session(_ session: MCSession, didReceiveCertificate certificate: [Any]?, fromPeer peerID: MCPeerID, certificateHandler: @escaping (Bool) -> Void) { 141 | certificateHandler(true) 142 | } 143 | 144 | // MARK: - Advertiser Delegate 145 | 146 | func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer peerID: MCPeerID, withContext context: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Void) { 147 | if (peerID.displayName < self.peerID.displayName) { 148 | invitationHandler(true, self.session) 149 | } 150 | } 151 | 152 | func advertiser(_ advertiser: MCNearbyServiceAdvertiser, didNotStartAdvertisingPeer error: Error) { 153 | self.delegate.meshNetwork(self, failedToJoinMesh: error) 154 | 155 | } 156 | 157 | // MARK: - Browser Delegate 158 | 159 | func browser(_ browser: MCNearbyServiceBrowser, foundPeer peerID: MCPeerID, withDiscoveryInfo info: [String : String]?) { 160 | if peerID.displayName > self.peerID.displayName { 161 | serviceBrowser.invitePeer(peerID, to: self.session, withContext: nil, timeout: 10) 162 | } 163 | } 164 | 165 | func browser(_ browser: MCNearbyServiceBrowser, lostPeer peerID: MCPeerID) {} 166 | 167 | func browser(_ browser: MCNearbyServiceBrowser, didNotStartBrowsingForPeers error: Error) { 168 | delegate.meshNetwork(self, failedToJoinMesh: error) 169 | 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /Dust/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Dust 4 | // 5 | // Created by Joe Blau on 9/12/14. 6 | // Copyright (c) 2014 joeblau. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import PKHUD 11 | import MultipeerConnectivity 12 | 13 | enum GestureType { 14 | case pan, tap, end 15 | } 16 | 17 | enum DustColors: Int { 18 | case red, orange, yellow, green, blue, violet 19 | 20 | var uiColor: UIColor { 21 | switch (self) { 22 | case .red: return UIColor(red: 0.898, green: 0.302, blue: 0.259, alpha: 1.0) 23 | case .orange: return UIColor(red: 0.894, green: 0.494, blue: 0.188, alpha: 1.0) 24 | case .yellow: return UIColor(red: 0.941, green: 0.880, blue: 0.336, alpha: 1.0) 25 | case .green: return UIColor(red: 0.224, green: 0.792, blue: 0.455, alpha: 1.0) 26 | case .blue: return UIColor(red: 0.227, green: 0.600, blue: 0.847, alpha: 1.0) 27 | case .violet: return UIColor(red: 0.604, green: 0.361, blue: 0.706, alpha: 1.0) 28 | } 29 | } 30 | 31 | static var colors: [DustColors] { 32 | return [.red, .orange, .yellow, .green, .blue, .violet] 33 | } 34 | } 35 | 36 | struct DustMessage { 37 | var percentX: Float 38 | var percentY: Float 39 | var gestureType: GestureType 40 | var color: DustColors 41 | } 42 | 43 | extension Data { 44 | init(from value: T) { 45 | var value = value 46 | self.init(buffer: UnsafeBufferPointer(start: &value, count: 1)) 47 | } 48 | func to(type: T.Type) -> T { 49 | return self.withUnsafeBytes { $0.pointee } 50 | } 51 | } 52 | 53 | final class ViewController: UIViewController, UIGestureRecognizerDelegate, MeshNetworkDelegate { 54 | 55 | private var myEmitter: CAEmitterLayer! 56 | private var theirEmitter: CAEmitterLayer! 57 | 58 | private let meshNetwork = MeshNetwork(serviceType: "Dust-Service") 59 | 60 | private var peersOutputStreams: Dictionary! = Dictionary() 61 | 62 | @IBOutlet weak var connectionButton: UIBarButtonItem! 63 | @IBOutlet weak var connectedPeerCount: UIBarButtonItem! 64 | @IBOutlet weak var colorSegmentControl: UISegmentedControl! 65 | 66 | override func viewDidLoad() { 67 | super.viewDidLoad() 68 | view.backgroundColor = UIColor(red: 0.067, green: 0.067, blue: 0.067, alpha: 1.0) 69 | UIApplication.shared.setStatusBarHidden(false, with: .fade) 70 | 71 | PKHUD.sharedHUD.userInteractionOnUnderlyingViewsEnabled = true 72 | 73 | let panGesture = UIPanGestureRecognizer(target: self, action: #selector(ViewController.handlePanGesture(_:))) 74 | panGesture.minimumNumberOfTouches = 1 75 | panGesture.delegate = self 76 | 77 | let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.handleTapGesture(_:))) 78 | tapGesture.numberOfTouchesRequired = 1 79 | tapGesture.numberOfTapsRequired = 2 80 | tapGesture.delegate = self 81 | 82 | view.addGestureRecognizer(panGesture) 83 | view.addGestureRecognizer(tapGesture) 84 | 85 | meshNetwork.delegate = self 86 | meshNetwork.joinMesh() 87 | 88 | connectionButton.tintColor = DustColors(rawValue: colorSegmentControl.selectedSegmentIndex)?.uiColor 89 | connectedPeerCount.tintColor = DustColors(rawValue: colorSegmentControl.selectedSegmentIndex)?.uiColor 90 | colorSegmentControl.tintColor = DustColors(rawValue: colorSegmentControl.selectedSegmentIndex)?.uiColor 91 | 92 | let emitterColor = DustColors(rawValue: colorSegmentControl.selectedSegmentIndex)?.uiColor 93 | myEmitter = CAEmitterLayer(emitterColor: emitterColor) 94 | view.layer.addSublayer(myEmitter) 95 | 96 | theirEmitter = CAEmitterLayer(emitterColor: emitterColor) 97 | view.layer.addSublayer(theirEmitter) 98 | } 99 | 100 | @IBAction func selectColor(_ sender: UISegmentedControl) { 101 | connectionButton.tintColor = DustColors(rawValue: colorSegmentControl.selectedSegmentIndex)?.uiColor 102 | connectedPeerCount.tintColor = DustColors(rawValue: colorSegmentControl.selectedSegmentIndex)?.uiColor 103 | colorSegmentControl.tintColor = DustColors(rawValue: colorSegmentControl.selectedSegmentIndex)?.uiColor 104 | myEmitter.setValue(DustColors(rawValue: colorSegmentControl.selectedSegmentIndex)?.uiColor.cgColor, forKeyPath: "emitterCells.dustCell.color") 105 | } 106 | 107 | func handlePanGesture(_ gestureRecognizer: UIPanGestureRecognizer) { 108 | let point = gestureRecognizer.location(in: self.view) 109 | myEmitter.lifetime = (gestureRecognizer.state == .ended) ? 0 : 1 110 | myEmitter.emitterPosition = point 111 | myEmitter.emitterShape = kCAEmitterLayerPoint 112 | 113 | switch gestureRecognizer.state { 114 | case .began, .changed: sendDataMessage(point, gestureType: .pan) 115 | case .ended: sendDataMessage(point, gestureType: .end) 116 | default: return 117 | } 118 | } 119 | 120 | func handleTapGesture(_ gestureRecoginzer: UITapGestureRecognizer) { 121 | let point = gestureRecoginzer.location(in: self.view) 122 | myEmitter.lifetime = 1 123 | myEmitter.emitterPosition = point 124 | myEmitter.emitterShape = kCAEmitterLayerCircle 125 | 126 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(0.5 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: { 127 | self.myEmitter.lifetime = 0 128 | }) 129 | sendDataMessage(point, gestureType: .tap) 130 | } 131 | 132 | func sendDataMessage(_ point: CGPoint, gestureType: GestureType) { 133 | 134 | 135 | let message = DustMessage(percentX: Float(point.x/view.bounds.width), 136 | percentY: Float(point.y/view.bounds.height), 137 | gestureType: gestureType, 138 | color: DustColors(rawValue: colorSegmentControl.selectedSegmentIndex)!) 139 | 140 | meshNetwork.sendData(Data(from: message), peerIDs: meshNetwork.connectedPeers, mode: .unreliable) 141 | } 142 | 143 | // MARK: Mesh Network Delegate 144 | func meshNetwork(_ meshNetwork: MeshNetwork, peer peerID: MCPeerID, changedState state: MCSessionState, currentPeers: [AnyObject]) { 145 | switch state { 146 | case .notConnected: 147 | PKHUD.sharedHUD.contentView = PKHUDSquareBaseView.init(image: PKHUDAssets.crossImage, title: "Disconnected", subtitle: peerID.displayName) 148 | case .connected: 149 | PKHUD.sharedHUD.contentView = PKHUDSquareBaseView.init(image: PKHUDAssets.checkmarkImage, title: "Connected", subtitle: peerID.displayName) 150 | case .connecting: 151 | PKHUD.sharedHUD.contentView = PKHUDSquareBaseView.init(image: PKHUDAssets.checkmarkImage, title: "Connecting", subtitle: peerID.displayName) 152 | } 153 | PKHUD.sharedHUD.show() 154 | PKHUD.sharedHUD.hide(afterDelay: 4.0) 155 | connectionButton.image = UIImage(named: currentPeers.count > 0 ? "connect" : "disconnect") 156 | connectedPeerCount.title = "\(currentPeers.count)" 157 | } 158 | 159 | func meshNetwork(_ meshNetwork: MeshNetwork, failedToJoinMesh error: Error) { 160 | PKHUD.sharedHUD.contentView = PKHUDSquareBaseView.init(image: PKHUDAssets.crossImage, title: "Error", subtitle: nil) 161 | PKHUD.sharedHUD.show() 162 | PKHUD.sharedHUD.hide(afterDelay: 4.0) 163 | } 164 | 165 | func meshNetwork(_ meshNetwork: MeshNetwork, didReceiveData data: Data, fromPeer peerdID: MCPeerID) { 166 | 167 | 168 | let message = data.to(type: DustMessage.self) 169 | 170 | 171 | let x = CGFloat(message.percentX * Float(view.bounds.width)) 172 | let y = CGFloat(message.percentY * Float(view.bounds.height)) 173 | theirEmitter.setValue(message.color.uiColor.cgColor, forKeyPath: "emitterCells.dustCell.color") 174 | theirEmitter.lifetime = 1 175 | theirEmitter.emitterPosition = CGPoint(x: x, y: y) 176 | switch message.gestureType { 177 | case .pan: 178 | theirEmitter.emitterShape = kCAEmitterLayerPoint 179 | case .tap: 180 | theirEmitter.emitterShape = kCAEmitterLayerCircle 181 | DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(0.5 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: { 182 | self.theirEmitter.lifetime = 0 183 | }) 184 | case .end: 185 | theirEmitter.lifetime = 0 186 | } 187 | } 188 | 189 | @IBAction func connect(_ sender: UIBarButtonItem) { 190 | if meshNetwork.connectedPeers.count == 0 { 191 | meshNetwork.joinMesh() 192 | } else { 193 | meshNetwork.leaveMesh() 194 | } 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /DustTests/DustTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DustTests.swift 3 | // DustTests 4 | // 5 | // Created by Joe Blau on 9/12/14. 6 | // Copyright (c) 2014 joeblau. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class DustTests: 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 | -------------------------------------------------------------------------------- /DustTests/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 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2014-2016 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 | 3 |

4 | 5 | 6 | 7 |

8 | 9 | Dust uses the iOS Particle Emitter And Multipeer Connectivity to create an ephemeral gesture experience. 10 | 11 | ## Prerequisites 12 | 13 | - Carthage - https://github.com/Carthage/Carthage 14 | - Xcode 8.0 / Swift 3.0 15 | 16 | ## Install Instructions 17 | 18 | ```sh 19 | git clone git@github.com:joeblau/Dust-iOS.git 20 | cd Dust-iOS 21 | carthage bootstrap 22 | ``` 23 | -------------------------------------------------------------------------------- /dustparticles.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/dustparticles.gif -------------------------------------------------------------------------------- /gh-assets/Assets/App Icon/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/gh-assets/Assets/App Icon/Icon-60@2x.png -------------------------------------------------------------------------------- /gh-assets/Assets/App Icon/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/gh-assets/Assets/App Icon/Icon-60@3x.png -------------------------------------------------------------------------------- /gh-assets/Assets/App Icon/Icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/gh-assets/Assets/App Icon/Icon-76.png -------------------------------------------------------------------------------- /gh-assets/Assets/App Icon/Icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/gh-assets/Assets/App Icon/Icon-76@2x.png -------------------------------------------------------------------------------- /gh-assets/Assets/App Icon/Icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/gh-assets/Assets/App Icon/Icon-83.5@2x.png -------------------------------------------------------------------------------- /gh-assets/Assets/App Icon/Icon-Small-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/gh-assets/Assets/App Icon/Icon-Small-40@2x.png -------------------------------------------------------------------------------- /gh-assets/Assets/App Icon/Icon-Small-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/gh-assets/Assets/App Icon/Icon-Small-60.png -------------------------------------------------------------------------------- /gh-assets/Assets/App Icon/Icon-Small-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/gh-assets/Assets/App Icon/Icon-Small-60@2x.png -------------------------------------------------------------------------------- /gh-assets/Assets/App Icon/Icon-Small-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/gh-assets/Assets/App Icon/Icon-Small-60@3x.png -------------------------------------------------------------------------------- /gh-assets/Assets/App Icon/Icon-Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/gh-assets/Assets/App Icon/Icon-Small.png -------------------------------------------------------------------------------- /gh-assets/Assets/App Icon/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/gh-assets/Assets/App Icon/Icon-Small@2x.png -------------------------------------------------------------------------------- /gh-assets/Assets/App Icon/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/gh-assets/Assets/App Icon/Icon-Small@3x.png -------------------------------------------------------------------------------- /gh-assets/Assets/App Icon/iTunesArtwork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/gh-assets/Assets/App Icon/iTunesArtwork.png -------------------------------------------------------------------------------- /gh-assets/Assets/App Icon/iTunesArtwork@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/gh-assets/Assets/App Icon/iTunesArtwork@2x.png -------------------------------------------------------------------------------- /gh-assets/double-tap.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/gh-assets/double-tap.pdf -------------------------------------------------------------------------------- /gh-assets/dust.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/gh-assets/dust.sketch -------------------------------------------------------------------------------- /gh-assets/free-drag.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeblau/Dust-Sample-Code/aa3278ef515b31d2fd20c9c1a85aad52ddc0bc8a/gh-assets/free-drag.pdf -------------------------------------------------------------------------------- /gh-assets/github-header.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | github-header 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | --------------------------------------------------------------------------------