@@ -16,15 +16,22 @@ import UIKit
16 value = min(maximumValue, max(minimumValue, value))
16 value = min(maximumValue, max(minimumValue, value))
18 let isInteger = floor(value) == value
18 let isInteger = floor(value) == value
21+ // If we have items, we will display them as steps
24+ if isInteger && stepValue == 1.0 && items.count > 0 {
25+ label.text = items[Int(value)]
20− if showIntegerIfDoubleIsInteger && isInteger {
27+ else if showIntegerIfDoubleIsInteger && isInteger {
21 label.text = String(stringInterpolationSegment: Int(value))
28 label.text = String(stringInterpolationSegment: Int(value))
23 label.text = String(stringInterpolationSegment: value)
30 label.text = String(stringInterpolationSegment: value)
26 if oldValue != value {
33 if oldValue != value {
27− sendActionsForControlEvents(.ValueChanged)
34+ sendActions(for: .valueChanged)
@@ -55,22 +62,22 @@ import UIKit
55 /// Text on the left button. Be sure that it fits in the button. Defaults to "−".
62 /// Text on the left button. Be sure that it fits in the button. Defaults to "−".
56 @IBInspectable public var leftButtonText: String = "−" {
63 @IBInspectable public var leftButtonText: String = "−" {
58− leftButton.setTitle(leftButtonText, forState: .Normal)
65+ leftButton.setTitle(leftButtonText, for: .normal)
62 /// Text on the right button. Be sure that it fits in the button. Defaults to "+".
69 /// Text on the right button. Be sure that it fits in the button. Defaults to "+".
63 @IBInspectable public var rightButtonText: String = "+" {
70 @IBInspectable public var rightButtonText: String = "+" {
65− rightButton.setTitle(rightButtonText, forState: .Normal)
72+ rightButton.setTitle(rightButtonText, for: .normal)
69 /// Text color of the buttons. Defaults to white.
76 /// Text color of the buttons. Defaults to white.
70− @IBInspectable public var buttonsTextColor: UIColor = UIColor.whiteColor() {
77+ @IBInspectable public var buttonsTextColor: UIColor = UIColor.white {
72 for button in [leftButton, rightButton] {
79 for button in [leftButton, rightButton] {
73− button.setTitleColor(buttonsTextColor, forState: .Normal)
80+ button.setTitleColor(buttonsTextColor, for: .normal)
@@ -95,7 +102,7 @@ import UIKit
97 /// Text color of the middle label. Defaults to white.
104 /// Text color of the middle label. Defaults to white.
98− @IBInspectable public var labelTextColor: UIColor = UIColor.whiteColor() {
105+ @IBInspectable public var labelTextColor: UIColor = UIColor.white {
100 label.textColor = labelTextColor
107 label.textColor = labelTextColor
@@ -132,10 +139,10 @@ import UIKit
134 /// Color of the border of the stepper and middle label's layer. Defaults to clear color.
141 /// Color of the border of the stepper and middle label's layer. Defaults to clear color.
135− @IBInspectable public var borderColor: UIColor = UIColor.clearColor() {
142+ @IBInspectable public var borderColor: UIColor = UIColor.clear {
137− layer.borderColor = borderColor.CGColor
144+ layer.borderColor = borderColor.cgColor
138− label.layer.borderColor = borderColor.CGColor
145+ label.layer.borderColor = borderColor.cgColor
@@ -156,38 +163,38 @@ import UIKit
156 let labelSlideLength: CGFloat = 5
163 let labelSlideLength: CGFloat = 5
158 /// Duration of the sliding animation
165 /// Duration of the sliding animation
159− let labelSlideDuration = NSTimeInterval(0.1)
166+ let labelSlideDuration = TimeInterval(0.1)
161 /// Duration of the animation when the value hits the limit.
168 /// Duration of the animation when the value hits the limit.
162− let limitHitAnimationDuration = NSTimeInterval(0.1)
169+ let limitHitAnimationDuration = TimeInterval(0.1)
164 lazy var leftButton: UIButton = {
171 lazy var leftButton: UIButton = {
165 let button = UIButton()
172 let button = UIButton()
166− button.setTitle(self.leftButtonText, forState: .Normal)
173+ button.setTitle(self.leftButtonText, for: .normal)
167− button.setTitleColor(self.buttonsTextColor, forState: .Normal)
174+ button.setTitleColor(self.buttonsTextColor, for: .normal)
168 button.backgroundColor = self.buttonsBackgroundColor
175 button.backgroundColor = self.buttonsBackgroundColor
169 button.titleLabel?.font = self.buttonsFont
176 button.titleLabel?.font = self.buttonsFont
170− button.addTarget(self, action: #selector(GMStepper.leftButtonTouchDown), forControlEvents: .TouchDown)
177+ button.addTarget(self, action: #selector(GMStepper.leftButtonTouchDown), for: .touchDown)
171− button.addTarget(self, action: #selector(GMStepper.buttonTouchUp), forControlEvents: .TouchUpInside)
178+ button.addTarget(self, action: #selector(GMStepper.buttonTouchUp), for: .touchUpInside)
172− button.addTarget(self, action: #selector(GMStepper.buttonTouchUp), forControlEvents: .TouchUpOutside)
179+ button.addTarget(self, action: #selector(GMStepper.buttonTouchUp), for: .touchUpOutside)
173 return button
180 return button
176 lazy var rightButton: UIButton = {
183 lazy var rightButton: UIButton = {
177 let button = UIButton()
184 let button = UIButton()
178− button.setTitle(self.rightButtonText, forState: .Normal)
185+ button.setTitle(self.rightButtonText, for: .normal)
179− button.setTitleColor(self.buttonsTextColor, forState: .Normal)
186+ button.setTitleColor(self.buttonsTextColor, for: .normal)
180 button.backgroundColor = self.buttonsBackgroundColor
187 button.backgroundColor = self.buttonsBackgroundColor
181 button.titleLabel?.font = self.buttonsFont
188 button.titleLabel?.font = self.buttonsFont
182− button.addTarget(self, action: #selector(GMStepper.rightButtonTouchDown), forControlEvents: .TouchDown)
189+ button.addTarget(self, action: #selector(GMStepper.rightButtonTouchDown), for: .touchDown)
183− button.addTarget(self, action: #selector(GMStepper.buttonTouchUp), forControlEvents: .TouchUpInside)
190+ button.addTarget(self, action: #selector(GMStepper.buttonTouchUp), for: .touchUpInside)
184− button.addTarget(self, action: #selector(GMStepper.buttonTouchUp), forControlEvents: .TouchUpOutside)
191+ button.addTarget(self, action: #selector(GMStepper.buttonTouchUp), for: .touchUpOutside)
185 return button
192 return button
188 lazy var label: UILabel = {
195 lazy var label: UILabel = {
189 let label = UILabel()
196 let label = UILabel()
190− label.textAlignment = .Center
197+ label.textAlignment = .center
191 if self.showIntegerIfDoubleIsInteger && floor(self.value) == self.value {
198 if self.showIntegerIfDoubleIsInteger && floor(self.value) == self.value {
192 label.text = String(stringInterpolationSegment: Int(self.value))
199 label.text = String(stringInterpolationSegment: Int(self.value))
@@ -196,7 +203,7 @@ import UIKit
196 label.textColor = self.labelTextColor
203 label.textColor = self.labelTextColor
197 label.backgroundColor = self.labelBackgroundColor
204 label.backgroundColor = self.labelBackgroundColor
198 label.font = self.labelFont
205 label.font = self.labelFont
199− label.userInteractionEnabled = true
206+ label.isUserInteractionEnabled = true
200 let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(GMStepper.handlePan))
207 let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(GMStepper.handlePan))
201 panRecognizer.maximumNumberOfTouches = 1
208 panRecognizer.maximumNumberOfTouches = 1
202 label.addGestureRecognizer(panRecognizer)
209 label.addGestureRecognizer(panRecognizer)
@@ -225,9 +232,33 @@ import UIKit
237+ public var items : [String] = [] {
239+ let isInteger = floor(value) == value
242+ // If we have items, we will display them as steps
245+ if isInteger && stepValue == 1.0 && items.count > 0 {
247+ var value = Int(self.value)
249+ if value >= items.count {
250+ value = items.count - 1
251+ self.value = Double(value)
254+ label.text = items[value]
229 /// Timer used for autorepeat option
260 /// Timer used for autorepeat option
230− var timer: NSTimer?
261+ var timer: Timer?
232 /** When UIStepper reaches its top speed, it alters the value with a time interval of ~0.05 sec.
263 /** When UIStepper reaches its top speed, it alters the value with a time interval of ~0.05 sec.
233 The user pressing and holding on the stepper repeatedly:
264 The user pressing and holding on the stepper repeatedly:
@@ -235,7 +266,7 @@ import UIKit
235 - For the next 1.5 sec, it changes the value every 0.1 sec.
266 - For the next 1.5 sec, it changes the value every 0.1 sec.
236 - Then, every 0.05 sec.
267 - Then, every 0.05 sec.
238− let timerInterval = NSTimeInterval(0.05)
269+ let timerInterval = TimeInterval(0.05)
240 /// Check the handleTimerFire: function. While it is counting the number of fires, it decreases the mod value so that the value is altered more frequently.
271 /// Check the handleTimerFire: function. While it is counting the number of fires, it decreases the mod value so that the value is altered more frequently.
241 var timerFireCount = 0
272 var timerFireCount = 0
@@ -268,7 +299,7 @@ import UIKit
268 layer.cornerRadius = cornerRadius
299 layer.cornerRadius = cornerRadius
269 clipsToBounds = true
300 clipsToBounds = true
271− NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(GMStepper.reset), name: UIApplicationWillResignActiveNotification, object: nil)
302+ NotificationCenter.default.addObserver(self, selector: #selector(GMStepper.reset), name: NSNotification.Name.UIApplicationWillResignActive, object: nil)
274 public override func layoutSubviews() {
305 public override func layoutSubviews() {
@@ -294,7 +325,7 @@ import UIKit
296 resetTimer()
327 resetTimer()
297− NSNotificationCenter.defaultCenter().removeObserver(self)
328+ NotificationCenter.default.removeObserver(self)
300 /// Useful closure for logging the timer interval. You can call this in the timer handler to test the autorepeat option. Not used in the current implementation.
331 /// Useful closure for logging the timer interval. You can call this in the timer handler to test the autorepeat option. Not used in the current implementation.
@@ -315,15 +346,15 @@ import UIKit
315extension GMStepper {
346extension GMStepper {
316 func handlePan(gesture: UIPanGestureRecognizer) {
347 func handlePan(gesture: UIPanGestureRecognizer) {
317 switch gesture.state {
348 switch gesture.state {
318− case .Began:
349+ case .began:
319− leftButton.enabled = false
350+ leftButton.isEnabled = false
320− rightButton.enabled = false
351+ rightButton.isEnabled = false
321− case .Changed:
352+ case .changed:
322− let translation = gesture.translationInView(label)
353+ let translation = gesture.translation(in: label)
323− gesture.setTranslation(CGPointZero, inView: label)
354+ gesture.setTranslation(CGPoint.zero, in: label)
325− let slidingRight = gesture.velocityInView(label).x > 0
356+ let slidingRight = gesture.velocity(in: label).x > 0
326− let slidingLeft = gesture.velocityInView(label).x < 0
357+ let slidingLeft = gesture.velocity(in: label).x < 0
328 // Move the label with pan
359 // Move the label with pan
329 if slidingRight {
360 if slidingRight {
@@ -356,7 +387,7 @@ extension GMStepper {
356 self.rightButton.backgroundColor = self.buttonsBackgroundColor
387 self.rightButton.backgroundColor = self.buttonsBackgroundColor
357 self.leftButton.backgroundColor = self.buttonsBackgroundColor
388 self.leftButton.backgroundColor = self.buttonsBackgroundColor
359− case .Ended, .Cancelled, .Failed:
390+ case .ended, .cancelled, .failed:
@@ -368,11 +399,11 @@ extension GMStepper {
368 stepperState = .Stable
399 stepperState = .Stable
369 resetTimer()
400 resetTimer()
371− leftButton.enabled = true
402+ leftButton.isEnabled = true
372− rightButton.enabled = true
403+ rightButton.isEnabled = true
373− label.userInteractionEnabled = true
404+ label.isUserInteractionEnabled = true
375− UIView.animateWithDuration(self.labelSlideDuration, animations: {
406+ UIView.animate(withDuration: self.labelSlideDuration, animations: {
376 self.label.center = self.labelOriginalCenter
407 self.label.center = self.labelOriginalCenter
377 self.rightButton.backgroundColor = self.buttonsBackgroundColor
408 self.rightButton.backgroundColor = self.buttonsBackgroundColor
378 self.leftButton.backgroundColor = self.buttonsBackgroundColor
409 self.leftButton.backgroundColor = self.buttonsBackgroundColor
@@ -383,8 +414,8 @@ extension GMStepper {
383// MARK: Button Events
414// MARK: Button Events
384extension GMStepper {
415extension GMStepper {
385 func leftButtonTouchDown(button: UIButton) {
416 func leftButtonTouchDown(button: UIButton) {
386− rightButton.enabled = false
417+ rightButton.isEnabled = false
387− label.userInteractionEnabled = false
418+ label.isUserInteractionEnabled = false
388 resetTimer()
419 resetTimer()
390 if value == minimumValue {
421 if value == minimumValue {
@@ -397,8 +428,8 @@ extension GMStepper {
399 func rightButtonTouchDown(button: UIButton) {
430 func rightButtonTouchDown(button: UIButton) {
400− leftButton.enabled = false
431+ leftButton.isEnabled = false
401− label.userInteractionEnabled = false
432+ label.isUserInteractionEnabled = false
402 resetTimer()
433 resetTimer()
404 if value == maximumValue {
435 if value == maximumValue {
@@ -418,20 +449,20 @@ extension GMStepper {
418extension GMStepper {
449extension GMStepper {
420 func animateSlideLeft() {
451 func animateSlideLeft() {
421− UIView.animateWithDuration(labelSlideDuration) {
452+ UIView.animate(withDuration: labelSlideDuration) {
422 self.label.center.x -= self.labelSlideLength
453 self.label.center.x -= self.labelSlideLength
426 func animateSlideRight() {
457 func animateSlideRight() {
427− UIView.animateWithDuration(labelSlideDuration) {
458+ UIView.animate(withDuration: labelSlideDuration) {
428 self.label.center.x += self.labelSlideLength
459 self.label.center.x += self.labelSlideLength
432 func animateToOriginalPosition() {
463 func animateToOriginalPosition() {
433 if self.label.center != self.labelOriginalCenter {
464 if self.label.center != self.labelOriginalCenter {
434− UIView.animateWithDuration(labelSlideDuration) {
465+ UIView.animate(withDuration: labelSlideDuration) {
435 self.label.center = self.labelOriginalCenter
466 self.label.center = self.labelOriginalCenter
@@ -439,14 +470,14 @@ extension GMStepper {
440 func animateLimitHitIfNeeded() {
471 func animateLimitHitIfNeeded() {
441 if value == minimumValue {
472 if value == minimumValue {
442− animateLimitHitForButton(leftButton)
473+ animateLimitHitForButton(button: leftButton)
443 } else if value == maximumValue {
474 } else if value == maximumValue {
444− animateLimitHitForButton(rightButton)
475+ animateLimitHitForButton(button: rightButton)
448 func animateLimitHitForButton(button: UIButton){
479 func animateLimitHitForButton(button: UIButton){
449− UIView.animateWithDuration(limitHitAnimationDuration) {
480+ UIView.animate(withDuration: limitHitAnimationDuration) {
450 button.backgroundColor = self.limitHitAnimationColor
481 button.backgroundColor = self.limitHitAnimationColor
@@ -454,7 +485,7 @@ extension GMStepper {
455// MARK: Timer
486// MARK: Timer
456extension GMStepper {
487extension GMStepper {
457− func handleTimerFire(timer: NSTimer) {
488+ func handleTimerFire(timer: Timer) {
458 timerFireCount += 1
489 timerFireCount += 1
460 if timerFireCount % timerFireCountModulo == 0 {
491 if timerFireCount % timerFireCountModulo == 0 {
@@ -463,7 +494,7 @@ extension GMStepper {
465 func scheduleTimer() {
496 func scheduleTimer() {
466− timer = NSTimer.scheduledTimerWithTimeInterval(timerInterval, target: self, selector: #selector(GMStepper.handleTimerFire), userInfo: nil, repeats: true)
497+ timer = Timer.scheduledTimer(timeInterval: timerInterval, target: self, selector: #selector(GMStepper.handleTimerFire), userInfo: nil, repeats: true)
469 func resetTimer() {
500 func resetTimer() {