├── .swift-version ├── SpinnerActivityIndicatorExample ├── Assets.xcassets │ ├── Contents.json │ ├── default_small_spinner.imageset │ │ ├── 012-spinning-wheel-18.png │ │ └── Contents.json │ └── AppIcon.appiconset │ │ └── Contents.json ├── ViewController.swift ├── AppDelegate.swift ├── Info.plist └── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Pod ├── Resources │ └── default_small_spinner.png ├── SpinnerController.swift └── SpinnerActivityIndicator.swift ├── SpinnerActivityIndicator.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata ├── xcuserdata │ └── design.xcuserdatad │ │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ └── SpinnerActivityIndicator.xcscheme └── project.pbxproj ├── .gitignore ├── SpinnerActivityIndicator.podspec ├── LICENSE └── README.md /.swift-version: -------------------------------------------------------------------------------- 1 | 4.0 2 | -------------------------------------------------------------------------------- /SpinnerActivityIndicatorExample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Pod/Resources/default_small_spinner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkach/SpinnerActivityIndicator/HEAD/Pod/Resources/default_small_spinner.png -------------------------------------------------------------------------------- /SpinnerActivityIndicator.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SpinnerActivityIndicatorExample/Assets.xcassets/default_small_spinner.imageset/012-spinning-wheel-18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkach/SpinnerActivityIndicator/HEAD/SpinnerActivityIndicatorExample/Assets.xcassets/default_small_spinner.imageset/012-spinning-wheel-18.png -------------------------------------------------------------------------------- /SpinnerActivityIndicatorExample/Assets.xcassets/default_small_spinner.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "012-spinning-wheel-18.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X noise 2 | .DS_Store 3 | 4 | # TextMate noise 5 | *.tm_build_errors 6 | 7 | # Xcode noise, 8 | # https://github.com/github/gitignore/blob/master/Objective-C.gitignore 9 | *.pbxuser 10 | !default.pbxuser 11 | *.mode1v3 12 | !default.mode1v3 13 | *.mode2v3 14 | !default.mode2v3 15 | *.perspectivev3 16 | !default.perspectivev3 17 | xcuserdata 18 | *.moved-aside 19 | *~.nib 20 | 21 | # TMP data 22 | Build/* 23 | DerivedData 24 | cintegration/output 25 | .idea/ 26 | tmp 27 | 28 | # CocoaPods 29 | Pods 30 | 31 | # Cedar helper 32 | spec_arc_support.rb 33 | -------------------------------------------------------------------------------- /SpinnerActivityIndicatorExample/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SpinnerActivityIndicator 4 | // 5 | // Created by Alexander Tkachenko on 8/22/17. 6 | // Copyright © 2017 megogo. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | @IBOutlet weak var spinnerActivity: SpinnerActivityIndicator! 13 | 14 | @IBAction func startSpinner(_ sender: Any) { 15 | spinnerActivity.startAnimating() 16 | } 17 | 18 | @IBAction func stopSpinner(_ sender: Any) { 19 | spinnerActivity.stopAnimating() 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /SpinnerActivityIndicatorExample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SpinnerActivityIndicator 4 | // 5 | // Created by Alexander Tkachenko on 8/22/17. 6 | // Copyright © 2017 megogo. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | var window: UIWindow? 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /SpinnerActivityIndicator.xcodeproj/xcuserdata/design.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SpinnerActivityIndicator.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | B52632811F4CB9090039AD3F 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /SpinnerActivityIndicator.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | 4 | s.name = "SpinnerActivityIndicator" 5 | s.version = "0.0.1" 6 | s.summary = "UIKit dynamics based activity indicator that works as real fidget spinner" 7 | 8 | s.description = <<-DESC 9 | UIKit dynamics based activity indicator that is much more 10 | fun and interactive than default system one! 11 | DESC 12 | 13 | s.homepage = "https://github.com/tkach/SpinnerActivityIndicator" 14 | 15 | s.license = { :type => "MIT" } 16 | 17 | 18 | s.author = { "Alex Tkachenko" => "tkach2004@gmail.com" } 19 | s.platform = :ios, "9.0" 20 | 21 | s.source = { :git => "https://github.com/tkach/SpinnerActivityIndicator.git", :tag => "#{s.version}" } 22 | s.source_files = ["Pod/*.{swift}", "Pod/**/*.{swift}" ] 23 | s.resources = ["Pod/Resources/*.{png}"] 24 | 25 | end 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2017 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SpinnerActivityIndicator 2 | =================== 3 | 4 | UIKit dynamics based activity indicator that works like a real fidget spinner. 5 | Your users will be much more entertained when they have an option to spin a spinner 6 | while your app is loading data/ uncompressing database/ mining [you_name_it]coins etc. 7 | Easily customizable via Interface Builder. 8 | 9 | ![Demo](https://user-images.githubusercontent.com/1849482/33743411-62a7f42c-dbb5-11e7-8518-91cc0b3ec91e.gif) 10 | 11 | Features 12 | -- 13 | - Simple and quick integration 14 | - Customizable via Interface Builder and from code 15 | - Fun 16 | 17 | Installation 18 | -- 19 | 20 | * via Cocoapods 21 | ```ruby 22 | use_frameworks! 23 | 24 | platform :ios, "9.0" 25 | 26 | target 'YourTarget' do 27 | pod 'SpinnerActivityIndicator', :git => "https://github.com/tkach/SpinnerActivityIndicator" 28 | end 29 | 30 | ``` 31 | * manual 32 | 33 | ``` 34 | Copy Pod folder from this repo to your project 35 | 36 | ``` 37 | 38 | Using and customizing 39 | -- 40 | 1. Add UIView to your xib or storyboard file, change it's class to SpinnerActivityIndicator. 41 | 2. Add constraints (Width and height define touchable area for user interaction so it should be big enough (> 100 would be great) 42 | 3. Customize color and isAnimating properties in Interface Builder 43 | 4. If you need custom Spinner image or size, set `style` property from code: 44 | 45 | ``` 46 | @IBOutlet weak var spinnerActivity: SpinnerActivityIndicator! 47 | override func viewDidLoad() { 48 | super.viewDidLoad() 49 | spinnerActivity.style = .custom(size: mySize, image: mySpinnerImage) 50 | } 51 | 52 | ``` 53 | -------------------------------------------------------------------------------- /SpinnerActivityIndicatorExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /SpinnerActivityIndicatorExample/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /SpinnerActivityIndicatorExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Pod/SpinnerController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SpinnerController.swift 3 | // SpinnerActivityIndicator 4 | // 5 | // Created by Alexander Tkachenko on 8/22/17. 6 | // Copyright © 2017 megogo. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | final class SpinnerController { 12 | private let spinner: UIView 13 | private let referenceView: UIView 14 | private let spinnerBehavior: UIDynamicItemBehavior 15 | private let animator: UIDynamicAnimator 16 | 17 | init(with spinner: UIView, referenceView: UIView) { 18 | self.spinner = spinner 19 | self.referenceView = referenceView 20 | spinnerBehavior = UIDynamicItemBehavior(items: [spinner]) 21 | spinnerBehavior.angularResistance = 0 22 | animator = UIDynamicAnimator(referenceView: self.referenceView) 23 | setup() 24 | } 25 | 26 | private func setup() { 27 | let panRecognizer = UIPanGestureRecognizer() 28 | panRecognizer.addTarget(self, action: #selector(handlePan(gesture:))) 29 | referenceView.addGestureRecognizer(panRecognizer) 30 | 31 | let center = referenceView.convert(spinner.center, to: referenceView) 32 | let centerAttachment = UIAttachmentBehavior(item: spinner, attachedToAnchor: center) 33 | animator.addBehavior(centerAttachment) 34 | } 35 | 36 | func start() { 37 | if (!animator.behaviors.contains(spinnerBehavior)) { 38 | animator.addBehavior(spinnerBehavior) 39 | } 40 | let velocity = spinnerBehavior.angularVelocity(for: spinner) 41 | let newVelocity = 5 - velocity 42 | spinnerBehavior.addAngularVelocity(newVelocity, for: spinner) 43 | } 44 | 45 | func stop() { 46 | animator.removeBehavior(spinnerBehavior) 47 | } 48 | 49 | var startTouchCenter: CGPoint! 50 | var lastTime: CFAbsoluteTime! 51 | var attachment: UIAttachmentBehavior! 52 | var lastAngle: CGFloat! 53 | var angularVelocity: CGFloat! 54 | 55 | @objc func handlePan(gesture: UIGestureRecognizer) { 56 | guard animator.behaviors.contains(spinnerBehavior) else { return } 57 | 58 | func angle(of view: UIView) -> CGFloat { 59 | return atan2(view.transform.b, view.transform.a) 60 | } 61 | if (gesture.state == .began) { 62 | startTouchCenter = spinner.center 63 | 64 | // calculate the center offset and anchor point 65 | let pointWithinAnimatedView = gesture.location(in: spinner) 66 | let offset = UIOffsetMake((CGFloat) (pointWithinAnimatedView.x - spinner.bounds.size.width / 2.0), 67 | (CGFloat) (pointWithinAnimatedView.y - spinner.bounds.size.height / 2.0)) 68 | let anchor = gesture.location(in: referenceView) 69 | attachment = UIAttachmentBehavior(item: spinner, offsetFromCenter: offset, attachedToAnchor: anchor) 70 | 71 | lastTime = CFAbsoluteTimeGetCurrent() 72 | lastAngle = angle(of: spinner) 73 | attachment?.action = { 74 | [unowned self] in 75 | let timeInterval = CGFloat(CFAbsoluteTimeGetCurrent() - self.lastTime) 76 | let angularDistance = angle(of: self.spinner) - self.lastAngle 77 | self.angularVelocity = angularDistance / timeInterval 78 | } 79 | animator.addBehavior(attachment) 80 | } else if (gesture.state == .changed) { 81 | let anchor = gesture.location(in: referenceView) 82 | attachment.anchorPoint = anchor 83 | } else if (gesture.state == .ended || gesture.state == .cancelled) { 84 | animator.removeBehavior(attachment) 85 | spinnerBehavior.addAngularVelocity(angularVelocity, for: spinner) 86 | } 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /SpinnerActivityIndicator.xcodeproj/xcuserdata/design.xcuserdatad/xcschemes/SpinnerActivityIndicator.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /SpinnerActivityIndicatorExample/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Pod/SpinnerActivityIndicator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SpinnerActivityIndicator.swift 3 | // SpinnerActivityIndicator 4 | // 5 | // Created by Alexander Tkachenko on 11/29/17. 6 | // Copyright © 2017 megogo. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public enum SpinnerStyle { 12 | case small 13 | case large 14 | case custom(size: CGSize, image: UIImage) 15 | 16 | var size: CGSize { 17 | let imageSize: CGSize 18 | switch self { 19 | case .small: 20 | imageSize = CGSize(width: 44, height: 44) 21 | case .large: 22 | imageSize = CGSize(width: 88, height: 88) 23 | case .custom(let size, _): 24 | imageSize = size 25 | } 26 | return imageSize 27 | } 28 | 29 | var image: UIImage? { 30 | if case .custom(_, let customImage) = self { 31 | return customImage 32 | } 33 | return nil 34 | } 35 | } 36 | 37 | @IBDesignable final public class SpinnerActivityIndicator: UIView { 38 | @IBInspectable public var color: UIColor = .gray { 39 | didSet { imageView.tintColor = color } 40 | } 41 | @IBInspectable public var isAnimating: Bool = true 42 | 43 | public var style: SpinnerStyle { 44 | didSet { 45 | imageView.image = style.image ?? imageView.image 46 | let imageSize = style.size 47 | widthConstraint?.constant = imageSize.width 48 | heightConstraint?.constant = imageSize.height 49 | } 50 | } 51 | 52 | private lazy var imageView: UIImageView = { 53 | let theBundle = Bundle(for: type(of: self)) 54 | let theImage = UIImage(named: "default_small_spinner", in: theBundle, compatibleWith: nil) 55 | let defaultSpinnerImage = theImage?.withRenderingMode(.alwaysTemplate) 56 | let imageView = UIImageView(image: defaultSpinnerImage) 57 | imageView.tintColor = self.color 58 | imageView.translatesAutoresizingMaskIntoConstraints = false 59 | return imageView 60 | }() 61 | 62 | private lazy var spinnerController: SpinnerController = { 63 | SpinnerController(with: self.imageView, referenceView: self) 64 | }() 65 | 66 | private var widthConstraint: NSLayoutConstraint? 67 | private var heightConstraint: NSLayoutConstraint? 68 | 69 | public init(activityIndicatorStyle style: SpinnerStyle) { 70 | self.style = style 71 | super.init(frame: .zero) 72 | commonInit() 73 | } 74 | 75 | override init(frame: CGRect) { 76 | style = .small 77 | super.init(frame: frame) 78 | commonInit() 79 | } 80 | 81 | public required init?(coder aDecoder: NSCoder) { 82 | style = .small 83 | super.init(coder: aDecoder) 84 | commonInit() 85 | } 86 | 87 | func startAnimating() { 88 | spinnerController.start() 89 | isAnimating = true 90 | UIView.animate(withDuration: 0.3, animations: { 91 | self.alpha = 1 92 | }) { _ in 93 | self.isUserInteractionEnabled = true 94 | } 95 | } 96 | 97 | func stopAnimating() { 98 | spinnerController.stop() 99 | isAnimating = false 100 | UIView.animate(withDuration: 0.3, animations: { 101 | self.alpha = 0 102 | }) { _ in 103 | self.isUserInteractionEnabled = false 104 | } 105 | } 106 | 107 | override public func didMoveToSuperview() { 108 | super.didMoveToSuperview() 109 | layoutIfNeeded() 110 | if isAnimating { 111 | #if TARGET_INTERFACE_BUILDER 112 | alpha = 1 113 | #else 114 | alpha = 0 115 | #endif 116 | 117 | startAnimating() 118 | } 119 | else { 120 | stopAnimating() 121 | } 122 | } 123 | 124 | override public func prepareForInterfaceBuilder() { 125 | layoutIfNeeded() 126 | isAnimating ? startAnimating() : stopAnimating() 127 | imageView.alpha = isAnimating ? 1 : 0.4 128 | } 129 | 130 | private func commonInit() { 131 | let imageSize = style.size 132 | if let image = style.image { imageView.image = image } 133 | addSubview(imageView) 134 | widthConstraint = imageView.widthAnchor.constraint(equalToConstant: imageSize.width) 135 | heightConstraint = imageView.heightAnchor.constraint(equalToConstant: imageSize.height) 136 | [widthConstraint, heightConstraint].forEach { $0?.isActive = true } 137 | imageView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true 138 | imageView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true 139 | } 140 | } 141 | 142 | -------------------------------------------------------------------------------- /SpinnerActivityIndicator.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B52632861F4CB9090039AD3F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52632851F4CB9090039AD3F /* AppDelegate.swift */; }; 11 | B52632881F4CB9090039AD3F /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52632871F4CB9090039AD3F /* ViewController.swift */; }; 12 | B526328B1F4CB9090039AD3F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B52632891F4CB9090039AD3F /* Main.storyboard */; }; 13 | B526328D1F4CB9090039AD3F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B526328C1F4CB9090039AD3F /* Assets.xcassets */; }; 14 | B52632901F4CB9090039AD3F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B526328E1F4CB9090039AD3F /* LaunchScreen.storyboard */; }; 15 | B52632981F4CBB720039AD3F /* SpinnerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52632971F4CBB720039AD3F /* SpinnerController.swift */; }; 16 | B5AFD37A1FCF63F500F32CC8 /* SpinnerActivityIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5AFD3791FCF63F500F32CC8 /* SpinnerActivityIndicator.swift */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | B52632821F4CB9090039AD3F /* SpinnerActivityIndicator.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SpinnerActivityIndicator.app; sourceTree = BUILT_PRODUCTS_DIR; }; 21 | B52632851F4CB9090039AD3F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 22 | B52632871F4CB9090039AD3F /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 23 | B526328A1F4CB9090039AD3F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 24 | B526328C1F4CB9090039AD3F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 25 | B526328F1F4CB9090039AD3F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 26 | B52632911F4CB9090039AD3F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 27 | B52632971F4CBB720039AD3F /* SpinnerController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpinnerController.swift; sourceTree = ""; }; 28 | B5AFD3791FCF63F500F32CC8 /* SpinnerActivityIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpinnerActivityIndicator.swift; sourceTree = ""; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | B526327F1F4CB9090039AD3F /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | ); 37 | runOnlyForDeploymentPostprocessing = 0; 38 | }; 39 | /* End PBXFrameworksBuildPhase section */ 40 | 41 | /* Begin PBXGroup section */ 42 | B52632791F4CB9090039AD3F = { 43 | isa = PBXGroup; 44 | children = ( 45 | B5AFD3781FCF63E000F32CC8 /* Pod */, 46 | B52632841F4CB9090039AD3F /* SpinnerActivityIndicatorExample */, 47 | B52632831F4CB9090039AD3F /* Products */, 48 | ); 49 | sourceTree = ""; 50 | }; 51 | B52632831F4CB9090039AD3F /* Products */ = { 52 | isa = PBXGroup; 53 | children = ( 54 | B52632821F4CB9090039AD3F /* SpinnerActivityIndicator.app */, 55 | ); 56 | name = Products; 57 | sourceTree = ""; 58 | }; 59 | B52632841F4CB9090039AD3F /* SpinnerActivityIndicatorExample */ = { 60 | isa = PBXGroup; 61 | children = ( 62 | B52632851F4CB9090039AD3F /* AppDelegate.swift */, 63 | B52632871F4CB9090039AD3F /* ViewController.swift */, 64 | B52632891F4CB9090039AD3F /* Main.storyboard */, 65 | B526328C1F4CB9090039AD3F /* Assets.xcassets */, 66 | B526328E1F4CB9090039AD3F /* LaunchScreen.storyboard */, 67 | B52632911F4CB9090039AD3F /* Info.plist */, 68 | ); 69 | path = SpinnerActivityIndicatorExample; 70 | sourceTree = ""; 71 | }; 72 | B5AFD3781FCF63E000F32CC8 /* Pod */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | B52632971F4CBB720039AD3F /* SpinnerController.swift */, 76 | B5AFD3791FCF63F500F32CC8 /* SpinnerActivityIndicator.swift */, 77 | ); 78 | path = Pod; 79 | sourceTree = ""; 80 | }; 81 | /* End PBXGroup section */ 82 | 83 | /* Begin PBXNativeTarget section */ 84 | B52632811F4CB9090039AD3F /* SpinnerActivityIndicator */ = { 85 | isa = PBXNativeTarget; 86 | buildConfigurationList = B52632941F4CB9090039AD3F /* Build configuration list for PBXNativeTarget "SpinnerActivityIndicator" */; 87 | buildPhases = ( 88 | B526327E1F4CB9090039AD3F /* Sources */, 89 | B526327F1F4CB9090039AD3F /* Frameworks */, 90 | B52632801F4CB9090039AD3F /* Resources */, 91 | ); 92 | buildRules = ( 93 | ); 94 | dependencies = ( 95 | ); 96 | name = SpinnerActivityIndicator; 97 | productName = SpinnerActivityIndicator; 98 | productReference = B52632821F4CB9090039AD3F /* SpinnerActivityIndicator.app */; 99 | productType = "com.apple.product-type.application"; 100 | }; 101 | /* End PBXNativeTarget section */ 102 | 103 | /* Begin PBXProject section */ 104 | B526327A1F4CB9090039AD3F /* Project object */ = { 105 | isa = PBXProject; 106 | attributes = { 107 | LastSwiftUpdateCheck = 0830; 108 | LastUpgradeCheck = 0830; 109 | ORGANIZATIONNAME = megogo; 110 | TargetAttributes = { 111 | B52632811F4CB9090039AD3F = { 112 | CreatedOnToolsVersion = 8.3.2; 113 | DevelopmentTeam = TA9RQZV3QA; 114 | ProvisioningStyle = Automatic; 115 | }; 116 | }; 117 | }; 118 | buildConfigurationList = B526327D1F4CB9090039AD3F /* Build configuration list for PBXProject "SpinnerActivityIndicator" */; 119 | compatibilityVersion = "Xcode 3.2"; 120 | developmentRegion = English; 121 | hasScannedForEncodings = 0; 122 | knownRegions = ( 123 | en, 124 | Base, 125 | ); 126 | mainGroup = B52632791F4CB9090039AD3F; 127 | productRefGroup = B52632831F4CB9090039AD3F /* Products */; 128 | projectDirPath = ""; 129 | projectRoot = ""; 130 | targets = ( 131 | B52632811F4CB9090039AD3F /* SpinnerActivityIndicator */, 132 | ); 133 | }; 134 | /* End PBXProject section */ 135 | 136 | /* Begin PBXResourcesBuildPhase section */ 137 | B52632801F4CB9090039AD3F /* Resources */ = { 138 | isa = PBXResourcesBuildPhase; 139 | buildActionMask = 2147483647; 140 | files = ( 141 | B52632901F4CB9090039AD3F /* LaunchScreen.storyboard in Resources */, 142 | B526328D1F4CB9090039AD3F /* Assets.xcassets in Resources */, 143 | B526328B1F4CB9090039AD3F /* Main.storyboard in Resources */, 144 | ); 145 | runOnlyForDeploymentPostprocessing = 0; 146 | }; 147 | /* End PBXResourcesBuildPhase section */ 148 | 149 | /* Begin PBXSourcesBuildPhase section */ 150 | B526327E1F4CB9090039AD3F /* Sources */ = { 151 | isa = PBXSourcesBuildPhase; 152 | buildActionMask = 2147483647; 153 | files = ( 154 | B52632881F4CB9090039AD3F /* ViewController.swift in Sources */, 155 | B52632981F4CBB720039AD3F /* SpinnerController.swift in Sources */, 156 | B5AFD37A1FCF63F500F32CC8 /* SpinnerActivityIndicator.swift in Sources */, 157 | B52632861F4CB9090039AD3F /* AppDelegate.swift in Sources */, 158 | ); 159 | runOnlyForDeploymentPostprocessing = 0; 160 | }; 161 | /* End PBXSourcesBuildPhase section */ 162 | 163 | /* Begin PBXVariantGroup section */ 164 | B52632891F4CB9090039AD3F /* Main.storyboard */ = { 165 | isa = PBXVariantGroup; 166 | children = ( 167 | B526328A1F4CB9090039AD3F /* Base */, 168 | ); 169 | name = Main.storyboard; 170 | sourceTree = ""; 171 | }; 172 | B526328E1F4CB9090039AD3F /* LaunchScreen.storyboard */ = { 173 | isa = PBXVariantGroup; 174 | children = ( 175 | B526328F1F4CB9090039AD3F /* Base */, 176 | ); 177 | name = LaunchScreen.storyboard; 178 | sourceTree = ""; 179 | }; 180 | /* End PBXVariantGroup section */ 181 | 182 | /* Begin XCBuildConfiguration section */ 183 | B52632921F4CB9090039AD3F /* Debug */ = { 184 | isa = XCBuildConfiguration; 185 | buildSettings = { 186 | ALWAYS_SEARCH_USER_PATHS = NO; 187 | CLANG_ANALYZER_NONNULL = YES; 188 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 189 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 190 | CLANG_CXX_LIBRARY = "libc++"; 191 | CLANG_ENABLE_MODULES = YES; 192 | CLANG_ENABLE_OBJC_ARC = YES; 193 | CLANG_WARN_BOOL_CONVERSION = YES; 194 | CLANG_WARN_CONSTANT_CONVERSION = YES; 195 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 196 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 197 | CLANG_WARN_EMPTY_BODY = YES; 198 | CLANG_WARN_ENUM_CONVERSION = YES; 199 | CLANG_WARN_INFINITE_RECURSION = YES; 200 | CLANG_WARN_INT_CONVERSION = YES; 201 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 202 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 203 | CLANG_WARN_UNREACHABLE_CODE = YES; 204 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 205 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 206 | COPY_PHASE_STRIP = NO; 207 | DEBUG_INFORMATION_FORMAT = dwarf; 208 | ENABLE_STRICT_OBJC_MSGSEND = YES; 209 | ENABLE_TESTABILITY = YES; 210 | GCC_C_LANGUAGE_STANDARD = gnu99; 211 | GCC_DYNAMIC_NO_PIC = NO; 212 | GCC_NO_COMMON_BLOCKS = YES; 213 | GCC_OPTIMIZATION_LEVEL = 0; 214 | GCC_PREPROCESSOR_DEFINITIONS = ( 215 | "DEBUG=1", 216 | "$(inherited)", 217 | ); 218 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 219 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 220 | GCC_WARN_UNDECLARED_SELECTOR = YES; 221 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 222 | GCC_WARN_UNUSED_FUNCTION = YES; 223 | GCC_WARN_UNUSED_VARIABLE = YES; 224 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 225 | MTL_ENABLE_DEBUG_INFO = YES; 226 | ONLY_ACTIVE_ARCH = YES; 227 | SDKROOT = iphoneos; 228 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 229 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 230 | TARGETED_DEVICE_FAMILY = "1,2"; 231 | }; 232 | name = Debug; 233 | }; 234 | B52632931F4CB9090039AD3F /* Release */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | ALWAYS_SEARCH_USER_PATHS = NO; 238 | CLANG_ANALYZER_NONNULL = YES; 239 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 240 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 241 | CLANG_CXX_LIBRARY = "libc++"; 242 | CLANG_ENABLE_MODULES = YES; 243 | CLANG_ENABLE_OBJC_ARC = YES; 244 | CLANG_WARN_BOOL_CONVERSION = YES; 245 | CLANG_WARN_CONSTANT_CONVERSION = YES; 246 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 247 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 248 | CLANG_WARN_EMPTY_BODY = YES; 249 | CLANG_WARN_ENUM_CONVERSION = YES; 250 | CLANG_WARN_INFINITE_RECURSION = YES; 251 | CLANG_WARN_INT_CONVERSION = YES; 252 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 253 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 254 | CLANG_WARN_UNREACHABLE_CODE = YES; 255 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 256 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 257 | COPY_PHASE_STRIP = NO; 258 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 259 | ENABLE_NS_ASSERTIONS = NO; 260 | ENABLE_STRICT_OBJC_MSGSEND = YES; 261 | GCC_C_LANGUAGE_STANDARD = gnu99; 262 | GCC_NO_COMMON_BLOCKS = YES; 263 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 264 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 265 | GCC_WARN_UNDECLARED_SELECTOR = YES; 266 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 267 | GCC_WARN_UNUSED_FUNCTION = YES; 268 | GCC_WARN_UNUSED_VARIABLE = YES; 269 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 270 | MTL_ENABLE_DEBUG_INFO = NO; 271 | SDKROOT = iphoneos; 272 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 273 | TARGETED_DEVICE_FAMILY = "1,2"; 274 | VALIDATE_PRODUCT = YES; 275 | }; 276 | name = Release; 277 | }; 278 | B52632951F4CB9090039AD3F /* Debug */ = { 279 | isa = XCBuildConfiguration; 280 | buildSettings = { 281 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 282 | DEVELOPMENT_TEAM = TA9RQZV3QA; 283 | INFOPLIST_FILE = SpinnerActivityIndicatorExample/Info.plist; 284 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 285 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 286 | PRODUCT_BUNDLE_IDENTIFIER = com.SpinnerActivityIndicator; 287 | PRODUCT_NAME = "$(TARGET_NAME)"; 288 | SWIFT_VERSION = 3.0; 289 | }; 290 | name = Debug; 291 | }; 292 | B52632961F4CB9090039AD3F /* Release */ = { 293 | isa = XCBuildConfiguration; 294 | buildSettings = { 295 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 296 | DEVELOPMENT_TEAM = TA9RQZV3QA; 297 | INFOPLIST_FILE = SpinnerActivityIndicatorExample/Info.plist; 298 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 299 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 300 | PRODUCT_BUNDLE_IDENTIFIER = com.SpinnerActivityIndicator; 301 | PRODUCT_NAME = "$(TARGET_NAME)"; 302 | SWIFT_VERSION = 3.0; 303 | }; 304 | name = Release; 305 | }; 306 | /* End XCBuildConfiguration section */ 307 | 308 | /* Begin XCConfigurationList section */ 309 | B526327D1F4CB9090039AD3F /* Build configuration list for PBXProject "SpinnerActivityIndicator" */ = { 310 | isa = XCConfigurationList; 311 | buildConfigurations = ( 312 | B52632921F4CB9090039AD3F /* Debug */, 313 | B52632931F4CB9090039AD3F /* Release */, 314 | ); 315 | defaultConfigurationIsVisible = 0; 316 | defaultConfigurationName = Release; 317 | }; 318 | B52632941F4CB9090039AD3F /* Build configuration list for PBXNativeTarget "SpinnerActivityIndicator" */ = { 319 | isa = XCConfigurationList; 320 | buildConfigurations = ( 321 | B52632951F4CB9090039AD3F /* Debug */, 322 | B52632961F4CB9090039AD3F /* Release */, 323 | ); 324 | defaultConfigurationIsVisible = 0; 325 | defaultConfigurationName = Release; 326 | }; 327 | /* End XCConfigurationList section */ 328 | }; 329 | rootObject = B526327A1F4CB9090039AD3F /* Project object */; 330 | } 331 | --------------------------------------------------------------------------------