@@ -19,37 +19,38 @@ public protocol Spinner {
1919 /**
2020 Dismiss the Spinner. Implementations should remove any views from their superview.
2121
22- - Parameter enablesUserInteraction: A boolean that specifies if the user interaction on the view should be enabled when the spinner is dismissed
2322 */
24- func dismiss( enablesUserInteraction enablesUserInteraction: Bool )
25- }
26-
27- public extension Spinner {
28- func dismiss( enablesUserInteraction enablesUserInteraction: Bool = false ) { }
23+ func dismiss( )
2924}
3025
3126public class SpinnerView : NSObject , Spinner {
32-
27+
3328 //TODO: Add an option to offset the indicator in the view or button
34-
29+
3530 private var controlTitleColors : [ ControlTitleColor ] ?
3631 private var spinner : UIActivityIndicatorView ?
3732 private var imageView : UIImageView ?
38-
33+ private var userInteractionEnabledAtReception = true
34+
3935 /**
4036 To display the indicator centered in a view.
4137
4238 - Parameter view: The view to display the indicator in.
4339 - Parameter style: A constant that specifies the style of the object to be created.
4440 - Parameter color: A UIColor that specifies the tint of the spinner
45- - Parameter disablesUserInteraction: A boolean that specifies if the user interaction on the view should be disabled while the spinner is shown
41+ - Parameter disablesUserInteraction: A boolean that specifies if the user interaction on the view should be disabled while the spinner is shown. Default is true
4642
4743 - Returns: A reference to the Spinner that was created, so that it can be dismissed as needed.
4844 */
49- public static func showSpinnerInView( view: UIView , style: UIActivityIndicatorViewStyle = . White, color: UIColor ? = nil , disablesUserInteraction: Bool = false ) -> Spinner {
50- let center = CGPointMake ( view. bounds. size. width/ 2 , view. bounds. size. height/ 2 )
45+
46+ public static func showSpinnerInView( view: UIView , style: UIActivityIndicatorViewStyle = . White, color: UIColor ? = nil , disablesUserInteraction: Bool = true ) -> Spinner {
47+ let center = CGPoint ( x: view. bounds. size. width/ 2 , y: view. bounds. size. height/ 2 )
48+
5149 let spinner = UIActivityIndicatorView ( activityIndicatorStyle: style)
5250
51+ let spinnerView = SpinnerView ( )
52+ spinnerView. userInteractionEnabledAtReception = view. userInteractionEnabled
53+
5354 if disablesUserInteraction {
5455 spinner. frame = view. frame
5556 spinner. layer. backgroundColor = UIColor ( red: 0.0 , green: 0.0 , blue: 0.0 , alpha: 0.3 ) . CGColor
@@ -61,10 +62,9 @@ public class SpinnerView: NSObject, Spinner {
6162
6263 spinner. startAnimating ( )
6364 view. addSubview ( spinner)
65+ spinnerView. spinner = spinner
6466
65- let view = SpinnerView ( )
66- view. spinner = spinner
67- return view
67+ return spinnerView
6868 }
6969
7070 /**
@@ -74,83 +74,84 @@ public class SpinnerView: NSObject, Spinner {
7474 - Parameter button: The button to display the indicator in.
7575 - Parameter style: A constant that specifies the style of the object to be created.
7676 - Parameter color: A UIColor that specifies the tint of the spinner
77- - Parameter disablesUserInteraction: A boolean that specifies if the user interaction on the button should be disabled while the spinner is shown
77+ - Parameter disablesUserInteraction: A boolean that specifies if the user interaction on the button should be disabled while the spinner is shown. Default is true
7878
7979 - Returns: A reference to the Spinner that was created, so that it can be dismissed as needed.
8080 */
8181 public static func showSpinnerInButton( button: UIButton , style: UIActivityIndicatorViewStyle = . White, color: UIColor ? = nil , disablesUserInteraction: Bool = true ) -> Spinner {
82+
8283 let view = showSpinnerInView ( button, style: style, color: color)
83- button . userInteractionEnabled = !disablesUserInteraction
84+
8485 if let spinnerView = view as? SpinnerView {
86+ spinnerView. userInteractionEnabledAtReception = button. userInteractionEnabled
8587 spinnerView. controlTitleColors = button. allTitleColors ( )
8688 button. removeAllTitleColors ( )
8789 }
90+ if disablesUserInteraction {
91+ button. userInteractionEnabled = false
92+ }
8893
8994 return view
9095 }
91-
96+
9297 /**
9398 To dismiss the currently displayed indicator.
9499 The views interaction will then be enabled depending on the parameter boolean
95100 If shown in a button the titles text will become visible
96101
97- - Parameter enablesUserInteraction: A boolean that specifies if the user interaction on the view should be enabled when the spinner is dismissed
98102 */
99- public func dismiss( enablesUserInteraction: Bool = false ) {
100- if let button = spinner? . superview as? UIButton {
101- button. restoreTitleColors ( controlTitleColors)
102- if enablesUserInteraction {
103- button. userInteractionEnabled = true
103+ public func dismiss( ) {
104+
105+ if let superView = spinner? . superview {
106+ superView. userInteractionEnabled = self . userInteractionEnabledAtReception
107+ if let button = superView as? UIButton {
108+ button. restoreTitleColors ( controlTitleColors)
104109 }
110+
105111 }
106- if let view = spinner? . superview where enablesUserInteraction == true {
107- view. userInteractionEnabled = true
108- }
109-
110112 spinner? . dismiss ( )
111113 imageView? . dismiss ( )
112114 }
113115}
114116
115117// Extension of SpinnerView that supports an animated UIImageView as a custom activity indicator
116118public extension SpinnerView {
117-
119+
118120 // Private reference to a proxy UIImageView holding images for use in custom spinner.
119121 private static var animationImage : UIImageView ?
120-
122+
121123 /**
122124 Used to create the custom indicator. Call this once (on app open, for example) and it
123125 will be set for the lifetime of the app.
124-
126+
125127 - Note: Currently only supports one custom indicator. If you need multiple custom activity
126128 indicators, you are probably better off creating something custom.
127-
129+
128130 - Parameter images: An array containing the UIImages to use for the animation.
129131 - Parameter duration: The animation duration.
130132 */
131133 public static func setCustomImages( images: [ UIImage ] , duration: NSTimeInterval ) {
132-
133134 if images. count == 0 {
134135 animationImage? . removeFromSuperview ( )
135136 animationImage = nil
136137 }
137138 else {
138- let image = UIImageView ( frame: CGRectMake ( 0 , 0 , images [ 0 ] . size. width, images [ 0 ] . size. height) )
139+ let image = UIImageView ( frame: CGRect ( x : 0 , y : 0 , width : images [ 0 ] . size. width, height : images [ 0 ] . size. height) )
139140 image. animationImages = images
140141 image. animationDuration = duration
141142 animationImage = image
142143 }
143144 }
144-
145+
145146 /**
146147 To display the indicator centered in a view.
147-
148+
148149 - Note: If the `animationImage` has not been created via `setCustomImages(_:duration:)`,
149150 it will default to the normal `UIActivityIndicatorView` and will not use
150151 a custom `UIImageView`.
151-
152+
152153 - Parameter view: The view to display the indicator in.
153-
154+
154155 - Returns: A reference to the `Spinner` that was created, so that it can be dismissed as needed.
155156 */
156157 public static func showCustomSpinnerInView( view: UIView ) -> Spinner {
@@ -161,7 +162,7 @@ public extension SpinnerView {
161162 imageView. animationImages = image. animationImages
162163 imageView. startAnimating ( )
163164 view. addSubview ( imageView)
164-
165+
165166 let spinnerView = SpinnerView ( )
166167 spinnerView. imageView = imageView
167168 return spinnerView
@@ -170,13 +171,13 @@ public extension SpinnerView {
170171 return showSpinnerInView ( view)
171172 }
172173 }
173-
174+
174175 /**
175- To display the indicator centered in a button.
176+ To display the indicator centered in a button.
176177 The button's titleLabel colors will be set to clear color while the indicator is shown.
177-
178+
178179 - Parameter button: The button to display the indicator in.
179-
180+
180181 - Returns: A reference to the ActivityIndicator that was created, so that it can be dismissed as needed
181182 */
182183 public static func showCustomSpinnerInButton( button: UIButton , disablesUserInteraction: Bool = true ) -> Spinner {
@@ -186,7 +187,7 @@ public extension SpinnerView {
186187 spinnerView. controlTitleColors = button. allTitleColors ( )
187188 button. removeAllTitleColors ( )
188189 }
189-
190+
190191 return view
191192 }
192193}
@@ -195,19 +196,19 @@ public extension SpinnerView {
195196
196197// Extension to allow UIActivityIndicatorView to be dismissed.
197198extension UIActivityIndicatorView : Spinner {
198-
199+
199200 // Called when the activity indicator should be removed.
200- public func dismiss( enablesUserInteraction enablesUserInteraction : Bool = false ) {
201+ public func dismiss( ) {
201202 stopAnimating ( )
202203 removeFromSuperview ( )
203204 }
204205}
205206
206207// Extension to allow UIImageView to be dismissed
207208extension UIImageView : Spinner {
208-
209+
209210 // Called when the activity indicator should be removed.
210- public func dismiss( enablesUserInteraction enablesUserInteraction : Bool = false ) {
211+ public func dismiss( ) {
211212 stopAnimating ( )
212213 removeFromSuperview ( )
213214 }
@@ -216,7 +217,7 @@ extension UIImageView: Spinner {
216217// MARK: - Private -
217218
218219private extension UIButton {
219-
220+
220221 // Extension to return an array of every color for every button state
221222 private func allTitleColors( ) -> [ ControlTitleColor ] {
222223 var colors : [ ControlTitleColor ] = [
@@ -227,30 +228,30 @@ private extension UIButton {
227228 ( . Application, titleColorForState ( . Application) ) ,
228229 ( . Reserved, titleColorForState ( . Reserved) )
229230 ]
230-
231+
231232 if #available( iOS 9 . 0 , * ) {
232233 colors. append ( ( . Focused, titleColorForState ( . Focused) ) )
233234 }
234-
235+
235236 return colors
236237 }
237-
238+
238239 /**
239- Function to set the buttons title colors to specific button states passed in the array parameter
240-
241- - Parameter colors: An array of ControlTitleColor each containing a UIControlState and a UIColor
242- */
240+ Function to set the buttons title colors to specific button states passed in the array parameter
241+
242+ - Parameter colors: An array of ControlTitleColor each containing a UIControlState and a UIColor
243+ */
243244 private func restoreTitleColors( colors: [ ControlTitleColor ] ? ) {
244245 guard let colors = colors else { return }
245246 for color in colors {
246247 setTitleColor ( color. 1 , forState: color. 0 )
247248 }
248249 }
249-
250+
250251 /**
251252 Sets all the the buttons title colors to clear
252253 */
253254 private func removeAllTitleColors( ) {
254255 restoreTitleColors ( allTitleColors ( ) . map ( { return ( $0. 0 , UIColor . clearColor ( ) ) } ) )
255256 }
256- }
257+ }
0 commit comments