├── .gitignore ├── Assets ├── Screenshot1.png └── example1.gif ├── CHANGELOG.md ├── Classes ├── Info.plist ├── SAStepper.h ├── SAStepperControl+Image.h ├── SAStepperControl+Image.m ├── SAStepperControl.h └── SAStepperControl.m ├── Example └── SAStepperControlDemo │ ├── SAStepperControl.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── SAStepperControl │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Launch Screen.storyboard │ ├── SAAppDelegate.h │ ├── SAAppDelegate.m │ ├── SAStepperControl-Info.plist │ ├── SAStepperControl-Prefix.pch │ ├── SAViewController.h │ ├── SAViewController.m │ ├── en.lproj │ │ └── InfoPlist.strings │ └── main.m │ └── SAStepperControlUITests │ ├── Info.plist │ └── SAStepperControlUITests.swift ├── LICENSE ├── README.md ├── Rakefile └── SAStepperControl.podspec /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | */build/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | profile 14 | *.moved-aside 15 | DerivedData 16 | .idea/ 17 | *.hmap 18 | *.xccheckout 19 | 20 | #CocoaPods 21 | Pods 22 | Example/SAStepperControlDemo/Build -------------------------------------------------------------------------------- /Assets/Screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shams-ahmed/SAStepperControl/770ac913a40bb57071b2f8f9fdc2d671ea91c1fb/Assets/Screenshot1.png -------------------------------------------------------------------------------- /Assets/example1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shams-ahmed/SAStepperControl/770ac913a40bb57071b2f8f9fdc2d671ea91c1fb/Assets/example1.gif -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # SAStepperControl CHANGELOG 2 | 3 | ## 0.1.0 4 | 5 | Initial release. 6 | -------------------------------------------------------------------------------- /Classes/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | -------------------------------------------------------------------------------- /Classes/SAStepper.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAStepper.h 3 | // SAStepperControl 4 | // 5 | // Created by shams ahmed on 21/08/2016. 6 | // Copyright © 2016 SA. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for SAStepper. 12 | FOUNDATION_EXPORT double SAStepperVersionNumber; 13 | 14 | //! Project version string for Masonry. 15 | FOUNDATION_EXPORT const unsigned char SAStepperVersionString[]; 16 | 17 | #import "SAStepperControl.h" 18 | -------------------------------------------------------------------------------- /Classes/SAStepperControl+Image.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAStepperControl_SAStepperControl_Image.h 3 | // SAStepperControl 4 | // 5 | // Created by shams ahmed on 20/08/2016. 6 | // Copyright © 2016 SA. All rights reserved. 7 | // 8 | 9 | #import "SAStepperControl.h" 10 | 11 | @interface SAStepperControl (Image) 12 | 13 | /// Create image froma view 14 | /// 15 | /// @param view UIView to create image 16 | /// 17 | /// @return Image of view 18 | - (UIImage * __nonnull)imageFromView:(UIView * __nonnull)view; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Classes/SAStepperControl+Image.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAStepperControl_Image.m 3 | // SAStepperControl 4 | // 5 | // Created by shams ahmed on 20/08/2016. 6 | // Copyright © 2016 SA. All rights reserved. 7 | // 8 | 9 | #import "SAStepperControl+Image.h" 10 | 11 | @implementation SAStepperControl (Image) 12 | 13 | #pragma mark - 14 | #pragma mark - UIImage 15 | 16 | - (UIImage * __nonnull)imageFromView:(UIView * __nonnull)view { 17 | UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, 0.0); 18 | 19 | [view.layer renderInContext:UIGraphicsGetCurrentContext()]; 20 | UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext(); 21 | 22 | UIGraphicsEndImageContext(); 23 | 24 | return viewImage; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Classes/SAStepperControl.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAStepperControl.h 3 | // SAStepperControl 4 | // 5 | // Created by Shams on 06/05/2014. 6 | // Copyright (c) 2014 SA. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface SAStepperControl : UIStepper 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Classes/SAStepperControl.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAStepperControl.m 3 | // SAStepperControl 4 | // 5 | // Created by Shams on 06/05/2014. 6 | // Copyright (c) 2014 SA. All rights reserved. 7 | // 8 | 9 | #import "SAStepperControl.h" 10 | #import "SAStepperControl+Image.h" 11 | 12 | @interface SAStepperControl () 13 | 14 | @property (nonatomic, strong) UILabel * __nonnull label; 15 | 16 | @end 17 | 18 | @implementation SAStepperControl 19 | 20 | #pragma mark - 21 | #pragma mark - Init 22 | 23 | - (__nonnull instancetype)initWithFrame:(CGRect)frame { 24 | self = [super initWithFrame:frame]; 25 | 26 | if (self) { 27 | [self setupLabel]; 28 | } 29 | 30 | return self; 31 | } 32 | 33 | - (void)awakeFromNib { 34 | [super awakeFromNib]; 35 | 36 | [self setupLabel]; 37 | } 38 | 39 | #pragma mark - 40 | #pragma mark - Layout 41 | 42 | - (void)layoutSubviews { 43 | [super layoutSubviews]; 44 | 45 | self.label.frame = CGRectMake(0, 46 | 0, 47 | 30, 48 | CGRectGetHeight(self.frame)); 49 | } 50 | 51 | #pragma mark - 52 | #pragma mark - Setup 53 | 54 | - (void)setupLabel { 55 | self.label = [[UILabel alloc] initWithFrame:CGRectMake(0, 56 | 0, 57 | 30, 58 | CGRectGetHeight(self.frame))]; 59 | 60 | self.label.textAlignment = NSTextAlignmentCenter; 61 | self.label.textColor = self.tintColor; 62 | self.label.adjustsFontSizeToFitWidth = YES; 63 | 64 | [self setDividerImage:[self imageFromView:self.label] 65 | forLeftSegmentState:UIControlStateNormal 66 | rightSegmentState:UIControlStateNormal]; 67 | } 68 | 69 | #pragma mark - 70 | #pragma mark - Tint Color 71 | 72 | - (void)tintColorDidChange { 73 | [super tintColorDidChange]; 74 | self.label.textColor = self.tintColor; 75 | 76 | [self setDividerImage:[self imageFromView:self.label] 77 | forLeftSegmentState:UIControlStateNormal 78 | rightSegmentState:UIControlStateNormal]; 79 | } 80 | 81 | #pragma mark - 82 | #pragma mark - Override 83 | 84 | - (UIImage *)dividerImageForLeftSegmentState:(UIControlState)leftState rightSegmentState:(UIControlState)rightState { 85 | return [self dividerImage]; 86 | } 87 | 88 | #pragma mark - 89 | #pragma mark - Private 90 | 91 | - (UIImage * __nonnull)dividerImage { 92 | if (self.value == 0) { 93 | UIView *dividerContainer = [[UIView alloc] initWithFrame:CGRectMake(14, 94 | 0, 95 | 2, 96 | 29)]; 97 | 98 | dividerContainer.alpha = 0.5; 99 | dividerContainer.backgroundColor = self.tintColor; 100 | 101 | for (UIView *view in self.label.subviews) { 102 | [view removeFromSuperview]; 103 | 104 | } 105 | 106 | self.label.text = nil; 107 | [self.label addSubview:dividerContainer]; 108 | 109 | return [self imageFromView:self.label]; 110 | } 111 | 112 | for (UIView *view in self.label.subviews) { 113 | [view removeFromSuperview]; 114 | } 115 | 116 | self.label.text = @(self.value).stringValue; 117 | 118 | return [self imageFromView:self.label]; 119 | } 120 | 121 | @end 122 | -------------------------------------------------------------------------------- /Example/SAStepperControlDemo/SAStepperControl.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 10AA36191D690A1A002BA782 /* SAStepperControl+Image.m in Sources */ = {isa = PBXBuildFile; fileRef = 10AA36181D690A1A002BA782 /* SAStepperControl+Image.m */; }; 11 | 10AA361C1D691B2C002BA782 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 10AA361B1D691B2C002BA782 /* Info.plist */; }; 12 | 10AA36251D691C66002BA782 /* SAStepperControlUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10AA36241D691C66002BA782 /* SAStepperControlUITests.swift */; }; 13 | 10AA362D1D691E97002BA782 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 10AA362C1D691E97002BA782 /* Launch Screen.storyboard */; }; 14 | D55C39A019193FEE0090B6B4 /* SAStepperControl.m in Sources */ = {isa = PBXBuildFile; fileRef = D55C399F19193FEE0090B6B4 /* SAStepperControl.m */; }; 15 | D58C751B1918F8550019067C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D58C751A1918F8550019067C /* Foundation.framework */; }; 16 | D58C751D1918F8550019067C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D58C751C1918F8550019067C /* CoreGraphics.framework */; }; 17 | D58C751F1918F8550019067C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D58C751E1918F8550019067C /* UIKit.framework */; }; 18 | D58C75251918F8550019067C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D58C75231918F8550019067C /* InfoPlist.strings */; }; 19 | D58C75271918F8550019067C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D58C75261918F8550019067C /* main.m */; }; 20 | D58C752B1918F8550019067C /* SAAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D58C752A1918F8550019067C /* SAAppDelegate.m */; }; 21 | D58C75341918F8550019067C /* SAViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D58C75331918F8550019067C /* SAViewController.m */; }; 22 | D58C75361918F8550019067C /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D58C75351918F8550019067C /* Images.xcassets */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXContainerItemProxy section */ 26 | 10AA36271D691C66002BA782 /* PBXContainerItemProxy */ = { 27 | isa = PBXContainerItemProxy; 28 | containerPortal = D58C750F1918F8550019067C /* Project object */; 29 | proxyType = 1; 30 | remoteGlobalIDString = D58C75161918F8550019067C; 31 | remoteInfo = SAStepperControl; 32 | }; 33 | /* End PBXContainerItemProxy section */ 34 | 35 | /* Begin PBXFileReference section */ 36 | 10AA36171D6909D5002BA782 /* SAStepperControl+Image.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SAStepperControl+Image.h"; sourceTree = ""; }; 37 | 10AA36181D690A1A002BA782 /* SAStepperControl+Image.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SAStepperControl+Image.m"; sourceTree = ""; }; 38 | 10AA361B1D691B2C002BA782 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 39 | 10AA361D1D691BF4002BA782 /* SAStepper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAStepper.h; sourceTree = ""; }; 40 | 10AA36221D691C66002BA782 /* SAStepperControlUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SAStepperControlUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 10AA36241D691C66002BA782 /* SAStepperControlUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SAStepperControlUITests.swift; sourceTree = ""; }; 42 | 10AA36261D691C66002BA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 43 | 10AA362C1D691E97002BA782 /* Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = ""; }; 44 | D55C399E19193FEE0090B6B4 /* SAStepperControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAStepperControl.h; sourceTree = ""; }; 45 | D55C399F19193FEE0090B6B4 /* SAStepperControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SAStepperControl.m; sourceTree = ""; }; 46 | D58C75171918F8550019067C /* SAStepperControl.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SAStepperControl.app; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | D58C751A1918F8550019067C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 48 | D58C751C1918F8550019067C /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 49 | D58C751E1918F8550019067C /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 50 | D58C75221918F8550019067C /* SAStepperControl-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SAStepperControl-Info.plist"; sourceTree = ""; }; 51 | D58C75241918F8550019067C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 52 | D58C75261918F8550019067C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 53 | D58C75281918F8550019067C /* SAStepperControl-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SAStepperControl-Prefix.pch"; sourceTree = ""; }; 54 | D58C75291918F8550019067C /* SAAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SAAppDelegate.h; sourceTree = ""; }; 55 | D58C752A1918F8550019067C /* SAAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SAAppDelegate.m; sourceTree = ""; }; 56 | D58C75321918F8550019067C /* SAViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SAViewController.h; sourceTree = ""; }; 57 | D58C75331918F8550019067C /* SAViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SAViewController.m; sourceTree = ""; }; 58 | D58C75351918F8550019067C /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 59 | D58C753C1918F8550019067C /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 60 | /* End PBXFileReference section */ 61 | 62 | /* Begin PBXFrameworksBuildPhase section */ 63 | 10AA361F1D691C66002BA782 /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | ); 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | D58C75141918F8550019067C /* Frameworks */ = { 71 | isa = PBXFrameworksBuildPhase; 72 | buildActionMask = 2147483647; 73 | files = ( 74 | D58C751D1918F8550019067C /* CoreGraphics.framework in Frameworks */, 75 | D58C751F1918F8550019067C /* UIKit.framework in Frameworks */, 76 | D58C751B1918F8550019067C /* Foundation.framework in Frameworks */, 77 | ); 78 | runOnlyForDeploymentPostprocessing = 0; 79 | }; 80 | /* End PBXFrameworksBuildPhase section */ 81 | 82 | /* Begin PBXGroup section */ 83 | 10AA361A1D691B06002BA782 /* support */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | 10AA361B1D691B2C002BA782 /* Info.plist */, 87 | 10AA361D1D691BF4002BA782 /* SAStepper.h */, 88 | ); 89 | name = support; 90 | sourceTree = ""; 91 | }; 92 | 10AA36231D691C66002BA782 /* SAStepperControlUITests */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | 10AA36241D691C66002BA782 /* SAStepperControlUITests.swift */, 96 | 10AA36261D691C66002BA782 /* Info.plist */, 97 | ); 98 | path = SAStepperControlUITests; 99 | sourceTree = ""; 100 | }; 101 | D55C399D19193FEE0090B6B4 /* SAStepperControl */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | D55C399E19193FEE0090B6B4 /* SAStepperControl.h */, 105 | D55C399F19193FEE0090B6B4 /* SAStepperControl.m */, 106 | 10AA36171D6909D5002BA782 /* SAStepperControl+Image.h */, 107 | 10AA36181D690A1A002BA782 /* SAStepperControl+Image.m */, 108 | 10AA361A1D691B06002BA782 /* support */, 109 | ); 110 | name = SAStepperControl; 111 | path = ../../Classes; 112 | sourceTree = ""; 113 | }; 114 | D58C750E1918F8550019067C = { 115 | isa = PBXGroup; 116 | children = ( 117 | D55C399D19193FEE0090B6B4 /* SAStepperControl */, 118 | D58C75201918F8550019067C /* SAStepperControlDemo */, 119 | 10AA36231D691C66002BA782 /* SAStepperControlUITests */, 120 | D58C75191918F8550019067C /* Frameworks */, 121 | D58C75181918F8550019067C /* Products */, 122 | ); 123 | sourceTree = ""; 124 | }; 125 | D58C75181918F8550019067C /* Products */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | D58C75171918F8550019067C /* SAStepperControl.app */, 129 | 10AA36221D691C66002BA782 /* SAStepperControlUITests.xctest */, 130 | ); 131 | name = Products; 132 | sourceTree = ""; 133 | }; 134 | D58C75191918F8550019067C /* Frameworks */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | D58C751A1918F8550019067C /* Foundation.framework */, 138 | D58C751C1918F8550019067C /* CoreGraphics.framework */, 139 | D58C751E1918F8550019067C /* UIKit.framework */, 140 | D58C753C1918F8550019067C /* XCTest.framework */, 141 | ); 142 | name = Frameworks; 143 | sourceTree = ""; 144 | }; 145 | D58C75201918F8550019067C /* SAStepperControlDemo */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | D58C75291918F8550019067C /* SAAppDelegate.h */, 149 | D58C752A1918F8550019067C /* SAAppDelegate.m */, 150 | D58C75321918F8550019067C /* SAViewController.h */, 151 | D58C75331918F8550019067C /* SAViewController.m */, 152 | D58C75211918F8550019067C /* Supporting Files */, 153 | ); 154 | name = SAStepperControlDemo; 155 | path = SAStepperControl; 156 | sourceTree = ""; 157 | }; 158 | D58C75211918F8550019067C /* Supporting Files */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | D58C75351918F8550019067C /* Images.xcassets */, 162 | D58C75221918F8550019067C /* SAStepperControl-Info.plist */, 163 | D58C75231918F8550019067C /* InfoPlist.strings */, 164 | D58C75261918F8550019067C /* main.m */, 165 | D58C75281918F8550019067C /* SAStepperControl-Prefix.pch */, 166 | 10AA362C1D691E97002BA782 /* Launch Screen.storyboard */, 167 | ); 168 | name = "Supporting Files"; 169 | sourceTree = ""; 170 | }; 171 | /* End PBXGroup section */ 172 | 173 | /* Begin PBXNativeTarget section */ 174 | 10AA36211D691C66002BA782 /* SAStepperControlUITests */ = { 175 | isa = PBXNativeTarget; 176 | buildConfigurationList = 10AA36291D691C66002BA782 /* Build configuration list for PBXNativeTarget "SAStepperControlUITests" */; 177 | buildPhases = ( 178 | 10AA361E1D691C66002BA782 /* Sources */, 179 | 10AA361F1D691C66002BA782 /* Frameworks */, 180 | 10AA36201D691C66002BA782 /* Resources */, 181 | ); 182 | buildRules = ( 183 | ); 184 | dependencies = ( 185 | 10AA36281D691C66002BA782 /* PBXTargetDependency */, 186 | ); 187 | name = SAStepperControlUITests; 188 | productName = SAStepperControlUITests; 189 | productReference = 10AA36221D691C66002BA782 /* SAStepperControlUITests.xctest */; 190 | productType = "com.apple.product-type.bundle.ui-testing"; 191 | }; 192 | D58C75161918F8550019067C /* SAStepperControl */ = { 193 | isa = PBXNativeTarget; 194 | buildConfigurationList = D58C754C1918F8550019067C /* Build configuration list for PBXNativeTarget "SAStepperControl" */; 195 | buildPhases = ( 196 | D58C75131918F8550019067C /* Sources */, 197 | D58C75141918F8550019067C /* Frameworks */, 198 | D58C75151918F8550019067C /* Resources */, 199 | ); 200 | buildRules = ( 201 | ); 202 | dependencies = ( 203 | ); 204 | name = SAStepperControl; 205 | productName = SAStepperControl; 206 | productReference = D58C75171918F8550019067C /* SAStepperControl.app */; 207 | productType = "com.apple.product-type.application"; 208 | }; 209 | /* End PBXNativeTarget section */ 210 | 211 | /* Begin PBXProject section */ 212 | D58C750F1918F8550019067C /* Project object */ = { 213 | isa = PBXProject; 214 | attributes = { 215 | CLASSPREFIX = SA; 216 | LastSwiftUpdateCheck = 0730; 217 | LastUpgradeCheck = 0730; 218 | ORGANIZATIONNAME = SA; 219 | TargetAttributes = { 220 | 10AA36211D691C66002BA782 = { 221 | CreatedOnToolsVersion = 7.3.1; 222 | TestTargetID = D58C75161918F8550019067C; 223 | }; 224 | }; 225 | }; 226 | buildConfigurationList = D58C75121918F8550019067C /* Build configuration list for PBXProject "SAStepperControl" */; 227 | compatibilityVersion = "Xcode 3.2"; 228 | developmentRegion = English; 229 | hasScannedForEncodings = 0; 230 | knownRegions = ( 231 | en, 232 | Base, 233 | ); 234 | mainGroup = D58C750E1918F8550019067C; 235 | productRefGroup = D58C75181918F8550019067C /* Products */; 236 | projectDirPath = ""; 237 | projectRoot = ""; 238 | targets = ( 239 | D58C75161918F8550019067C /* SAStepperControl */, 240 | 10AA36211D691C66002BA782 /* SAStepperControlUITests */, 241 | ); 242 | }; 243 | /* End PBXProject section */ 244 | 245 | /* Begin PBXResourcesBuildPhase section */ 246 | 10AA36201D691C66002BA782 /* Resources */ = { 247 | isa = PBXResourcesBuildPhase; 248 | buildActionMask = 2147483647; 249 | files = ( 250 | ); 251 | runOnlyForDeploymentPostprocessing = 0; 252 | }; 253 | D58C75151918F8550019067C /* Resources */ = { 254 | isa = PBXResourcesBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | D58C75361918F8550019067C /* Images.xcassets in Resources */, 258 | D58C75251918F8550019067C /* InfoPlist.strings in Resources */, 259 | 10AA362D1D691E97002BA782 /* Launch Screen.storyboard in Resources */, 260 | 10AA361C1D691B2C002BA782 /* Info.plist in Resources */, 261 | ); 262 | runOnlyForDeploymentPostprocessing = 0; 263 | }; 264 | /* End PBXResourcesBuildPhase section */ 265 | 266 | /* Begin PBXSourcesBuildPhase section */ 267 | 10AA361E1D691C66002BA782 /* Sources */ = { 268 | isa = PBXSourcesBuildPhase; 269 | buildActionMask = 2147483647; 270 | files = ( 271 | 10AA36251D691C66002BA782 /* SAStepperControlUITests.swift in Sources */, 272 | ); 273 | runOnlyForDeploymentPostprocessing = 0; 274 | }; 275 | D58C75131918F8550019067C /* Sources */ = { 276 | isa = PBXSourcesBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | 10AA36191D690A1A002BA782 /* SAStepperControl+Image.m in Sources */, 280 | D58C752B1918F8550019067C /* SAAppDelegate.m in Sources */, 281 | D55C39A019193FEE0090B6B4 /* SAStepperControl.m in Sources */, 282 | D58C75341918F8550019067C /* SAViewController.m in Sources */, 283 | D58C75271918F8550019067C /* main.m in Sources */, 284 | ); 285 | runOnlyForDeploymentPostprocessing = 0; 286 | }; 287 | /* End PBXSourcesBuildPhase section */ 288 | 289 | /* Begin PBXTargetDependency section */ 290 | 10AA36281D691C66002BA782 /* PBXTargetDependency */ = { 291 | isa = PBXTargetDependency; 292 | target = D58C75161918F8550019067C /* SAStepperControl */; 293 | targetProxy = 10AA36271D691C66002BA782 /* PBXContainerItemProxy */; 294 | }; 295 | /* End PBXTargetDependency section */ 296 | 297 | /* Begin PBXVariantGroup section */ 298 | D58C75231918F8550019067C /* InfoPlist.strings */ = { 299 | isa = PBXVariantGroup; 300 | children = ( 301 | D58C75241918F8550019067C /* en */, 302 | ); 303 | name = InfoPlist.strings; 304 | sourceTree = ""; 305 | }; 306 | /* End PBXVariantGroup section */ 307 | 308 | /* Begin XCBuildConfiguration section */ 309 | 10AA362A1D691C66002BA782 /* Debug */ = { 310 | isa = XCBuildConfiguration; 311 | buildSettings = { 312 | CLANG_ANALYZER_NONNULL = YES; 313 | CLANG_WARN_UNREACHABLE_CODE = YES; 314 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 315 | DEBUG_INFORMATION_FORMAT = dwarf; 316 | ENABLE_STRICT_OBJC_MSGSEND = YES; 317 | GCC_NO_COMMON_BLOCKS = YES; 318 | INFOPLIST_FILE = SAStepperControlUITests/Info.plist; 319 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 320 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 321 | MTL_ENABLE_DEBUG_INFO = YES; 322 | PRODUCT_BUNDLE_IDENTIFIER = SA.SAStepperControlUITests; 323 | PRODUCT_NAME = "$(TARGET_NAME)"; 324 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 325 | TEST_TARGET_NAME = SAStepperControl; 326 | }; 327 | name = Debug; 328 | }; 329 | 10AA362B1D691C66002BA782 /* Release */ = { 330 | isa = XCBuildConfiguration; 331 | buildSettings = { 332 | CLANG_ANALYZER_NONNULL = YES; 333 | CLANG_WARN_UNREACHABLE_CODE = YES; 334 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 335 | COPY_PHASE_STRIP = NO; 336 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 337 | ENABLE_STRICT_OBJC_MSGSEND = YES; 338 | GCC_NO_COMMON_BLOCKS = YES; 339 | INFOPLIST_FILE = SAStepperControlUITests/Info.plist; 340 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 341 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 342 | MTL_ENABLE_DEBUG_INFO = NO; 343 | PRODUCT_BUNDLE_IDENTIFIER = SA.SAStepperControlUITests; 344 | PRODUCT_NAME = "$(TARGET_NAME)"; 345 | TEST_TARGET_NAME = SAStepperControl; 346 | }; 347 | name = Release; 348 | }; 349 | D58C754A1918F8550019067C /* Debug */ = { 350 | isa = XCBuildConfiguration; 351 | buildSettings = { 352 | ALWAYS_SEARCH_USER_PATHS = NO; 353 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 354 | CLANG_CXX_LIBRARY = "libc++"; 355 | CLANG_ENABLE_MODULES = YES; 356 | CLANG_ENABLE_OBJC_ARC = YES; 357 | CLANG_WARN_BOOL_CONVERSION = YES; 358 | CLANG_WARN_CONSTANT_CONVERSION = YES; 359 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 360 | CLANG_WARN_EMPTY_BODY = YES; 361 | CLANG_WARN_ENUM_CONVERSION = YES; 362 | CLANG_WARN_INT_CONVERSION = YES; 363 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 364 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 365 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 366 | COPY_PHASE_STRIP = NO; 367 | ENABLE_TESTABILITY = YES; 368 | GCC_C_LANGUAGE_STANDARD = gnu99; 369 | GCC_DYNAMIC_NO_PIC = NO; 370 | GCC_OPTIMIZATION_LEVEL = 0; 371 | GCC_PREPROCESSOR_DEFINITIONS = ( 372 | "DEBUG=1", 373 | "$(inherited)", 374 | ); 375 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 376 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 377 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 378 | GCC_WARN_UNDECLARED_SELECTOR = YES; 379 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 380 | GCC_WARN_UNUSED_FUNCTION = YES; 381 | GCC_WARN_UNUSED_VARIABLE = YES; 382 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 383 | ONLY_ACTIVE_ARCH = YES; 384 | SDKROOT = iphoneos; 385 | TARGETED_DEVICE_FAMILY = "1,2"; 386 | }; 387 | name = Debug; 388 | }; 389 | D58C754B1918F8550019067C /* Release */ = { 390 | isa = XCBuildConfiguration; 391 | buildSettings = { 392 | ALWAYS_SEARCH_USER_PATHS = NO; 393 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 394 | CLANG_CXX_LIBRARY = "libc++"; 395 | CLANG_ENABLE_MODULES = YES; 396 | CLANG_ENABLE_OBJC_ARC = YES; 397 | CLANG_WARN_BOOL_CONVERSION = YES; 398 | CLANG_WARN_CONSTANT_CONVERSION = YES; 399 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 400 | CLANG_WARN_EMPTY_BODY = YES; 401 | CLANG_WARN_ENUM_CONVERSION = YES; 402 | CLANG_WARN_INT_CONVERSION = YES; 403 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 404 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 405 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 406 | COPY_PHASE_STRIP = YES; 407 | ENABLE_NS_ASSERTIONS = NO; 408 | GCC_C_LANGUAGE_STANDARD = gnu99; 409 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 410 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 411 | GCC_WARN_UNDECLARED_SELECTOR = YES; 412 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 413 | GCC_WARN_UNUSED_FUNCTION = YES; 414 | GCC_WARN_UNUSED_VARIABLE = YES; 415 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 416 | SDKROOT = iphoneos; 417 | TARGETED_DEVICE_FAMILY = "1,2"; 418 | VALIDATE_PRODUCT = YES; 419 | }; 420 | name = Release; 421 | }; 422 | D58C754D1918F8550019067C /* Debug */ = { 423 | isa = XCBuildConfiguration; 424 | buildSettings = { 425 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 426 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 427 | GCC_PREFIX_HEADER = "SAStepperControl/SAStepperControl-Prefix.pch"; 428 | INFOPLIST_FILE = "SAStepperControl/SAStepperControl-Info.plist"; 429 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 430 | PRODUCT_BUNDLE_IDENTIFIER = "SA.${PRODUCT_NAME:rfc1034identifier}"; 431 | PRODUCT_NAME = "$(TARGET_NAME)"; 432 | WRAPPER_EXTENSION = app; 433 | }; 434 | name = Debug; 435 | }; 436 | D58C754E1918F8550019067C /* Release */ = { 437 | isa = XCBuildConfiguration; 438 | buildSettings = { 439 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 440 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 441 | GCC_PREFIX_HEADER = "SAStepperControl/SAStepperControl-Prefix.pch"; 442 | INFOPLIST_FILE = "SAStepperControl/SAStepperControl-Info.plist"; 443 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 444 | PRODUCT_BUNDLE_IDENTIFIER = "SA.${PRODUCT_NAME:rfc1034identifier}"; 445 | PRODUCT_NAME = "$(TARGET_NAME)"; 446 | WRAPPER_EXTENSION = app; 447 | }; 448 | name = Release; 449 | }; 450 | /* End XCBuildConfiguration section */ 451 | 452 | /* Begin XCConfigurationList section */ 453 | 10AA36291D691C66002BA782 /* Build configuration list for PBXNativeTarget "SAStepperControlUITests" */ = { 454 | isa = XCConfigurationList; 455 | buildConfigurations = ( 456 | 10AA362A1D691C66002BA782 /* Debug */, 457 | 10AA362B1D691C66002BA782 /* Release */, 458 | ); 459 | defaultConfigurationIsVisible = 0; 460 | }; 461 | D58C75121918F8550019067C /* Build configuration list for PBXProject "SAStepperControl" */ = { 462 | isa = XCConfigurationList; 463 | buildConfigurations = ( 464 | D58C754A1918F8550019067C /* Debug */, 465 | D58C754B1918F8550019067C /* Release */, 466 | ); 467 | defaultConfigurationIsVisible = 0; 468 | defaultConfigurationName = Release; 469 | }; 470 | D58C754C1918F8550019067C /* Build configuration list for PBXNativeTarget "SAStepperControl" */ = { 471 | isa = XCConfigurationList; 472 | buildConfigurations = ( 473 | D58C754D1918F8550019067C /* Debug */, 474 | D58C754E1918F8550019067C /* Release */, 475 | ); 476 | defaultConfigurationIsVisible = 0; 477 | defaultConfigurationName = Release; 478 | }; 479 | /* End XCConfigurationList section */ 480 | }; 481 | rootObject = D58C750F1918F8550019067C /* Project object */; 482 | } 483 | -------------------------------------------------------------------------------- /Example/SAStepperControlDemo/SAStepperControl.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/SAStepperControlDemo/SAStepperControl/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "3x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "3x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "57x57", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "57x57", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "iphone", 45 | "size" : "60x60", 46 | "scale" : "3x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "29x29", 51 | "scale" : "1x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "2x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "40x40", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "2x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "50x50", 71 | "scale" : "1x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "50x50", 76 | "scale" : "2x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "72x72", 81 | "scale" : "1x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "72x72", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ipad", 90 | "size" : "76x76", 91 | "scale" : "1x" 92 | }, 93 | { 94 | "idiom" : "ipad", 95 | "size" : "76x76", 96 | "scale" : "2x" 97 | }, 98 | { 99 | "idiom" : "ipad", 100 | "size" : "83.5x83.5", 101 | "scale" : "2x" 102 | } 103 | ], 104 | "info" : { 105 | "version" : 1, 106 | "author" : "xcode" 107 | } 108 | } -------------------------------------------------------------------------------- /Example/SAStepperControlDemo/SAStepperControl/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/SAStepperControlDemo/SAStepperControl/Launch Screen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 27 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Example/SAStepperControlDemo/SAStepperControl/SAAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAAppDelegate.h 3 | // SAStepperControl 4 | // 5 | // Created by Shams on 06/05/2014. 6 | // Copyright (c) 2014 SA. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface SAAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/SAStepperControlDemo/SAStepperControl/SAAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAAppDelegate.m 3 | // SAStepperControl 4 | // 5 | // Created by Shams on 06/05/2014. 6 | // Copyright (c) 2014 SA. All rights reserved. 7 | // 8 | 9 | #import "SAAppDelegate.h" 10 | #import "SAViewController.h" 11 | 12 | @implementation SAAppDelegate 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 15 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 16 | self.window.backgroundColor = [UIColor whiteColor]; 17 | self.window.rootViewController = [[SAViewController alloc] init]; 18 | 19 | [self.window makeKeyWindow]; 20 | [self.window makeKeyAndVisible]; 21 | 22 | return YES; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Example/SAStepperControlDemo/SAStepperControl/SAStepperControl-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 0.1.4 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 0.1.4 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | Launch Screen 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationPortraitUpsideDown 37 | 38 | UISupportedInterfaceOrientations~ipad 39 | 40 | UIInterfaceOrientationPortrait 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Example/SAStepperControlDemo/SAStepperControl/SAStepperControl-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/SAStepperControlDemo/SAStepperControl/SAViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SAViewController.h 3 | // SAStepperControl 4 | // 5 | // Created by Shams on 06/05/2014. 6 | // Copyright (c) 2014 SA. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface SAViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/SAStepperControlDemo/SAStepperControl/SAViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SAViewController.m 3 | // SAStepperControl 4 | // 5 | // Created by Shams on 06/05/2014. 6 | // Copyright (c) 2014 SA. All rights reserved. 7 | // 8 | 9 | #import "SAViewController.h" 10 | #import "SAStepperControl.h" 11 | 12 | @interface SAViewController () 13 | 14 | @end 15 | 16 | @implementation SAViewController 17 | 18 | #pragma mark - 19 | #pragma mark - Lifecycle 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | 24 | // Example of stepper control style 25 | self.view.tintColor = [UIColor redColor]; 26 | 27 | // Create SAStepperControl 28 | SAStepperControl *stepperControl = [[SAStepperControl alloc] initWithFrame:CGRectMake(self.view.center.x - 46, 29 | self.view.center.y, 30 | 0, 31 | 0)]; 32 | 33 | [self.view addSubview:stepperControl]; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Example/SAStepperControlDemo/SAStepperControl/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/SAStepperControlDemo/SAStepperControl/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SAStepperControl 4 | // 5 | // Created by Shams on 06/05/2014. 6 | // Copyright (c) 2014 SA. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "SAAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SAAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Example/SAStepperControlDemo/SAStepperControlUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/SAStepperControlDemo/SAStepperControlUITests/SAStepperControlUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SAStepperControlUITests.swift 3 | // SAStepperControlUITests 4 | // 5 | // Created by shams ahmed on 21/08/2016. 6 | // Copyright © 2016 SA. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class SAStepperControlUITests: XCTestCase { 12 | 13 | // MARK: 14 | // MARK: Setup 15 | 16 | override func setUp() { 17 | super.setUp() 18 | 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | 21 | // In UI tests it is usually best to stop immediately when a failure occurs. 22 | continueAfterFailure = false 23 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 24 | XCUIApplication().launch() 25 | 26 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 27 | } 28 | 29 | override func tearDown() { 30 | // Put teardown code here. This method is called after the invocation of each test method in the class. 31 | super.tearDown() 32 | } 33 | 34 | // MARK: 35 | // MARK: Test 36 | 37 | func test() { 38 | let steppersQuery = XCUIApplication().steppers 39 | let incrementButton = steppersQuery.buttons["Increment"] 40 | incrementButton.tap() 41 | incrementButton.tap() 42 | incrementButton.tap() 43 | 44 | let decrementButton = steppersQuery.buttons["Decrement"] 45 | decrementButton.tap() 46 | decrementButton.tap() 47 | decrementButton.tap() 48 | incrementButton.tap() 49 | incrementButton.tap() 50 | decrementButton.tap() 51 | decrementButton.tap() 52 | decrementButton.tap() 53 | decrementButton.tap() 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 shams-ahmed 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SAStepperControl 2 | 3 | [![Version](http://cocoapod-badges.herokuapp.com/v/SAStepperControl/badge.png)](http://cocoadocs.org/docsets/SAStepperControl) 4 | [![Platform](http://cocoapod-badges.herokuapp.com/p/SAStepperControl/badge.png)](http://cocoadocs.org/docsets/SAStepperControl) 5 | 6 | ## Purpose 7 | 8 | An easy-to-use UIStepper subclass that implements a counter within the control 9 | 10 | ##### Let's see example 11 | 12 | ![Screenshot:](Assets/example1.gif) 13 | 14 | 15 | ## Usage 16 | 17 | To run the example project; clone the repo, and open the demo project 18 | 19 | ## Requirements 20 | iOS 7 21 | 22 | ## Installation 23 | 24 | SAStepperControl is available through [CocoaPods](http://cocoapods.org), to install 25 | it simply add the following line to your Podfile: 26 | 27 | pod "SAStepperControl" 28 | 29 | ## Author 30 | 31 | shams-ahmed, shamsahmed@me.com 32 | 33 | ## License 34 | 35 | SAStepperControl is available under the MIT license. See the LICENSE file for more info. 36 | 37 | 38 | 39 | [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/shams-ahmed/sasteppercontrol/trend.png)](https://bitdeli.com/free "Bitdeli Badge") 40 | 41 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | desc "Runs the specs [EMPTY]" 2 | task :spec do 3 | # Provide your own implementation 4 | end 5 | 6 | task :version do 7 | git_remotes = `git remote`.strip.split("\n") 8 | 9 | if git_remotes.count > 0 10 | puts "-- fetching version number from github" 11 | sh 'git fetch' 12 | 13 | remote_version = remote_spec_version 14 | end 15 | 16 | if remote_version.nil? 17 | puts "There is no current released version. You're about to release a new Pod." 18 | version = "0.0.1" 19 | else 20 | puts "The current released version of your pod is " + 21 | remote_spec_version.to_s() 22 | version = suggested_version_number 23 | end 24 | 25 | puts "Enter the version you want to release (" + version + ") " 26 | new_version_number = $stdin.gets.strip 27 | if new_version_number == "" 28 | new_version_number = version 29 | end 30 | 31 | replace_version_number(new_version_number) 32 | end 33 | 34 | desc "Release a new version of the Pod (append repo=name to push to a private spec repo)" 35 | task :release do 36 | # Allow override of spec repo name using `repo=private` after task name 37 | repo = ENV["repo"] || "master" 38 | 39 | puts "* Running version" 40 | sh "rake version" 41 | 42 | unless ENV['SKIP_CHECKS'] 43 | if `git symbolic-ref HEAD 2>/dev/null`.strip.split('/').last != 'master' 44 | $stderr.puts "[!] You need to be on the `master' branch in order to be able to do a release." 45 | exit 1 46 | end 47 | 48 | if `git tag`.strip.split("\n").include?(spec_version) 49 | $stderr.puts "[!] A tag for version `#{spec_version}' already exists. Change the version in the podspec" 50 | exit 1 51 | end 52 | 53 | puts "You are about to release `#{spec_version}`, is that correct? [y/n]" 54 | exit if $stdin.gets.strip.downcase != 'y' 55 | end 56 | 57 | puts "* Running specs" 58 | sh "rake spec" 59 | 60 | puts "* Linting the podspec" 61 | sh "pod lib lint" 62 | 63 | # Then release 64 | sh "git commit #{podspec_path} CHANGELOG.md -m 'Release #{spec_version}' --allow-empty" 65 | sh "git tag -a #{spec_version} -m 'Release #{spec_version}'" 66 | sh "git push origin master" 67 | sh "git push origin --tags" 68 | sh "pod push #{repo} #{podspec_path}" 69 | end 70 | 71 | # @return [Pod::Version] The version as reported by the Podspec. 72 | # 73 | def spec_version 74 | require 'cocoapods' 75 | spec = Pod::Specification.from_file(podspec_path) 76 | spec.version 77 | end 78 | 79 | # @return [Pod::Version] The version as reported by the Podspec from remote. 80 | # 81 | def remote_spec_version 82 | require 'cocoapods-core' 83 | 84 | if spec_file_exist_on_remote? 85 | remote_spec = eval(`git show origin/master:#{podspec_path}`) 86 | remote_spec.version 87 | else 88 | nil 89 | end 90 | end 91 | 92 | # @return [Bool] If the remote repository has a copy of the podpesc file or not. 93 | # 94 | def spec_file_exist_on_remote? 95 | test_condition = `if git rev-parse --verify --quiet origin/master:#{podspec_path} >/dev/null; 96 | then 97 | echo 'true' 98 | else 99 | echo 'false' 100 | fi` 101 | 102 | 'true' == test_condition.strip 103 | end 104 | 105 | # @return [String] The relative path of the Podspec. 106 | # 107 | def podspec_path 108 | podspecs = Dir.glob('*.podspec') 109 | if podspecs.count == 1 110 | podspecs.first 111 | else 112 | raise "Could not select a podspec" 113 | end 114 | end 115 | 116 | # @return [String] The suggested version number based on the local and remote 117 | # version numbers. 118 | # 119 | def suggested_version_number 120 | if spec_version != remote_spec_version 121 | spec_version.to_s() 122 | else 123 | next_version(spec_version).to_s() 124 | end 125 | end 126 | 127 | # @param [Pod::Version] version 128 | # the version for which you need the next version 129 | # 130 | # @note It is computed by bumping the last component of 131 | # the version string by 1. 132 | # 133 | # @return [Pod::Version] The version that comes next after 134 | # the version supplied. 135 | # 136 | def next_version(version) 137 | version_components = version.to_s().split("."); 138 | last = (version_components.last.to_i() + 1).to_s 139 | version_components[-1] = last 140 | Pod::Version.new(version_components.join(".")) 141 | end 142 | 143 | # @param [String] new_version_number 144 | # the new version number 145 | # 146 | # @note This methods replaces the version number in the podspec file 147 | # with a new version number. 148 | # 149 | # @return void 150 | # 151 | def replace_version_number(new_version_number) 152 | text = File.read(podspec_path) 153 | text.gsub!(/(s.version( )*= ")#{spec_version}(")/, 154 | "\\1#{new_version_number}\\3") 155 | File.open(podspec_path, "w") { |file| file.puts text } 156 | end 157 | -------------------------------------------------------------------------------- /SAStepperControl.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "SAStepperControl" 3 | s.version = "0.1.4" 4 | s.summary = "UIStepper subclass: display's current value between increment/decrement operators" 5 | s.homepage = "https://github.com/shams-ahmed/SAStepperControl" 6 | s.screenshots = "https://raw.githubusercontent.com/shams-ahmed/SAStepperControl/master/Assets/Screenshot1.png" 7 | s.license = 'MIT' 8 | s.author = { "shams-ahmed" => "shamsahmed@me.com" } 9 | s.source = { :git => "https://github.com/shams-ahmed/SAStepperControl.git", :tag => s.version.to_s } 10 | s.platform = :ios, '7.0' 11 | s.requires_arc = true 12 | s.source_files = 'Classes/**/*.{h,m}' 13 | end 14 | --------------------------------------------------------------------------------