Compare commits
43 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
d7c8bb83b0 | |
|
|
810fcbefea | |
|
|
f893371f73 | |
|
|
9444b32028 | |
|
|
dd09a1e0d9 | |
|
|
a02560f7e0 | |
|
|
3c81fa9ade | |
|
|
719830b81e | |
|
|
82453c0681 | |
|
|
7367554d53 | |
|
|
4bb23e79aa | |
|
|
e91c2577e4 | |
|
|
d81e614d1b | |
|
|
338fa1ebad | |
|
|
ae98a8c70b | |
|
|
c2748bb776 | |
|
|
4c5bfffbb8 | |
|
|
71c1c1b9a6 | |
|
|
b470b560b9 | |
|
|
a47725de8b | |
|
|
8af374c283 | |
|
|
88dd8d76b6 | |
|
|
07616aa0ff | |
|
|
44f1477df1 | |
|
|
fae1225e36 | |
|
|
ae068ac0fd | |
|
|
35f3db649a | |
|
|
96389e6d75 | |
|
|
c136918409 | |
|
|
f52eb0448b | |
|
|
43d38b5973 | |
|
|
5d4d5a4989 | |
|
|
8631f60be1 | |
|
|
31d50f82f7 | |
|
|
36df74db47 | |
|
|
bc199530cb | |
|
|
b7acb5d479 | |
|
|
993b8297e2 | |
|
|
39296c9815 | |
|
|
a3f6ab1441 | |
|
|
0ee7bfa26c | |
|
|
9bc287a1b5 | |
|
|
f380fc31d0 |
|
|
@ -31,3 +31,5 @@ DerivedData
|
|||
# Carthage/Checkouts
|
||||
|
||||
Carthage/Build
|
||||
|
||||
.DS_Store
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
4.2
|
||||
|
|
@ -1,14 +1,16 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = "GMStepper"
|
||||
s.version = "1.0.1"
|
||||
s.version = "2.2.1"
|
||||
s.summary = "A stepper with a sliding label in the middle."
|
||||
s.homepage = "https://github.com/gmertk/GMStepper"
|
||||
s.screenshots = "https://dl.dropboxusercontent.com/u/4397140/pod-screenshots/screenshot_1.png"
|
||||
s.screenshots = "https://raw.githubusercontent.com/gmertk/GMStepper/master/Screenshots/screenshot_1.gif"
|
||||
s.license = 'MIT'
|
||||
s.author = { "Gunay Mert Karadogan" => "mertkaradogan@gmail.com" }
|
||||
s.authors = { "Gunay Mert Karadogan" => "mertkaradogan@gmail.com",
|
||||
"Brent Whitman" => "brent@pathym.com" }
|
||||
s.source = { :git => "https://github.com/gmertk/GMStepper.git", :tag => s.version.to_s }
|
||||
s.social_media_url = 'https://twitter.com/gunaymertk'
|
||||
s.platform = :ios, '8.0'
|
||||
s.requires_arc = true
|
||||
s.source_files = 'GMStepper/*.swift'
|
||||
s.swift_version = '4.2'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,72 +11,96 @@ import UIKit
|
|||
@IBDesignable public class GMStepper: UIControl {
|
||||
|
||||
/// Current value of the stepper. Defaults to 0.
|
||||
@IBInspectable public var value: Double = 0 {
|
||||
@objc @IBInspectable public var value: Double = 0 {
|
||||
didSet {
|
||||
value = min(maximumValue, max(minimumValue, value))
|
||||
|
||||
let isInteger = floor(value) == value
|
||||
handleIsLimitReached()
|
||||
|
||||
if showIntegerIfDoubleIsInteger && isInteger {
|
||||
label.text = String(stringInterpolationSegment: Int(value))
|
||||
} else {
|
||||
label.text = String(stringInterpolationSegment: value)
|
||||
}
|
||||
label.text = formattedValue
|
||||
|
||||
if oldValue != value {
|
||||
sendActionsForControlEvents(.ValueChanged)
|
||||
sendActions(for: .valueChanged)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var formattedValue: String? {
|
||||
let isInteger = Decimal(value).exponent >= 0
|
||||
|
||||
// If we have items, we will display them as steps
|
||||
if isInteger && stepValue == 1.0 && items.count > 0 {
|
||||
return items[Int(value)]
|
||||
}
|
||||
else {
|
||||
return formatter.string(from: NSNumber(value: value))
|
||||
}
|
||||
}
|
||||
|
||||
/// Minimum value. Must be less than maximumValue. Defaults to 0.
|
||||
@IBInspectable public var minimumValue: Double = 0 {
|
||||
@objc @IBInspectable public var minimumValue: Double = 0 {
|
||||
didSet {
|
||||
value = min(maximumValue, max(minimumValue, value))
|
||||
}
|
||||
}
|
||||
|
||||
/// Maximum value. Must be more than minimumValue. Defaults to 100.
|
||||
@IBInspectable public var maximumValue: Double = 100 {
|
||||
@objc @IBInspectable public var maximumValue: Double = 100 {
|
||||
didSet {
|
||||
value = min(maximumValue, max(minimumValue, value))
|
||||
}
|
||||
}
|
||||
|
||||
/// Step/Increment value as in UIStepper. Defaults to 1.
|
||||
@IBInspectable public var stepValue: Double = 1
|
||||
@objc @IBInspectable public var stepValue: Double = 1 {
|
||||
didSet {
|
||||
setupNumberFormatter()
|
||||
}
|
||||
}
|
||||
|
||||
/// The same as UIStepper's autorepeat. If true, holding on the buttons or keeping the pan gesture alters the value repeatedly. Defaults to true.
|
||||
@IBInspectable public var autorepeat: Bool = true
|
||||
@objc @IBInspectable public var autorepeat: Bool = true
|
||||
|
||||
/// If the value is integer, it is shown without floating point.
|
||||
@IBInspectable public var showIntegerIfDoubleIsInteger: Bool = true
|
||||
|
||||
/// Text on the left button. Be sure that it fits in the button. Defaults to "-".
|
||||
@IBInspectable public var leftButtonText: String = "-" {
|
||||
@objc @IBInspectable public var showIntegerIfDoubleIsInteger: Bool = true {
|
||||
didSet {
|
||||
leftButton.setTitle(leftButtonText, forState: .Normal)
|
||||
setupNumberFormatter()
|
||||
}
|
||||
}
|
||||
|
||||
/// Text on the right button. Be sure that it fits in the button. Defaults to "+".
|
||||
@IBInspectable public var rightButtonText: String = "+" {
|
||||
/// Image on the left button. Defaults to nil.
|
||||
@objc @IBInspectable public var leftButtonImage: UIImage? = nil {
|
||||
didSet {
|
||||
rightButton.setTitle(rightButtonText, forState: .Normal)
|
||||
leftButton.setImage(leftButtonImage, for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
/// Text color of the buttons. Defaults to white.
|
||||
@IBInspectable public var buttonsTextColor: UIColor = UIColor.whiteColor() {
|
||||
/// Image on the right button. Defaults to nil.
|
||||
@objc @IBInspectable public var rightButtonImage: UIImage? = nil {
|
||||
didSet {
|
||||
for button in [leftButton, rightButton] {
|
||||
button.setTitleColor(buttonsTextColor, forState: .Normal)
|
||||
}
|
||||
rightButton.setImage(rightButtonImage, for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
/// Left button content insets. Defaults to ".zero".
|
||||
@objc @IBInspectable public var leftButtonContentInsets: UIEdgeInsets = .zero {
|
||||
didSet {
|
||||
leftButton.contentEdgeInsets = leftButtonContentInsets
|
||||
}
|
||||
}
|
||||
|
||||
/// Right button content insets. Defaults to ".zero".
|
||||
@objc @IBInspectable public var rightButtonContentInsets: UIEdgeInsets = .zero {
|
||||
didSet {
|
||||
rightButton.contentEdgeInsets = rightButtonContentInsets
|
||||
}
|
||||
}
|
||||
|
||||
/// Left button limit opacity. Defaults to "0.4".
|
||||
@objc @IBInspectable public var leftButtonLimitOpacity: CGFloat = 0.4
|
||||
|
||||
/// Background color of the buttons. Defaults to dark blue.
|
||||
@IBInspectable public var buttonsBackgroundColor: UIColor = UIColor(red:0.21, green:0.5, blue:0.74, alpha:1) {
|
||||
@objc @IBInspectable public var buttonsBackgroundColor: UIColor = UIColor(red:0.21, green:0.5, blue:0.74, alpha:1) {
|
||||
didSet {
|
||||
for button in [leftButton, rightButton] {
|
||||
button.backgroundColor = buttonsBackgroundColor
|
||||
|
|
@ -85,46 +109,66 @@ import UIKit
|
|||
}
|
||||
}
|
||||
|
||||
/// Font of the buttons. Defaults to AvenirNext-Bold, 20.0 points in size.
|
||||
public var buttonsFont = UIFont(name: "AvenirNext-Bold", size: 20.0)! {
|
||||
didSet {
|
||||
for button in [leftButton, rightButton] {
|
||||
button.titleLabel?.font = buttonsFont
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Label tap closure
|
||||
@objc public var didTouchLabel: ((Double) -> Void)?
|
||||
|
||||
/// Block is called when the minimum is exceeded
|
||||
@objc public var minimumExceeded: (() -> Void)?
|
||||
|
||||
/// Text color of the middle label. Defaults to white.
|
||||
@IBInspectable public var labelTextColor: UIColor = UIColor.whiteColor() {
|
||||
@objc @IBInspectable public var labelTextColor: UIColor = UIColor.white {
|
||||
didSet {
|
||||
label.textColor = labelTextColor
|
||||
}
|
||||
}
|
||||
|
||||
/// Text color of the middle label. Defaults to lighter blue.
|
||||
@IBInspectable public var labelBackgroundColor: UIColor = UIColor(red:0.26, green:0.6, blue:0.87, alpha:1) {
|
||||
@objc @IBInspectable public var labelBackgroundColor: UIColor = UIColor(red:0.26, green:0.6, blue:0.87, alpha:1) {
|
||||
didSet {
|
||||
label.backgroundColor = labelBackgroundColor
|
||||
}
|
||||
}
|
||||
|
||||
/// Font of the middle label. Defaults to AvenirNext-Bold, 25.0 points in size.
|
||||
public var labelFont = UIFont(name: "AvenirNext-Bold", size: 25.0)! {
|
||||
@objc public var labelFont = UIFont(name: "AvenirNext-Bold", size: 25.0)! {
|
||||
didSet {
|
||||
label.font = labelFont
|
||||
}
|
||||
}
|
||||
/// Corner radius of the middle label. Defaults to 0.
|
||||
@objc @IBInspectable public var labelCornerRadius: CGFloat = 0 {
|
||||
didSet {
|
||||
label.layer.cornerRadius = labelCornerRadius
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// Corner radius of the stepper's layer. Defaults to 4.0.
|
||||
@IBInspectable public var cornerRadius: CGFloat = 4.0 {
|
||||
@objc @IBInspectable public var cornerRadius: CGFloat = 4.0 {
|
||||
didSet {
|
||||
layer.cornerRadius = cornerRadius
|
||||
clipsToBounds = true
|
||||
}
|
||||
}
|
||||
|
||||
/// Border width of the stepper and middle label's layer. Defaults to 0.0.
|
||||
@objc @IBInspectable public var borderWidth: CGFloat = 0.0 {
|
||||
didSet {
|
||||
layer.borderWidth = borderWidth
|
||||
label.layer.borderWidth = borderWidth
|
||||
}
|
||||
}
|
||||
|
||||
/// Color of the border of the stepper and middle label's layer. Defaults to clear color.
|
||||
@objc @IBInspectable public var borderColor: UIColor = UIColor.clear {
|
||||
didSet {
|
||||
layer.borderColor = borderColor.cgColor
|
||||
label.layer.borderColor = borderColor.cgColor
|
||||
}
|
||||
}
|
||||
|
||||
/// Percentage of the middle label's width. Must be between 0 and 1. Defaults to 0.5. Be sure that it is wide enough to show the value.
|
||||
@IBInspectable public var labelWidthWeight: CGFloat = 0.5 {
|
||||
@objc @IBInspectable public var labelWidthWeight: CGFloat = 0.5 {
|
||||
didSet {
|
||||
labelWidthWeight = min(1, max(0, labelWidthWeight))
|
||||
setNeedsLayout()
|
||||
|
|
@ -132,58 +176,59 @@ import UIKit
|
|||
}
|
||||
|
||||
/// Color of the flashing animation on the buttons in case the value hit the limit.
|
||||
@IBInspectable public var limitHitAnimationColor: UIColor = UIColor(red:0.26, green:0.6, blue:0.87, alpha:1)
|
||||
@objc @IBInspectable public var limitHitAnimationColor: UIColor = UIColor(red:0.26, green:0.6, blue:0.87, alpha:1)
|
||||
|
||||
/// Formatter for displaying the current value
|
||||
let formatter = NumberFormatter()
|
||||
|
||||
/**
|
||||
Width of the sliding animation. When buttons clicked, the middle label does a slide animation towards to the clicked button. Defaults to 5.
|
||||
*/
|
||||
let labelSlideLength: CGFloat = 5
|
||||
|
||||
/// Duration of the sliding animation
|
||||
let labelSlideDuration = NSTimeInterval(0.1)
|
||||
let labelSlideDuration = TimeInterval(0.1)
|
||||
|
||||
/// Duration of the animation when the value hits the limit.
|
||||
let limitHitAnimationDuration = NSTimeInterval(0.1)
|
||||
let limitHitAnimationDuration = TimeInterval(0.1)
|
||||
|
||||
lazy var leftButton: UIButton = {
|
||||
let button = UIButton()
|
||||
button.setTitle(self.leftButtonText, forState: .Normal)
|
||||
button.setTitleColor(self.buttonsTextColor, forState: .Normal)
|
||||
button.setImage(self.leftButtonImage, for: .normal)
|
||||
button.backgroundColor = self.buttonsBackgroundColor
|
||||
button.titleLabel?.font = self.buttonsFont
|
||||
button.addTarget(self, action: "leftButtonTouchDown:", forControlEvents: .TouchDown)
|
||||
button.addTarget(self, action: "buttonTouchUp:", forControlEvents: UIControlEvents.TouchUpInside)
|
||||
button.addTarget(self, action: "buttonTouchUp:", forControlEvents: UIControlEvents.TouchUpOutside)
|
||||
button.addTarget(self, action: #selector(GMStepper.leftButtonTouchDown), for: .touchDown)
|
||||
button.addTarget(self, action: #selector(GMStepper.buttonTouchUp), for: .touchUpInside)
|
||||
button.addTarget(self, action: #selector(GMStepper.buttonTouchUp), for: .touchUpOutside)
|
||||
button.addTarget(self, action: #selector(GMStepper.buttonTouchUp), for: .touchCancel)
|
||||
return button
|
||||
}()
|
||||
|
||||
lazy var rightButton: UIButton = {
|
||||
let button = UIButton()
|
||||
button.setTitle(self.rightButtonText, forState: .Normal)
|
||||
button.setTitleColor(self.buttonsTextColor, forState: .Normal)
|
||||
button.setImage(self.rightButtonImage, for: .normal)
|
||||
button.backgroundColor = self.buttonsBackgroundColor
|
||||
button.titleLabel?.font = self.buttonsFont
|
||||
button.addTarget(self, action: "rightButtonTouchDown:", forControlEvents: .TouchDown)
|
||||
button.addTarget(self, action: "buttonTouchUp:", forControlEvents: UIControlEvents.TouchUpInside)
|
||||
button.addTarget(self, action: "buttonTouchUp:", forControlEvents: UIControlEvents.TouchUpOutside)
|
||||
button.addTarget(self, action: #selector(GMStepper.rightButtonTouchDown), for: .touchDown)
|
||||
button.addTarget(self, action: #selector(GMStepper.buttonTouchUp), for: .touchUpInside)
|
||||
button.addTarget(self, action: #selector(GMStepper.buttonTouchUp), for: .touchUpOutside)
|
||||
button.addTarget(self, action: #selector(GMStepper.buttonTouchUp), for: .touchCancel)
|
||||
return button
|
||||
}()
|
||||
|
||||
lazy var label: UILabel = {
|
||||
let label = UILabel()
|
||||
label.textAlignment = .Center
|
||||
if self.showIntegerIfDoubleIsInteger && floor(self.value) == self.value {
|
||||
label.text = String(stringInterpolationSegment: Int(self.value))
|
||||
} else {
|
||||
label.text = String(stringInterpolationSegment: self.value)
|
||||
}
|
||||
label.textAlignment = .center
|
||||
label.text = formattedValue
|
||||
label.textColor = self.labelTextColor
|
||||
label.backgroundColor = self.labelBackgroundColor
|
||||
label.font = self.labelFont
|
||||
label.userInteractionEnabled = true
|
||||
let panRecognizer = UIPanGestureRecognizer(target: self, action: "handlePan:")
|
||||
label.layer.cornerRadius = self.labelCornerRadius
|
||||
label.layer.masksToBounds = true
|
||||
label.isUserInteractionEnabled = true
|
||||
let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(GMStepper.handlePan))
|
||||
panRecognizer.maximumNumberOfTouches = 1
|
||||
label.addGestureRecognizer(panRecognizer)
|
||||
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(GMStepper.handleLabelTap))
|
||||
label.addGestureRecognizer(tapRecognizer)
|
||||
return label
|
||||
}()
|
||||
|
||||
|
|
@ -209,9 +254,16 @@ import UIKit
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@objc public var items : [String] = [] {
|
||||
didSet {
|
||||
label.text = formattedValue
|
||||
}
|
||||
}
|
||||
|
||||
/// Timer used for autorepeat option
|
||||
var timer: NSTimer?
|
||||
var timer: Timer?
|
||||
|
||||
/** When UIStepper reaches its top speed, it alters the value with a time interval of ~0.05 sec.
|
||||
The user pressing and holding on the stepper repeatedly:
|
||||
|
|
@ -219,7 +271,7 @@ import UIKit
|
|||
- For the next 1.5 sec, it changes the value every 0.1 sec.
|
||||
- Then, every 0.05 sec.
|
||||
*/
|
||||
let timerInterval = NSTimeInterval(0.05)
|
||||
let timerInterval = TimeInterval(0.05)
|
||||
|
||||
/// 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.
|
||||
var timerFireCount = 0
|
||||
|
|
@ -233,39 +285,38 @@ import UIKit
|
|||
}
|
||||
}
|
||||
|
||||
/// Useful for logging the timer interval. You can call this in the timer handler to test the autorepeat option.
|
||||
lazy var printTimerGaps: () -> () = {
|
||||
var prevTime: CFAbsoluteTime?
|
||||
|
||||
return { _ in
|
||||
var now = CFAbsoluteTimeGetCurrent()
|
||||
if let prevTime = prevTime {
|
||||
println(now - prevTime)
|
||||
}
|
||||
prevTime = now
|
||||
}
|
||||
}()
|
||||
|
||||
required public init(coder aDecoder: NSCoder) {
|
||||
@objc required public init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
setup()
|
||||
}
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
@objc public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
setup()
|
||||
}
|
||||
|
||||
func setup() {
|
||||
fileprivate func setup() {
|
||||
addSubview(leftButton)
|
||||
addSubview(rightButton)
|
||||
addSubview(label)
|
||||
|
||||
handleIsLimitReached()
|
||||
backgroundColor = buttonsBackgroundColor
|
||||
layer.cornerRadius = cornerRadius
|
||||
clipsToBounds = true
|
||||
labelOriginalCenter = label.center
|
||||
|
||||
NSNotificationCenter.defaultCenter().addObserver(self, selector: "reset", name: UIApplicationWillResignActiveNotification, object: nil)
|
||||
setupNumberFormatter()
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(GMStepper.reset), name: UIApplication.willResignActiveNotification, object: nil)
|
||||
}
|
||||
|
||||
func setupNumberFormatter() {
|
||||
let decValue = Decimal(stepValue)
|
||||
let digits = decValue.significantFractionalDecimalDigits
|
||||
formatter.minimumIntegerDigits = 1
|
||||
formatter.minimumFractionDigits = showIntegerIfDoubleIsInteger ? 0 : digits
|
||||
formatter.maximumFractionDigits = digits
|
||||
}
|
||||
|
||||
public override func layoutSubviews() {
|
||||
|
|
@ -286,28 +337,42 @@ import UIKit
|
|||
value += stepValue
|
||||
} else if stepperState == .ShouldDecrease {
|
||||
value -= stepValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
deinit {
|
||||
resetTimer()
|
||||
NSNotificationCenter.defaultCenter().removeObserver(self)
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
|
||||
/// 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.
|
||||
// lazy var printTimerGaps: () -> () = {
|
||||
// var prevTime: CFAbsoluteTime?
|
||||
//
|
||||
// return { _ in
|
||||
// var now = CFAbsoluteTimeGetCurrent()
|
||||
// if let prevTime = prevTime {
|
||||
// print(now - prevTime)
|
||||
// }
|
||||
// prevTime = now
|
||||
// }
|
||||
// }()
|
||||
}
|
||||
|
||||
// MARK: Pan Gesture
|
||||
extension GMStepper {
|
||||
func handlePan(gesture: UIPanGestureRecognizer) {
|
||||
@objc func handlePan(gesture: UIPanGestureRecognizer) {
|
||||
switch gesture.state {
|
||||
case .Began:
|
||||
leftButton.enabled = false
|
||||
rightButton.enabled = false
|
||||
case .Changed:
|
||||
var translation = gesture.translationInView(label)
|
||||
gesture.setTranslation(CGPointZero, inView: label)
|
||||
case .began:
|
||||
leftButton.isEnabled = false
|
||||
rightButton.isEnabled = false
|
||||
case .changed:
|
||||
let translation = gesture.translation(in: label)
|
||||
gesture.setTranslation(CGPoint.zero, in: label)
|
||||
|
||||
var slidingRight = gesture.velocityInView(label).x > 0
|
||||
var slidingLeft = gesture.velocityInView(label).x < 0
|
||||
let slidingRight = gesture.velocity(in: label).x > 0
|
||||
let slidingLeft = gesture.velocity(in: label).x < 0
|
||||
|
||||
// Move the label with pan
|
||||
if slidingRight {
|
||||
|
|
@ -340,23 +405,27 @@ extension GMStepper {
|
|||
self.rightButton.backgroundColor = self.buttonsBackgroundColor
|
||||
self.leftButton.backgroundColor = self.buttonsBackgroundColor
|
||||
}
|
||||
case .Ended, .Cancelled, .Failed:
|
||||
case .ended, .cancelled, .failed:
|
||||
reset()
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func reset() {
|
||||
@objc func handleLabelTap() {
|
||||
didTouchLabel?(value)
|
||||
}
|
||||
|
||||
@objc func reset() {
|
||||
panState = .Stable
|
||||
stepperState = .Stable
|
||||
resetTimer()
|
||||
|
||||
leftButton.enabled = true
|
||||
rightButton.enabled = true
|
||||
label.userInteractionEnabled = true
|
||||
leftButton.isEnabled = true
|
||||
rightButton.isEnabled = true
|
||||
label.isUserInteractionEnabled = true
|
||||
|
||||
UIView.animateWithDuration(self.labelSlideDuration, animations: {
|
||||
UIView.animate(withDuration: self.labelSlideDuration, animations: {
|
||||
self.label.center = self.labelOriginalCenter
|
||||
self.rightButton.backgroundColor = self.buttonsBackgroundColor
|
||||
self.leftButton.backgroundColor = self.buttonsBackgroundColor
|
||||
|
|
@ -366,23 +435,23 @@ extension GMStepper {
|
|||
|
||||
// MARK: Button Events
|
||||
extension GMStepper {
|
||||
func leftButtonTouchDown(button: UIButton) {
|
||||
rightButton.enabled = false
|
||||
label.userInteractionEnabled = false
|
||||
@objc func leftButtonTouchDown(button: UIButton) {
|
||||
rightButton.isEnabled = false
|
||||
label.isUserInteractionEnabled = false
|
||||
resetTimer()
|
||||
|
||||
if value == minimumValue {
|
||||
animateLimitHitIfNeeded()
|
||||
minimumExceeded?()
|
||||
} else {
|
||||
stepperState = .ShouldDecrease
|
||||
animateSlideLeft()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func rightButtonTouchDown(button: UIButton) {
|
||||
leftButton.enabled = false
|
||||
label.userInteractionEnabled = false
|
||||
@objc func rightButtonTouchDown(button: UIButton) {
|
||||
leftButton.isEnabled = false
|
||||
label.isUserInteractionEnabled = false
|
||||
resetTimer()
|
||||
|
||||
if value == maximumValue {
|
||||
|
|
@ -393,7 +462,7 @@ extension GMStepper {
|
|||
}
|
||||
}
|
||||
|
||||
func buttonTouchUp(button: UIButton) {
|
||||
@objc func buttonTouchUp(button: UIButton) {
|
||||
reset()
|
||||
}
|
||||
}
|
||||
|
|
@ -402,20 +471,20 @@ extension GMStepper {
|
|||
extension GMStepper {
|
||||
|
||||
func animateSlideLeft() {
|
||||
UIView.animateWithDuration(labelSlideDuration) {
|
||||
UIView.animate(withDuration: labelSlideDuration) {
|
||||
self.label.center.x -= self.labelSlideLength
|
||||
}
|
||||
}
|
||||
|
||||
func animateSlideRight() {
|
||||
UIView.animateWithDuration(labelSlideDuration) {
|
||||
UIView.animate(withDuration: labelSlideDuration) {
|
||||
self.label.center.x += self.labelSlideLength
|
||||
}
|
||||
}
|
||||
|
||||
func animateToOriginalPosition() {
|
||||
if self.label.center != self.labelOriginalCenter {
|
||||
UIView.animateWithDuration(labelSlideDuration) {
|
||||
UIView.animate(withDuration: labelSlideDuration) {
|
||||
self.label.center = self.labelOriginalCenter
|
||||
}
|
||||
}
|
||||
|
|
@ -423,14 +492,14 @@ extension GMStepper {
|
|||
|
||||
func animateLimitHitIfNeeded() {
|
||||
if value == minimumValue {
|
||||
animateLimitHitForButton(leftButton)
|
||||
animateLimitHitForButton(button: leftButton)
|
||||
} else if value == maximumValue {
|
||||
animateLimitHitForButton(rightButton)
|
||||
animateLimitHitForButton(button: rightButton)
|
||||
}
|
||||
}
|
||||
|
||||
func animateLimitHitForButton(button: UIButton){
|
||||
UIView.animateWithDuration(limitHitAnimationDuration) {
|
||||
UIView.animate(withDuration: limitHitAnimationDuration) {
|
||||
button.backgroundColor = self.limitHitAnimationColor
|
||||
}
|
||||
}
|
||||
|
|
@ -438,7 +507,7 @@ extension GMStepper {
|
|||
|
||||
// MARK: Timer
|
||||
extension GMStepper {
|
||||
func handleTimerFire(timer: NSTimer) {
|
||||
@objc func handleTimerFire(timer: Timer) {
|
||||
timerFireCount += 1
|
||||
|
||||
if timerFireCount % timerFireCountModulo == 0 {
|
||||
|
|
@ -447,7 +516,7 @@ extension GMStepper {
|
|||
}
|
||||
|
||||
func scheduleTimer() {
|
||||
timer = NSTimer.scheduledTimerWithTimeInterval(timerInterval, target: self, selector: "handleTimerFire:", userInfo: nil, repeats: true)
|
||||
timer = Timer.scheduledTimer(timeInterval: timerInterval, target: self, selector: #selector(GMStepper.handleTimerFire), userInfo: nil, repeats: true)
|
||||
}
|
||||
|
||||
func resetTimer() {
|
||||
|
|
@ -457,6 +526,19 @@ extension GMStepper {
|
|||
timerFireCount = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension GMStepper {
|
||||
|
||||
}
|
||||
func handleIsLimitReached() {
|
||||
let isLimitReached = value == minimumValue
|
||||
leftButton.alpha = isLimitReached ? leftButtonLimitOpacity : 1
|
||||
}
|
||||
}
|
||||
|
||||
extension Decimal {
|
||||
|
||||
var significantFractionalDecimalDigits: Int {
|
||||
return max(-exponent, 0)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,18 +7,18 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
3169DD3E1B496C33009791D1 /* GMStepper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 319C195B1B48445E005EFEE5 /* GMStepper.swift */; };
|
||||
3116C0DB1DA4DD360015AC69 /* GMStepperExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3116C0DA1DA4DD360015AC69 /* GMStepperExampleTests.swift */; };
|
||||
3198AC771DA4DEE500311FB3 /* GMStepper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 319C195B1B48445E005EFEE5 /* GMStepper.swift */; };
|
||||
319C19381B4843EB005EFEE5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 319C19371B4843EB005EFEE5 /* AppDelegate.swift */; };
|
||||
319C193A1B4843EB005EFEE5 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 319C19391B4843EB005EFEE5 /* ViewController.swift */; };
|
||||
319C193D1B4843EB005EFEE5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 319C193B1B4843EB005EFEE5 /* Main.storyboard */; };
|
||||
319C193F1B4843EB005EFEE5 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 319C193E1B4843EB005EFEE5 /* Images.xcassets */; };
|
||||
319C19421B4843EB005EFEE5 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 319C19401B4843EB005EFEE5 /* LaunchScreen.xib */; };
|
||||
319C194E1B4843EB005EFEE5 /* GMStepperExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 319C194D1B4843EB005EFEE5 /* GMStepperExampleTests.swift */; };
|
||||
319C195C1B48445E005EFEE5 /* GMStepper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 319C195B1B48445E005EFEE5 /* GMStepper.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
319C19481B4843EB005EFEE5 /* PBXContainerItemProxy */ = {
|
||||
3116C0DD1DA4DD360015AC69 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 319C192A1B4843EB005EFEE5 /* Project object */;
|
||||
proxyType = 1;
|
||||
|
|
@ -28,6 +28,9 @@
|
|||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
3116C0D81DA4DD360015AC69 /* GMStepperExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GMStepperExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
3116C0DA1DA4DD360015AC69 /* GMStepperExampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GMStepperExampleTests.swift; sourceTree = "<group>"; };
|
||||
3116C0DC1DA4DD360015AC69 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
319C19321B4843EB005EFEE5 /* GMStepperExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GMStepperExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
319C19361B4843EB005EFEE5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
319C19371B4843EB005EFEE5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -35,21 +38,18 @@
|
|||
319C193C1B4843EB005EFEE5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
319C193E1B4843EB005EFEE5 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
319C19411B4843EB005EFEE5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
|
||||
319C19471B4843EB005EFEE5 /* GMStepperExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GMStepperExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
319C194C1B4843EB005EFEE5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
319C194D1B4843EB005EFEE5 /* GMStepperExampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GMStepperExampleTests.swift; sourceTree = "<group>"; };
|
||||
319C195B1B48445E005EFEE5 /* GMStepper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GMStepper.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
319C192F1B4843EB005EFEE5 /* Frameworks */ = {
|
||||
3116C0D51DA4DD360015AC69 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
319C19441B4843EB005EFEE5 /* Frameworks */ = {
|
||||
319C192F1B4843EB005EFEE5 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
|
|
@ -59,12 +59,21 @@
|
|||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
3116C0D91DA4DD360015AC69 /* GMStepperExampleTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3116C0DA1DA4DD360015AC69 /* GMStepperExampleTests.swift */,
|
||||
3116C0DC1DA4DD360015AC69 /* Info.plist */,
|
||||
);
|
||||
path = GMStepperExampleTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
319C19291B4843EB005EFEE5 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
319C195A1B48445E005EFEE5 /* GMStepper */,
|
||||
319C19341B4843EB005EFEE5 /* GMStepperExample */,
|
||||
319C194A1B4843EB005EFEE5 /* GMStepperExampleTests */,
|
||||
3116C0D91DA4DD360015AC69 /* GMStepperExampleTests */,
|
||||
319C19331B4843EB005EFEE5 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -73,7 +82,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
319C19321B4843EB005EFEE5 /* GMStepperExample.app */,
|
||||
319C19471B4843EB005EFEE5 /* GMStepperExampleTests.xctest */,
|
||||
3116C0D81DA4DD360015AC69 /* GMStepperExampleTests.xctest */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -99,23 +108,6 @@
|
|||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
319C194A1B4843EB005EFEE5 /* GMStepperExampleTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
319C194D1B4843EB005EFEE5 /* GMStepperExampleTests.swift */,
|
||||
319C194B1B4843EB005EFEE5 /* Supporting Files */,
|
||||
);
|
||||
path = GMStepperExampleTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
319C194B1B4843EB005EFEE5 /* Supporting Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
319C194C1B4843EB005EFEE5 /* Info.plist */,
|
||||
);
|
||||
name = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
319C195A1B48445E005EFEE5 /* GMStepper */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -128,6 +120,24 @@
|
|||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
3116C0D71DA4DD360015AC69 /* GMStepperExampleTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 3116C0DF1DA4DD360015AC69 /* Build configuration list for PBXNativeTarget "GMStepperExampleTests" */;
|
||||
buildPhases = (
|
||||
3116C0D41DA4DD360015AC69 /* Sources */,
|
||||
3116C0D51DA4DD360015AC69 /* Frameworks */,
|
||||
3116C0D61DA4DD360015AC69 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
3116C0DE1DA4DD360015AC69 /* PBXTargetDependency */,
|
||||
);
|
||||
name = GMStepperExampleTests;
|
||||
productName = GMStepperExampleTests;
|
||||
productReference = 3116C0D81DA4DD360015AC69 /* GMStepperExampleTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
319C19311B4843EB005EFEE5 /* GMStepperExample */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 319C19511B4843EB005EFEE5 /* Build configuration list for PBXNativeTarget "GMStepperExample" */;
|
||||
|
|
@ -145,40 +155,27 @@
|
|||
productReference = 319C19321B4843EB005EFEE5 /* GMStepperExample.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
319C19461B4843EB005EFEE5 /* GMStepperExampleTests */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 319C19541B4843EB005EFEE5 /* Build configuration list for PBXNativeTarget "GMStepperExampleTests" */;
|
||||
buildPhases = (
|
||||
319C19431B4843EB005EFEE5 /* Sources */,
|
||||
319C19441B4843EB005EFEE5 /* Frameworks */,
|
||||
319C19451B4843EB005EFEE5 /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
319C19491B4843EB005EFEE5 /* PBXTargetDependency */,
|
||||
);
|
||||
name = GMStepperExampleTests;
|
||||
productName = GMStepperExampleTests;
|
||||
productReference = 319C19471B4843EB005EFEE5 /* GMStepperExampleTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
319C192A1B4843EB005EFEE5 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0700;
|
||||
LastUpgradeCheck = 0640;
|
||||
LastSwiftMigration = 0700;
|
||||
LastSwiftUpdateCheck = 0800;
|
||||
LastUpgradeCheck = 0900;
|
||||
ORGANIZATIONNAME = "Gunay Mert Karadogan";
|
||||
TargetAttributes = {
|
||||
3116C0D71DA4DD360015AC69 = {
|
||||
CreatedOnToolsVersion = 8.0;
|
||||
LastSwiftMigration = 1000;
|
||||
ProvisioningStyle = Automatic;
|
||||
TestTargetID = 319C19311B4843EB005EFEE5;
|
||||
};
|
||||
319C19311B4843EB005EFEE5 = {
|
||||
CreatedOnToolsVersion = 6.4;
|
||||
};
|
||||
319C19461B4843EB005EFEE5 = {
|
||||
CreatedOnToolsVersion = 6.4;
|
||||
TestTargetID = 319C19311B4843EB005EFEE5;
|
||||
DevelopmentTeam = 289M6XEDV4;
|
||||
LastSwiftMigration = 1000;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -196,12 +193,19 @@
|
|||
projectRoot = "";
|
||||
targets = (
|
||||
319C19311B4843EB005EFEE5 /* GMStepperExample */,
|
||||
319C19461B4843EB005EFEE5 /* GMStepperExampleTests */,
|
||||
3116C0D71DA4DD360015AC69 /* GMStepperExampleTests */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
3116C0D61DA4DD360015AC69 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
319C19301B4843EB005EFEE5 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
|
@ -212,16 +216,18 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
319C19451B4843EB005EFEE5 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
3116C0D41DA4DD360015AC69 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3116C0DB1DA4DD360015AC69 /* GMStepperExampleTests.swift in Sources */,
|
||||
3198AC771DA4DEE500311FB3 /* GMStepper.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
319C192E1B4843EB005EFEE5 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
|
@ -232,22 +238,13 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
319C19431B4843EB005EFEE5 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
319C194E1B4843EB005EFEE5 /* GMStepperExampleTests.swift in Sources */,
|
||||
3169DD3E1B496C33009791D1 /* GMStepper.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
319C19491B4843EB005EFEE5 /* PBXTargetDependency */ = {
|
||||
3116C0DE1DA4DD360015AC69 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 319C19311B4843EB005EFEE5 /* GMStepperExample */;
|
||||
targetProxy = 319C19481B4843EB005EFEE5 /* PBXContainerItemProxy */;
|
||||
targetProxy = 3116C0DD1DA4DD360015AC69 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
|
|
@ -271,6 +268,42 @@
|
|||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
3116C0E01DA4DD360015AC69 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVES = YES;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
INFOPLIST_FILE = GMStepperExampleTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.gmertk.GMStepperExampleTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_VERSION = 4.2;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GMStepperExample.app/GMStepperExample";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
3116C0E11DA4DD360015AC69 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVES = YES;
|
||||
INFOPLIST_FILE = GMStepperExampleTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.gmertk.GMStepperExampleTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 4.2;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GMStepperExample.app/GMStepperExample";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
319C194F1B4843EB005EFEE5 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
|
|
@ -279,19 +312,28 @@
|
|||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
|
|
@ -323,13 +365,21 @@
|
|||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
|
|
@ -348,6 +398,7 @@
|
|||
IPHONEOS_DEPLOYMENT_TARGET = 8.4;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
|
|
@ -356,9 +407,13 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
DEVELOPMENT_TEAM = 289M6XEDV4;
|
||||
INFOPLIST_FILE = GMStepperExample/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.gunaymert.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 4.2;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
|
|
@ -366,49 +421,28 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
DEVELOPMENT_TEAM = 289M6XEDV4;
|
||||
INFOPLIST_FILE = GMStepperExample/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "com.gunaymert.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
319C19551B4843EB005EFEE5 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = GMStepperExampleTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GMStepperExample.app/GMStepperExample";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
319C19561B4843EB005EFEE5 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
);
|
||||
INFOPLIST_FILE = GMStepperExampleTests/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GMStepperExample.app/GMStepperExample";
|
||||
SWIFT_VERSION = 4.2;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
3116C0DF1DA4DD360015AC69 /* Build configuration list for PBXNativeTarget "GMStepperExampleTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
3116C0E01DA4DD360015AC69 /* Debug */,
|
||||
3116C0E11DA4DD360015AC69 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
319C192D1B4843EB005EFEE5 /* Build configuration list for PBXProject "GMStepperExample" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
|
@ -427,15 +461,6 @@
|
|||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
319C19541B4843EB005EFEE5 /* Build configuration list for PBXNativeTarget "GMStepperExampleTests" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
319C19551B4843EB005EFEE5 /* Debug */,
|
||||
319C19561B4843EB005EFEE5 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 319C192A1B4843EB005EFEE5 /* Project object */;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
@ -14,33 +14,33 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
var window: UIWindow?
|
||||
|
||||
|
||||
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
// Override point for customization after application launch.
|
||||
return true
|
||||
}
|
||||
|
||||
func applicationWillResignActive(application: UIApplication) {
|
||||
func applicationWillResignActive(_ application: UIApplication) {
|
||||
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
|
||||
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
|
||||
}
|
||||
|
||||
func applicationDidEnterBackground(application: UIApplication) {
|
||||
func applicationDidEnterBackground(_ application: UIApplication) {
|
||||
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||
}
|
||||
|
||||
func applicationWillEnterForeground(application: UIApplication) {
|
||||
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
|
||||
func applicationWillEnterForeground(_ application: UIApplication) {
|
||||
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
|
||||
}
|
||||
|
||||
func applicationDidBecomeActive(application: UIApplication) {
|
||||
func applicationDidBecomeActive(_ application: UIApplication) {
|
||||
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||
}
|
||||
|
||||
func applicationWillTerminate(application: UIApplication) {
|
||||
func applicationWillTerminate(_ application: UIApplication) {
|
||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6214" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="8191" systemVersion="15A279b" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6207"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
|
|
@ -13,17 +14,20 @@
|
|||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 Gunay Mert Karadogan. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
|
||||
<rect key="frame" x="20" y="439" width="441" height="21"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="GMStepperExample" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
|
||||
<rect key="frame" x="20" y="140" width="441" height="43"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7706" systemVersion="14E46" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="vXZ-lx-hvc">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11201" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="vXZ-lx-hvc">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
|
|
@ -14,12 +16,11 @@
|
|||
<viewControllerLayoutGuide type="bottom" id="2fi-mo-0CV"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="kh9-bI-dsS">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="AU6-4C-B2F" customClass="GMStepper" customModule="GMStepperExample" customModuleProvider="target">
|
||||
<rect key="frame" x="24" y="28" width="552" height="44"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="6mC-hP-wFD"/>
|
||||
</constraints>
|
||||
|
|
@ -33,77 +34,74 @@
|
|||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="if7-U5-bAM" customClass="GMStepper" customModule="GMStepperExample" customModuleProvider="target">
|
||||
<rect key="frame" x="140" y="116" width="320" height="66"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="66" id="iQi-6P-vt9"/>
|
||||
<constraint firstAttribute="width" constant="320" id="ji4-Pf-1fZ"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="buttonsBackgroundColor">
|
||||
<color key="value" red="1" green="0.3591497541" blue="0.36842127060000002" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="value" red="1" green="0.3591497541" blue="0.36842127060000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="labelTextColor">
|
||||
<color key="value" red="1" green="0.3591497541" blue="0.36842127060000002" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="value" red="1" green="0.3591497541" blue="0.36842127060000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="labelBackgroundColor">
|
||||
<color key="value" red="0.90823972230000005" green="0.92638683320000004" blue="0.93171715740000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="value" red="0.90823972230000005" green="0.92638683320000004" blue="0.93171715740000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="buttonsTextColor">
|
||||
<color key="value" red="0.90823972230000005" green="0.92638683320000004" blue="0.93171715740000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="value" red="0.90823972230000005" green="0.92638683320000004" blue="0.93171715740000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="limitHitAnimationColor">
|
||||
<color key="value" red="0.90823972230000005" green="0.92638683320000004" blue="0.93171715740000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="value" red="0.90823972230000005" green="0.92638683320000004" blue="0.93171715740000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="stepValue">
|
||||
<real key="value" value="0.69999999999999996"/>
|
||||
<real key="value" value="0.1"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="R9n-I0-fq7" customClass="GMStepper" customModule="GMStepperExample" customModuleProvider="target">
|
||||
<rect key="frame" x="200" y="226" width="200" height="66"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="200" id="dVu-w0-mf0"/>
|
||||
<constraint firstAttribute="height" constant="66" id="ie8-vl-NAV"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="buttonsBackgroundColor">
|
||||
<color key="value" red="0.1819814891" green="0.69426733259999995" blue="0.53024792669999998" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="value" red="0.1819814891" green="0.69426733259999995" blue="0.53024792669999998" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="labelTextColor">
|
||||
<color key="value" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="value" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="labelBackgroundColor">
|
||||
<color key="value" red="0.6588235294" green="0.85882352939999995" blue="0.6588235294" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="value" red="0.6588235294" green="0.85882352939999995" blue="0.6588235294" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="buttonsTextColor">
|
||||
<color key="value" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="value" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="limitHitAnimationColor">
|
||||
<color key="value" red="0.6588235294" green="0.85882352939999995" blue="0.6588235294" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="value" red="0.6588235294" green="0.85882352939999995" blue="0.6588235294" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="U8X-8Z-7Mo" customClass="GMStepper" customModule="GMStepperExample" customModuleProvider="target">
|
||||
<rect key="frame" x="24" y="336" width="552" height="44"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="aF3-T7-dIP"/>
|
||||
<constraint firstAttribute="width" constant="200" id="vhP-7K-vOu"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="buttonsBackgroundColor">
|
||||
<color key="value" red="0.90823972230000005" green="0.92638683320000004" blue="0.93171715740000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="value" red="0.90823972230000005" green="0.92638683320000004" blue="0.93171715740000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="labelTextColor">
|
||||
<color key="value" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="value" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="labelBackgroundColor">
|
||||
<color key="value" red="0.98624199629999998" green="0.77968657019999998" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="value" red="0.98624199629999998" green="0.77968657019999998" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="buttonsTextColor">
|
||||
<color key="value" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="value" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="labelWidthWeight">
|
||||
<real key="value" value="0.69999999999999996"/>
|
||||
|
|
@ -114,7 +112,7 @@
|
|||
<integer key="value" value="0"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="limitHitAnimationColor">
|
||||
<color key="value" red="0.98624199629999998" green="0.77968657019999998" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="value" red="0.98624199629999998" green="0.77968657019999998" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="maximumValue">
|
||||
<integer key="value" value="100"/>
|
||||
|
|
@ -126,8 +124,44 @@
|
|||
</mask>
|
||||
</variation>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9Ri-Yr-sRs" customClass="GMStepper" customModule="GMStepperExample" customModuleProvider="target">
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="180" id="dhO-Nd-SFk"/>
|
||||
<constraint firstAttribute="height" constant="50" id="xPS-vU-cZc"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="maximumValue">
|
||||
<real key="value" value="10"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="stepValue">
|
||||
<real key="value" value="1"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
|
||||
<real key="value" value="2"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
|
||||
<real key="value" value="4"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="buttonsBackgroundColor">
|
||||
<color key="value" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="buttonsTextColor">
|
||||
<color key="value" red="1" green="0.47058823529999999" blue="0.15686274510000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="borderColor">
|
||||
<color key="value" red="1" green="0.47058823529999999" blue="0.15686274510000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="labelBackgroundColor">
|
||||
<color key="value" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="color" keyPath="labelTextColor">
|
||||
<color key="value" red="1" green="0.47058823529999999" blue="0.15686274510000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="R9n-I0-fq7" firstAttribute="centerX" secondItem="U8X-8Z-7Mo" secondAttribute="centerX" id="3cD-WW-Qg4"/>
|
||||
<constraint firstItem="if7-U5-bAM" firstAttribute="top" secondItem="AU6-4C-B2F" secondAttribute="bottom" constant="44" id="662-W9-CUn"/>
|
||||
|
|
@ -137,7 +171,9 @@
|
|||
<constraint firstItem="if7-U5-bAM" firstAttribute="centerX" secondItem="R9n-I0-fq7" secondAttribute="centerX" id="K7g-rC-ehJ"/>
|
||||
<constraint firstItem="U8X-8Z-7Mo" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leadingMargin" constant="8" id="S1b-pD-UXA"/>
|
||||
<constraint firstItem="U8X-8Z-7Mo" firstAttribute="top" secondItem="R9n-I0-fq7" secondAttribute="bottom" constant="44" id="fBW-Xx-pa0"/>
|
||||
<constraint firstItem="9Ri-Yr-sRs" firstAttribute="centerX" secondItem="kh9-bI-dsS" secondAttribute="centerX" id="fay-qT-jKR"/>
|
||||
<constraint firstItem="AU6-4C-B2F" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leadingMargin" constant="8" id="iIM-b2-jzV"/>
|
||||
<constraint firstItem="9Ri-Yr-sRs" firstAttribute="top" secondItem="U8X-8Z-7Mo" secondAttribute="bottom" constant="44" id="nKi-Fp-8B7"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="U8X-8Z-7Mo" secondAttribute="trailing" constant="8" id="ppd-nb-fL8"/>
|
||||
<constraint firstItem="AU6-4C-B2F" firstAttribute="top" secondItem="jyV-Pf-zRb" secondAttribute="bottom" constant="8" symbolic="YES" id="zDK-gF-kms"/>
|
||||
</constraints>
|
||||
|
|
@ -148,6 +184,7 @@
|
|||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="x5A-6p-PRh" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="274" y="363"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.gunaymert.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ class ViewController: UIViewController {
|
|||
@IBOutlet weak var stepper: GMStepper!
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
stepper.addTarget(self, action: "stepperValueChanged:", forControlEvents: .ValueChanged)
|
||||
stepper.addTarget(self, action: #selector(ViewController.stepperValueChanged), for: .valueChanged)
|
||||
}
|
||||
|
||||
func stepperValueChanged(stepper: GMStepper) {
|
||||
println(stepper.value)
|
||||
@objc func stepperValueChanged(stepper: GMStepper) {
|
||||
print(stepper.value, terminator: "")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
// Copyright (c) 2015 Gunay Mert Karadogan. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import XCTest
|
||||
import UIKit
|
||||
|
||||
class GMStepperExampleTests: XCTestCase {
|
||||
var stepper: GMStepper!
|
||||
|
|
@ -19,7 +19,7 @@ class GMStepperExampleTests: XCTestCase {
|
|||
|
||||
func testDefaults() {
|
||||
XCTAssert(stepper.minimumValue == 0, "minimumValue defaults 0")
|
||||
XCTAssert(stepper.maximumValue == 10, "maximumValue defaults to 10")
|
||||
XCTAssert(stepper.maximumValue == 100, "maximumValue defaults to 100")
|
||||
XCTAssert(stepper.value == 0, "value defaults to 0")
|
||||
}
|
||||
|
||||
|
|
@ -37,6 +37,6 @@ class GMStepperExampleTests: XCTestCase {
|
|||
|
||||
XCTAssert(stepper.value == stepper.maximumValue, "Pass")
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.gunaymert.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
|
|
@ -16,8 +16,6 @@
|
|||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
|
|
|
|||
23
README.md
23
README.md
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
A stepper with a sliding label in the middle. Pan the label or tap the buttons. Check out the tutorial, [How to Build a Custom Stepper - Part 1](http://gmertk.github.io/custom-stepper-part-1/).
|
||||
|
||||
|
||||
## Screenshot
|
||||
|
||||

|
||||
|
|
@ -19,7 +20,7 @@ it, simply add the following lines to your Podfile:
|
|||
use_frameworks!
|
||||
pod "GMStepper"
|
||||
```
|
||||
|
||||
|
||||
## Setup
|
||||
|
||||
If you want to use storyboards, just drop a UIView into your storyboard and set its class to `GMStepper`. Then customize through the attributes inspector. Otherwise, you can write the code to initialize with frame and set the properties.
|
||||
|
|
@ -27,7 +28,7 @@ If you want to use storyboards, just drop a UIView into your storyboard and set
|
|||
## Properties
|
||||
```swift
|
||||
/// Current value of the stepper. Defaults to 0.
|
||||
var value: Double = 0
|
||||
var value: Double = 0
|
||||
|
||||
/// Minimum value. Must be less than maximumValue. Defaults to 0.
|
||||
var minimumValue: Double = 0
|
||||
|
|
@ -43,7 +44,7 @@ var autorepeat: Bool = true
|
|||
|
||||
/// If the value is integer, it is shown without floating point.
|
||||
var showIntegerIfDoubleIsInteger: Bool = true
|
||||
|
||||
|
||||
/// Text on the left button. Be sure that it fits in the button. Defaults to "-".
|
||||
var leftButtonText: String = "-"
|
||||
|
||||
|
|
@ -68,20 +69,30 @@ var labelBackgroundColor: UIColor = UIColor(red:0.26, green:0.6, blue:0.87, alph
|
|||
/// Font of the middle label. Defaults to AvenirNext-Bold, 25.0 points in size.
|
||||
var labelFont = UIFont(name: "AvenirNext-Bold", size: 25.0)
|
||||
|
||||
/// Corner radius of the middle label's layer. Defaults to 0.0.
|
||||
var labelCornerRadius: CGFloat = 0.0
|
||||
|
||||
/// Corner radius of the stepper's layer. Defaults to 4.0.
|
||||
var cornerRadius: CGFloat = 4.0
|
||||
|
||||
/// Border width of the stepper and middle label's layer. Defaults to 0.0.
|
||||
var borderWidth: CGFloat = 0.0
|
||||
|
||||
/// Color of the border of the stepper and middle label's layer. Defaults to clear color.
|
||||
var borderColor: UIColor = UIColor.clearColor()
|
||||
|
||||
/// Percentage of the middle label's width. Must be between 0 and 1. Defaults to 0.5. Be sure that it is wide enough to show the value.
|
||||
var labelWidthWeight: CGFloat = 0.5
|
||||
var labelWidthWeight: CGFloat = 0.5
|
||||
|
||||
/// Color of the flashing animation on the buttons in case the value hit the limit.
|
||||
var limitHitAnimationColor: UIColor = UIColor(red:0.26, green:0.6, blue:0.87, alpha:1)
|
||||
```
|
||||
|
||||
|
||||
## Author
|
||||
## Authors
|
||||
|
||||
Günay Mert Karadoğan, mertkaradogan@gmail.com
|
||||
* [Brent Whitman](https://github.com/bwhtmn) - Maintainer
|
||||
* [Günay Mert Karadoğan](https://github.com/gmertk) - Creator
|
||||
|
||||
## License
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue