├── LICENSE ├── README.md ├── RangeControl.podspec ├── RangeControl.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── alexeyledovskiy.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── alexeyledovskiy.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── RangeControl ├── Info.plist ├── RangeControl.h └── RangeControl.swift ├── RangeControlExample ├── .gitignore ├── Podfile ├── Podfile.lock ├── Pods │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ ├── project.pbxproj │ │ └── xcuserdata │ │ │ └── alexeyledovskiy.xcuserdatad │ │ │ └── xcschemes │ │ │ ├── Pods-RangeControlExample.xcscheme │ │ │ ├── RangeControl.xcscheme │ │ │ └── xcschememanagement.plist │ ├── RangeControl │ │ ├── LICENSE │ │ └── RangeControl │ │ │ └── RangeControl.swift │ └── Target Support Files │ │ ├── Pods-RangeControlExample │ │ ├── Pods-RangeControlExample-Info.plist │ │ ├── Pods-RangeControlExample-acknowledgements.markdown │ │ ├── Pods-RangeControlExample-acknowledgements.plist │ │ ├── Pods-RangeControlExample-dummy.m │ │ ├── Pods-RangeControlExample-frameworks.sh │ │ ├── Pods-RangeControlExample-umbrella.h │ │ ├── Pods-RangeControlExample.debug.xcconfig │ │ ├── Pods-RangeControlExample.modulemap │ │ └── Pods-RangeControlExample.release.xcconfig │ │ └── RangeControl │ │ ├── RangeControl-Info.plist │ │ ├── RangeControl-dummy.m │ │ ├── RangeControl-prefix.pch │ │ ├── RangeControl-umbrella.h │ │ ├── RangeControl.modulemap │ │ └── RangeControl.xcconfig ├── RangeControlExample.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── alexeyledovskiy.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── alexeyledovskiy.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── RangeControlExample.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── alexeyledovskiy.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist └── RangeControlExample │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ └── testImage.imageset │ │ ├── Contents.json │ │ ├── milky-way-starry-sky-night-sky-star-956981.jpeg │ │ ├── milky-way-starry-sky-night-sky-star-956982.jpeg │ │ └── milky-way-starry-sky-night-sky-star-956983.jpeg │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── ViewController.swift ├── UITest ├── Info.plist └── UITest.swift ├── screenshot1.png ├── screenshot2.gif └── screenshot3.gif /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [2019] [Alexey Ledovskiy] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RangeControl 2 | 3 | RangeControl is a UIControl element that allows to select control range from min to max values. 4 | 5 | [![ScreenShot](https://raw.githubusercontent.com/AlexeyIS/RangeControl/master/screenshot1.png "ScreenShot")](https://raw.githubusercontent.com/AlexeyIS/RangeControl/master/screenshot1.png "ScreenShot") 6 | 7 | [![Screenshoot](https://raw.githubusercontent.com/AlexeyIS/RangeControl/master/screenshot2.gif "Screenshoot")](https://raw.githubusercontent.com/AlexeyIS/RangeControl/master/screenshot2.gif "Screenshoot") 8 | 9 | 10 | ## Getting Started 11 | 12 | You can setup RangeControl from code or from storyboard. It also allows you to add custom view to the background. 13 | 14 | ```swift 15 | let imageView = UIImageView(image: UIImage(named: "testImage")) 16 | imageView.contentMode = .scaleAspectFill 17 | imageView.translatesAutoresizingMaskIntoConstraints = false 18 | imageView.clipsToBounds = true 19 | rangeControl.backgroundView.addArrangedSubview(imageView) 20 | ``` 21 | You can add block to listen for values update: 22 | ``` 23 | rangeControl.onRangeValueChanged = { (low,up) in 24 | print("Low: \(low) up: \(up)") 25 | } 26 | ``` 27 | ### Prerequisites 28 | 29 | The demo project is included here RangeControlExample. 30 | 31 | [![screenshot1](https://raw.githubusercontent.com/AlexeyIS/RangeControl/master/screenshot3.gif "screenshot1")](https://raw.githubusercontent.com/AlexeyIS/RangeControl/master/screenshot3.gif "screenshot1") 32 | 33 | ## Requirements 34 | 35 | - iOS 10.0+ 36 | - Xcode 10.1+ 37 | - Swift 4.2+ 38 | 39 | ## Installation 40 | 41 | ### CocoaPods 42 | 43 | [CocoaPods](https://cocoapods.org) is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate Alamofire into your Xcode project using CocoaPods, specify it in your `Podfile`: 44 | 45 | ```ruby 46 | pod 'RangeControl' 47 | ``` 48 | 49 | ## Authors 50 | 51 | * **Alexey Ledovskiy** - *Initial work* - [RangeControl](https://github.com/AlexeyIS/RangeControl) 52 | 53 | ## Donations 54 | Any amount you can donate today to support the project would be greatly appreciated. 55 | 56 | [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6WLJ933Z3K7BC) 57 | 58 | 59 | 60 | ## License 61 | 62 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details 63 | -------------------------------------------------------------------------------- /RangeControl.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.platform = :ios 3 | s.ios.deployment_target = '10.0' 4 | 5 | s.name = "RangeControl" 6 | s.version = "1.0.0" 7 | s.summary = "RangeControl lets user to trim from both ends." 8 | 9 | s.description = "RangeControl allows to select range values from min to max range." 10 | 11 | s.homepage = "https://github.com/AlexeyIS/RangeControl" 12 | s.screenshots = "https://raw.githubusercontent.com/AlexeyIS/RangeControl/master/screenshot1.png", "https://raw.githubusercontent.com/AlexeyIS/RangeControl/master/screenshot2.gif", "https://raw.githubusercontent.com/AlexeyIS/RangeControl/master/screenshot3.gif" 13 | 14 | s.license = { :type => "MIT", :file => "LICENSE" } 15 | 16 | s.author = { "Alexey Ledovskiy" => "alexey.ledovskiy@gmail.com" } 17 | s.social_media_url = "http://twitter.com/AlexeyIS" 18 | 19 | s.source = { :git => "https://github.com/AlexeyIS/RangeControl.git", :tag => "#{s.version}" } 20 | 21 | 22 | s.source_files = "RangeControl/**/*.{swift}" 23 | s.framework = "UIKit" 24 | s.swift_version = "4.2" 25 | 26 | end 27 | -------------------------------------------------------------------------------- /RangeControl.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4157D93625FD6DE800791F67 /* UITest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4157D93525FD6DE800791F67 /* UITest.swift */; }; 11 | 41FBE982224DEF3600C6AD7E /* RangeControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 41FBE980224DEF3600C6AD7E /* RangeControl.h */; settings = {ATTRIBUTES = (Public, ); }; }; 12 | 41FBE989224DEF5100C6AD7E /* RangeControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41FBE988224DEF5100C6AD7E /* RangeControl.swift */; }; 13 | /* End PBXBuildFile section */ 14 | 15 | /* Begin PBXFileReference section */ 16 | 4157D93325FD6DE800791F67 /* UITest.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UITest.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 17 | 4157D93525FD6DE800791F67 /* UITest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITest.swift; sourceTree = ""; }; 18 | 4157D93725FD6DE800791F67 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 19 | 41FBE97D224DEF3600C6AD7E /* RangeControl.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RangeControl.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 20 | 41FBE980224DEF3600C6AD7E /* RangeControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RangeControl.h; sourceTree = ""; }; 21 | 41FBE981224DEF3600C6AD7E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 22 | 41FBE988224DEF5100C6AD7E /* RangeControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RangeControl.swift; sourceTree = ""; }; 23 | /* End PBXFileReference section */ 24 | 25 | /* Begin PBXFrameworksBuildPhase section */ 26 | 4157D93025FD6DE800791F67 /* Frameworks */ = { 27 | isa = PBXFrameworksBuildPhase; 28 | buildActionMask = 2147483647; 29 | files = ( 30 | ); 31 | runOnlyForDeploymentPostprocessing = 0; 32 | }; 33 | 41FBE97A224DEF3600C6AD7E /* Frameworks */ = { 34 | isa = PBXFrameworksBuildPhase; 35 | buildActionMask = 2147483647; 36 | files = ( 37 | ); 38 | runOnlyForDeploymentPostprocessing = 0; 39 | }; 40 | /* End PBXFrameworksBuildPhase section */ 41 | 42 | /* Begin PBXGroup section */ 43 | 4157D93425FD6DE800791F67 /* UITest */ = { 44 | isa = PBXGroup; 45 | children = ( 46 | 4157D93525FD6DE800791F67 /* UITest.swift */, 47 | 4157D93725FD6DE800791F67 /* Info.plist */, 48 | ); 49 | path = UITest; 50 | sourceTree = ""; 51 | }; 52 | 41FBE973224DEF3600C6AD7E = { 53 | isa = PBXGroup; 54 | children = ( 55 | 41FBE97F224DEF3600C6AD7E /* RangeControl */, 56 | 4157D93425FD6DE800791F67 /* UITest */, 57 | 41FBE97E224DEF3600C6AD7E /* Products */, 58 | ); 59 | sourceTree = ""; 60 | }; 61 | 41FBE97E224DEF3600C6AD7E /* Products */ = { 62 | isa = PBXGroup; 63 | children = ( 64 | 41FBE97D224DEF3600C6AD7E /* RangeControl.framework */, 65 | 4157D93325FD6DE800791F67 /* UITest.xctest */, 66 | ); 67 | name = Products; 68 | sourceTree = ""; 69 | }; 70 | 41FBE97F224DEF3600C6AD7E /* RangeControl */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 41FBE988224DEF5100C6AD7E /* RangeControl.swift */, 74 | 41FBE980224DEF3600C6AD7E /* RangeControl.h */, 75 | 41FBE981224DEF3600C6AD7E /* Info.plist */, 76 | ); 77 | path = RangeControl; 78 | sourceTree = ""; 79 | }; 80 | /* End PBXGroup section */ 81 | 82 | /* Begin PBXHeadersBuildPhase section */ 83 | 41FBE978224DEF3600C6AD7E /* Headers */ = { 84 | isa = PBXHeadersBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | 41FBE982224DEF3600C6AD7E /* RangeControl.h in Headers */, 88 | ); 89 | runOnlyForDeploymentPostprocessing = 0; 90 | }; 91 | /* End PBXHeadersBuildPhase section */ 92 | 93 | /* Begin PBXNativeTarget section */ 94 | 4157D93225FD6DE800791F67 /* UITest */ = { 95 | isa = PBXNativeTarget; 96 | buildConfigurationList = 4157D93A25FD6DE800791F67 /* Build configuration list for PBXNativeTarget "UITest" */; 97 | buildPhases = ( 98 | 4157D92F25FD6DE800791F67 /* Sources */, 99 | 4157D93025FD6DE800791F67 /* Frameworks */, 100 | 4157D93125FD6DE800791F67 /* Resources */, 101 | ); 102 | buildRules = ( 103 | ); 104 | dependencies = ( 105 | ); 106 | name = UITest; 107 | productName = UITest; 108 | productReference = 4157D93325FD6DE800791F67 /* UITest.xctest */; 109 | productType = "com.apple.product-type.bundle.ui-testing"; 110 | }; 111 | 41FBE97C224DEF3600C6AD7E /* RangeControl */ = { 112 | isa = PBXNativeTarget; 113 | buildConfigurationList = 41FBE985224DEF3600C6AD7E /* Build configuration list for PBXNativeTarget "RangeControl" */; 114 | buildPhases = ( 115 | 41FBE978224DEF3600C6AD7E /* Headers */, 116 | 41FBE979224DEF3600C6AD7E /* Sources */, 117 | 41FBE97A224DEF3600C6AD7E /* Frameworks */, 118 | 41FBE97B224DEF3600C6AD7E /* Resources */, 119 | ); 120 | buildRules = ( 121 | ); 122 | dependencies = ( 123 | ); 124 | name = RangeControl; 125 | productName = RangeControl; 126 | productReference = 41FBE97D224DEF3600C6AD7E /* RangeControl.framework */; 127 | productType = "com.apple.product-type.framework"; 128 | }; 129 | /* End PBXNativeTarget section */ 130 | 131 | /* Begin PBXProject section */ 132 | 41FBE974224DEF3600C6AD7E /* Project object */ = { 133 | isa = PBXProject; 134 | attributes = { 135 | LastSwiftUpdateCheck = 1240; 136 | LastUpgradeCheck = 1240; 137 | ORGANIZATIONNAME = "Alexey Ledovskiy"; 138 | TargetAttributes = { 139 | 4157D93225FD6DE800791F67 = { 140 | CreatedOnToolsVersion = 12.4; 141 | }; 142 | 41FBE97C224DEF3600C6AD7E = { 143 | CreatedOnToolsVersion = 10.2; 144 | LastSwiftMigration = 1020; 145 | }; 146 | }; 147 | }; 148 | buildConfigurationList = 41FBE977224DEF3600C6AD7E /* Build configuration list for PBXProject "RangeControl" */; 149 | compatibilityVersion = "Xcode 9.3"; 150 | developmentRegion = en; 151 | hasScannedForEncodings = 0; 152 | knownRegions = ( 153 | en, 154 | Base, 155 | ); 156 | mainGroup = 41FBE973224DEF3600C6AD7E; 157 | productRefGroup = 41FBE97E224DEF3600C6AD7E /* Products */; 158 | projectDirPath = ""; 159 | projectRoot = ""; 160 | targets = ( 161 | 41FBE97C224DEF3600C6AD7E /* RangeControl */, 162 | 4157D93225FD6DE800791F67 /* UITest */, 163 | ); 164 | }; 165 | /* End PBXProject section */ 166 | 167 | /* Begin PBXResourcesBuildPhase section */ 168 | 4157D93125FD6DE800791F67 /* Resources */ = { 169 | isa = PBXResourcesBuildPhase; 170 | buildActionMask = 2147483647; 171 | files = ( 172 | ); 173 | runOnlyForDeploymentPostprocessing = 0; 174 | }; 175 | 41FBE97B224DEF3600C6AD7E /* Resources */ = { 176 | isa = PBXResourcesBuildPhase; 177 | buildActionMask = 2147483647; 178 | files = ( 179 | ); 180 | runOnlyForDeploymentPostprocessing = 0; 181 | }; 182 | /* End PBXResourcesBuildPhase section */ 183 | 184 | /* Begin PBXSourcesBuildPhase section */ 185 | 4157D92F25FD6DE800791F67 /* Sources */ = { 186 | isa = PBXSourcesBuildPhase; 187 | buildActionMask = 2147483647; 188 | files = ( 189 | 4157D93625FD6DE800791F67 /* UITest.swift in Sources */, 190 | ); 191 | runOnlyForDeploymentPostprocessing = 0; 192 | }; 193 | 41FBE979224DEF3600C6AD7E /* Sources */ = { 194 | isa = PBXSourcesBuildPhase; 195 | buildActionMask = 2147483647; 196 | files = ( 197 | 41FBE989224DEF5100C6AD7E /* RangeControl.swift in Sources */, 198 | ); 199 | runOnlyForDeploymentPostprocessing = 0; 200 | }; 201 | /* End PBXSourcesBuildPhase section */ 202 | 203 | /* Begin XCBuildConfiguration section */ 204 | 4157D93825FD6DE800791F67 /* Debug */ = { 205 | isa = XCBuildConfiguration; 206 | buildSettings = { 207 | CODE_SIGN_STYLE = Automatic; 208 | DEVELOPMENT_TEAM = PS9F2MA7E5; 209 | INFOPLIST_FILE = UITest/Info.plist; 210 | IPHONEOS_DEPLOYMENT_TARGET = 14.4; 211 | LD_RUNPATH_SEARCH_PATHS = ( 212 | "$(inherited)", 213 | "@executable_path/Frameworks", 214 | "@loader_path/Frameworks", 215 | ); 216 | PRODUCT_BUNDLE_IDENTIFIER = com.ledovskiy.RangeControlUITest.UITest; 217 | PRODUCT_NAME = "$(TARGET_NAME)"; 218 | SWIFT_VERSION = 5.0; 219 | TARGETED_DEVICE_FAMILY = "1,2"; 220 | }; 221 | name = Debug; 222 | }; 223 | 4157D93925FD6DE800791F67 /* Release */ = { 224 | isa = XCBuildConfiguration; 225 | buildSettings = { 226 | CODE_SIGN_STYLE = Automatic; 227 | DEVELOPMENT_TEAM = PS9F2MA7E5; 228 | INFOPLIST_FILE = UITest/Info.plist; 229 | IPHONEOS_DEPLOYMENT_TARGET = 14.4; 230 | LD_RUNPATH_SEARCH_PATHS = ( 231 | "$(inherited)", 232 | "@executable_path/Frameworks", 233 | "@loader_path/Frameworks", 234 | ); 235 | PRODUCT_BUNDLE_IDENTIFIER = com.ledovskiy.RangeControlUITest.UITest; 236 | PRODUCT_NAME = "$(TARGET_NAME)"; 237 | SWIFT_VERSION = 5.0; 238 | TARGETED_DEVICE_FAMILY = "1,2"; 239 | }; 240 | name = Release; 241 | }; 242 | 41FBE983224DEF3600C6AD7E /* Debug */ = { 243 | isa = XCBuildConfiguration; 244 | buildSettings = { 245 | ALWAYS_SEARCH_USER_PATHS = NO; 246 | CLANG_ANALYZER_NONNULL = YES; 247 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 248 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 249 | CLANG_CXX_LIBRARY = "libc++"; 250 | CLANG_ENABLE_MODULES = YES; 251 | CLANG_ENABLE_OBJC_ARC = YES; 252 | CLANG_ENABLE_OBJC_WEAK = YES; 253 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 254 | CLANG_WARN_BOOL_CONVERSION = YES; 255 | CLANG_WARN_COMMA = YES; 256 | CLANG_WARN_CONSTANT_CONVERSION = YES; 257 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 258 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 259 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 260 | CLANG_WARN_EMPTY_BODY = YES; 261 | CLANG_WARN_ENUM_CONVERSION = YES; 262 | CLANG_WARN_INFINITE_RECURSION = YES; 263 | CLANG_WARN_INT_CONVERSION = YES; 264 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 265 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 266 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 267 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 268 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 269 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 270 | CLANG_WARN_STRICT_PROTOTYPES = YES; 271 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 272 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 273 | CLANG_WARN_UNREACHABLE_CODE = YES; 274 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 275 | CODE_SIGN_IDENTITY = "iPhone Developer"; 276 | COPY_PHASE_STRIP = NO; 277 | CURRENT_PROJECT_VERSION = 1; 278 | DEBUG_INFORMATION_FORMAT = dwarf; 279 | ENABLE_STRICT_OBJC_MSGSEND = YES; 280 | ENABLE_TESTABILITY = YES; 281 | GCC_C_LANGUAGE_STANDARD = gnu11; 282 | GCC_DYNAMIC_NO_PIC = NO; 283 | GCC_NO_COMMON_BLOCKS = YES; 284 | GCC_OPTIMIZATION_LEVEL = 0; 285 | GCC_PREPROCESSOR_DEFINITIONS = ( 286 | "DEBUG=1", 287 | "$(inherited)", 288 | ); 289 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 290 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 291 | GCC_WARN_UNDECLARED_SELECTOR = YES; 292 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 293 | GCC_WARN_UNUSED_FUNCTION = YES; 294 | GCC_WARN_UNUSED_VARIABLE = YES; 295 | IPHONEOS_DEPLOYMENT_TARGET = 12.2; 296 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 297 | MTL_FAST_MATH = YES; 298 | ONLY_ACTIVE_ARCH = YES; 299 | SDKROOT = iphoneos; 300 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 301 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 302 | VERSIONING_SYSTEM = "apple-generic"; 303 | VERSION_INFO_PREFIX = ""; 304 | }; 305 | name = Debug; 306 | }; 307 | 41FBE984224DEF3600C6AD7E /* Release */ = { 308 | isa = XCBuildConfiguration; 309 | buildSettings = { 310 | ALWAYS_SEARCH_USER_PATHS = NO; 311 | CLANG_ANALYZER_NONNULL = YES; 312 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 313 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 314 | CLANG_CXX_LIBRARY = "libc++"; 315 | CLANG_ENABLE_MODULES = YES; 316 | CLANG_ENABLE_OBJC_ARC = YES; 317 | CLANG_ENABLE_OBJC_WEAK = YES; 318 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 319 | CLANG_WARN_BOOL_CONVERSION = YES; 320 | CLANG_WARN_COMMA = YES; 321 | CLANG_WARN_CONSTANT_CONVERSION = YES; 322 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 323 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 324 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 325 | CLANG_WARN_EMPTY_BODY = YES; 326 | CLANG_WARN_ENUM_CONVERSION = YES; 327 | CLANG_WARN_INFINITE_RECURSION = YES; 328 | CLANG_WARN_INT_CONVERSION = YES; 329 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 330 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 331 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 333 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 334 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 335 | CLANG_WARN_STRICT_PROTOTYPES = YES; 336 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 337 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 338 | CLANG_WARN_UNREACHABLE_CODE = YES; 339 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 340 | CODE_SIGN_IDENTITY = "iPhone Developer"; 341 | COPY_PHASE_STRIP = NO; 342 | CURRENT_PROJECT_VERSION = 1; 343 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 344 | ENABLE_NS_ASSERTIONS = NO; 345 | ENABLE_STRICT_OBJC_MSGSEND = YES; 346 | GCC_C_LANGUAGE_STANDARD = gnu11; 347 | GCC_NO_COMMON_BLOCKS = YES; 348 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 349 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 350 | GCC_WARN_UNDECLARED_SELECTOR = YES; 351 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 352 | GCC_WARN_UNUSED_FUNCTION = YES; 353 | GCC_WARN_UNUSED_VARIABLE = YES; 354 | IPHONEOS_DEPLOYMENT_TARGET = 12.2; 355 | MTL_ENABLE_DEBUG_INFO = NO; 356 | MTL_FAST_MATH = YES; 357 | SDKROOT = iphoneos; 358 | SWIFT_COMPILATION_MODE = wholemodule; 359 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 360 | VALIDATE_PRODUCT = YES; 361 | VERSIONING_SYSTEM = "apple-generic"; 362 | VERSION_INFO_PREFIX = ""; 363 | }; 364 | name = Release; 365 | }; 366 | 41FBE986224DEF3600C6AD7E /* Debug */ = { 367 | isa = XCBuildConfiguration; 368 | buildSettings = { 369 | CLANG_ENABLE_MODULES = YES; 370 | CODE_SIGN_IDENTITY = ""; 371 | CODE_SIGN_STYLE = Automatic; 372 | DEFINES_MODULE = YES; 373 | DEVELOPMENT_TEAM = PS9F2MA7E5; 374 | DYLIB_COMPATIBILITY_VERSION = 1; 375 | DYLIB_CURRENT_VERSION = 1; 376 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 377 | INFOPLIST_FILE = RangeControl/Info.plist; 378 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 379 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 380 | "IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 13.1; 381 | LD_RUNPATH_SEARCH_PATHS = ( 382 | "$(inherited)", 383 | "@executable_path/Frameworks", 384 | "@loader_path/Frameworks", 385 | ); 386 | PRODUCT_BUNDLE_IDENTIFIER = com.ledovskiy.RangeControl; 387 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 388 | SKIP_INSTALL = YES; 389 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 390 | SWIFT_VERSION = 5.0; 391 | TARGETED_DEVICE_FAMILY = "1,2"; 392 | }; 393 | name = Debug; 394 | }; 395 | 41FBE987224DEF3600C6AD7E /* Release */ = { 396 | isa = XCBuildConfiguration; 397 | buildSettings = { 398 | CLANG_ENABLE_MODULES = YES; 399 | CODE_SIGN_IDENTITY = ""; 400 | CODE_SIGN_STYLE = Automatic; 401 | DEFINES_MODULE = YES; 402 | DEVELOPMENT_TEAM = PS9F2MA7E5; 403 | DYLIB_COMPATIBILITY_VERSION = 1; 404 | DYLIB_CURRENT_VERSION = 1; 405 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 406 | INFOPLIST_FILE = RangeControl/Info.plist; 407 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 408 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 409 | "IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 13.1; 410 | LD_RUNPATH_SEARCH_PATHS = ( 411 | "$(inherited)", 412 | "@executable_path/Frameworks", 413 | "@loader_path/Frameworks", 414 | ); 415 | PRODUCT_BUNDLE_IDENTIFIER = com.ledovskiy.RangeControl; 416 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 417 | SKIP_INSTALL = YES; 418 | SWIFT_VERSION = 5.0; 419 | TARGETED_DEVICE_FAMILY = "1,2"; 420 | }; 421 | name = Release; 422 | }; 423 | /* End XCBuildConfiguration section */ 424 | 425 | /* Begin XCConfigurationList section */ 426 | 4157D93A25FD6DE800791F67 /* Build configuration list for PBXNativeTarget "UITest" */ = { 427 | isa = XCConfigurationList; 428 | buildConfigurations = ( 429 | 4157D93825FD6DE800791F67 /* Debug */, 430 | 4157D93925FD6DE800791F67 /* Release */, 431 | ); 432 | defaultConfigurationIsVisible = 0; 433 | defaultConfigurationName = Release; 434 | }; 435 | 41FBE977224DEF3600C6AD7E /* Build configuration list for PBXProject "RangeControl" */ = { 436 | isa = XCConfigurationList; 437 | buildConfigurations = ( 438 | 41FBE983224DEF3600C6AD7E /* Debug */, 439 | 41FBE984224DEF3600C6AD7E /* Release */, 440 | ); 441 | defaultConfigurationIsVisible = 0; 442 | defaultConfigurationName = Release; 443 | }; 444 | 41FBE985224DEF3600C6AD7E /* Build configuration list for PBXNativeTarget "RangeControl" */ = { 445 | isa = XCConfigurationList; 446 | buildConfigurations = ( 447 | 41FBE986224DEF3600C6AD7E /* Debug */, 448 | 41FBE987224DEF3600C6AD7E /* Release */, 449 | ); 450 | defaultConfigurationIsVisible = 0; 451 | defaultConfigurationName = Release; 452 | }; 453 | /* End XCConfigurationList section */ 454 | }; 455 | rootObject = 41FBE974224DEF3600C6AD7E /* Project object */; 456 | } 457 | -------------------------------------------------------------------------------- /RangeControl.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RangeControl.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /RangeControl.xcodeproj/project.xcworkspace/xcuserdata/alexeyledovskiy.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexeyIS/RangeControl/44c80cb49a3e258bfa4987daf2df57d20736c4b1/RangeControl.xcodeproj/project.xcworkspace/xcuserdata/alexeyledovskiy.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /RangeControl.xcodeproj/xcuserdata/alexeyledovskiy.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /RangeControl.xcodeproj/xcuserdata/alexeyledovskiy.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | RangeControl.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | UITest.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 1 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /RangeControl/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | 22 | 23 | -------------------------------------------------------------------------------- /RangeControl/RangeControl.h: -------------------------------------------------------------------------------- 1 | // 2 | // RangeControl.h 3 | // RangeControl 4 | // 5 | // Created by Alexey Ledovskiy on 3/28/19. 6 | // Copyright © 2019 Alexey Ledovskiy. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for RangeControl. 12 | FOUNDATION_EXPORT double RangeControlVersionNumber; 13 | 14 | //! Project version string for RangeControl. 15 | FOUNDATION_EXPORT const unsigned char RangeControlVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /RangeControl/RangeControl.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RangeControl.swift 3 | // Chart 4 | // 5 | // Created by Alexey Ledovskiy on 3/12/19. 6 | // Copyright © 2019 Alexey Ledovskiy. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import QuartzCore 11 | 12 | class RangeControlThumbLayer: CALayer { 13 | private let arrowHeight = CGFloat(36.0/128.0) 14 | private let arrowWidth = CGFloat(16.0/32.0) 15 | 16 | var isLeft = false 17 | var highlighted: Bool = false 18 | 19 | override func action(forKey event: String) -> CAAction? { 20 | if(event == "position"){ return nil } 21 | return super.action(forKey: event) 22 | } 23 | 24 | weak var rangeControl: RangeControl? 25 | override func draw(in ctx: CGContext) { 26 | if let slider = rangeControl { 27 | let thumbFrame = bounds 28 | let path = UIBezierPath(roundedRect: thumbFrame, cornerRadius: 2) 29 | ctx.addPath(path.cgPath) 30 | 31 | //Thumb 32 | ctx.setFillColor( slider.thumbColor.cgColor) 33 | ctx.addPath(path.cgPath) 34 | ctx.fillPath() 35 | 36 | //Arrows 37 | let arrow = UIBezierPath() 38 | let center = CGPoint(x: bounds.width/2.0, y: bounds.height/2.0) 39 | let arrowSize = CGSize(width: bounds.width * arrowWidth/1.5, height: bounds.height * arrowHeight) 40 | let arrowRect = CGRect(x: center.x - arrowSize.width/2, y: center.y - arrowSize.height/2, width: arrowSize.width, height: arrowSize.height) 41 | 42 | if(!isLeft){ 43 | arrow.move(to: arrowRect.origin) 44 | arrow.addLine(to: CGPoint(x: center.x + arrowSize.width/2.0, y: center.y)) 45 | arrow.move(to: CGPoint(x: center.x + arrowSize.width/2.0, y: center.y)) 46 | arrow.addLine(to: CGPoint(x: arrowRect.origin.x, y: arrowRect.origin.y + arrowRect.height)) 47 | }else{ 48 | arrow.move(to: CGPoint(x: arrowRect.origin.x + arrowSize.width, y: arrowRect.origin.y)) 49 | arrow.addLine(to: CGPoint(x: center.x - arrowSize.width/2.0, y: center.y)) 50 | arrow.move(to: CGPoint(x: center.x - arrowSize.width/2.0, y: center.y)) 51 | arrow.addLine(to: CGPoint(x: arrowRect.origin.x + arrowSize.width, y: arrowRect.origin.y + arrowRect.height)) 52 | } 53 | 54 | ctx.setLineWidth(2.5) 55 | ctx.setLineCap(.round) 56 | ctx.setStrokeColor(UIColor.white.cgColor) 57 | ctx.addPath(arrow.cgPath) 58 | ctx.strokePath() 59 | } 60 | } 61 | } 62 | 63 | class RangeControlTrackLayer: CALayer { 64 | weak var rangeControl: RangeControl? 65 | override func action(forKey event: String) -> CAAction? { 66 | if(event == "position" || event == "contents"){ return nil } 67 | return super.action(forKey: event) 68 | } 69 | 70 | override func draw(in ctx: CGContext) { 71 | if let slider = rangeControl { 72 | //Tack 73 | let rectTrack = CGRect(x: 0, y: slider.margin, width: bounds.width, height: bounds.height - slider.margin*2) 74 | let path = UIBezierPath(rect: rectTrack) 75 | 76 | let lowerValuePosition = CGFloat(slider.positionForValue(slider.lowValue)) 77 | let upperValuePosition = CGFloat(slider.positionForValue(slider.upValue)) 78 | //Cut rect 79 | let rect = CGRect(x: lowerValuePosition - slider.thumbWidth/2.0, y: slider.margin, width: upperValuePosition - lowerValuePosition + slider.thumbWidth, height: bounds.height - slider.margin*2 ) 80 | 81 | let cutout = UIBezierPath(rect: rect) 82 | path.append(cutout.reversing()) 83 | ctx.addPath(path.cgPath) 84 | 85 | // Fill the track 86 | ctx.setFillColor( slider.trackColor.cgColor) 87 | ctx.addPath(path.cgPath) 88 | ctx.fillPath() 89 | 90 | //Frame borders 91 | let border = CGRect(x: lowerValuePosition, y: 0, width: upperValuePosition - lowerValuePosition , height: bounds.height) 92 | let borderPath = UIBezierPath(rect: border) 93 | 94 | let borderCut = CGRect(x: lowerValuePosition, y: 1, width: upperValuePosition - lowerValuePosition , height: bounds.height-2) 95 | let borderCutPath = UIBezierPath(rect: borderCut) 96 | 97 | borderPath.append(borderCutPath.reversing()) 98 | ctx.setFillColor(slider.thumbColor.cgColor) 99 | ctx.addPath(borderPath.cgPath) 100 | ctx.fillPath() 101 | 102 | } 103 | } 104 | } 105 | 106 | public typealias OnRangeValueChanged = ((_ low:Float, _ up:Float)->Void) 107 | 108 | open class RangeControl: UIControl{ 109 | 110 | static let height = CGFloat(50.0) 111 | let margin = CGFloat(4.0) 112 | 113 | private let trackLayer = RangeControlTrackLayer() 114 | private let lowThumbLayer = RangeControlThumbLayer() 115 | private let upThumbLayer = RangeControlThumbLayer() 116 | public let backgroundView = UIStackView() 117 | private let contentView = UIView() 118 | 119 | private var previousLocation = CGPoint() 120 | 121 | open var minValue:Float = 0.0 { didSet { updateLayerFrames() } } 122 | open var maxValue:Float = 1.0 { didSet { updateLayerFrames() } } 123 | open var lowValue:Float = 0.8 { didSet { updateLayerFrames() } } 124 | open var upValue:Float = 1.0 { didSet { updateLayerFrames() } } 125 | open var onRangeValueChanged: OnRangeValueChanged? 126 | 127 | open var trackColor: UIColor = UIColor.lightGray.withAlphaComponent(0.45) { 128 | didSet { trackLayer.setNeedsDisplay() } 129 | } 130 | 131 | open var thumbColor: UIColor = UIColor.lightGray.withAlphaComponent(0.95) { 132 | didSet { 133 | lowThumbLayer.setNeedsDisplay() 134 | upThumbLayer.setNeedsDisplay() 135 | } 136 | } 137 | 138 | open var thumbWidth:CGFloat{ 139 | return CGFloat(bounds.height/4.0) 140 | } 141 | 142 | open var thumbHeight:CGFloat{ 143 | return CGFloat(bounds.height) 144 | } 145 | 146 | override open var frame: CGRect { didSet { updateLayerFrames() } } 147 | 148 | public override init(frame: CGRect) { 149 | super.init(frame: frame) 150 | setup() 151 | 152 | } 153 | 154 | public required init?(coder aDecoder: NSCoder) { 155 | super.init(coder: aDecoder) 156 | setup() 157 | } 158 | 159 | override open func layoutSubviews() { 160 | super.layoutSubviews() 161 | updateLayerFrames() 162 | } 163 | 164 | private func setup() { 165 | translatesAutoresizingMaskIntoConstraints = false 166 | backgroundView.translatesAutoresizingMaskIntoConstraints = false 167 | 168 | addSubview(backgroundView) 169 | backgroundView.isUserInteractionEnabled = false 170 | backgroundView.topAnchor.constraint(equalTo: self.topAnchor, constant: margin).isActive = true 171 | backgroundView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -margin).isActive = true 172 | backgroundView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0).isActive = true 173 | backgroundView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0).isActive = true 174 | setNeedsLayout() 175 | contentView.translatesAutoresizingMaskIntoConstraints = false 176 | addSubview(contentView) 177 | contentView.frame = bounds 178 | contentView.isUserInteractionEnabled = false 179 | contentView.backgroundColor = UIColor.clear 180 | contentView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true 181 | contentView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true 182 | contentView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true 183 | contentView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true 184 | 185 | 186 | trackLayer.isOpaque = false 187 | lowThumbLayer.isOpaque = false 188 | upThumbLayer.isOpaque = false 189 | 190 | 191 | lowThumbLayer.isLeft = true 192 | contentView.layer.addSublayer(trackLayer) 193 | contentView.layer.addSublayer(lowThumbLayer) 194 | contentView.layer.addSublayer(upThumbLayer) 195 | updateLayerFrames() 196 | lowThumbLayer.rangeControl = self 197 | upThumbLayer.rangeControl = self 198 | trackLayer.rangeControl = self 199 | 200 | trackLayer.contentsScale = UIScreen.main.scale 201 | lowThumbLayer.contentsScale = UIScreen.main.scale 202 | upThumbLayer.contentsScale = UIScreen.main.scale 203 | setNeedsDisplay() 204 | } 205 | 206 | open func updateLayerFrames() { 207 | if(minValue == Float.nan || lowValue == Float.nan || upValue == Float.nan || maxValue == Float.nan){ 208 | return 209 | } 210 | 211 | trackLayer.frame = bounds 212 | 213 | let lowThumbCenter = CGFloat(positionForValue(lowValue)) 214 | let upThumbCenter = CGFloat(positionForValue(upValue)) 215 | lowThumbLayer.frame = CGRect(x: lowThumbCenter - thumbWidth / 2.0, y: 0.0, width: thumbWidth, height: thumbHeight) 216 | upThumbLayer.frame = CGRect(x: upThumbCenter - thumbWidth / 2.0, y: 0.0, width: thumbWidth, height: thumbHeight) 217 | 218 | trackLayer.setNeedsDisplay() 219 | lowThumbLayer.setNeedsDisplay() 220 | upThumbLayer.setNeedsDisplay() 221 | onRangeValueChanged?(lowValue,upValue) 222 | } 223 | 224 | func positionForValue(_ value: Float) -> Float { 225 | return Float(bounds.width - thumbWidth) * (value - minValue) / 226 | (maxValue - minValue) + Float(thumbWidth / 2.0) 227 | } 228 | 229 | override open func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { 230 | previousLocation = touch.location(in: self) 231 | 232 | if lowThumbLayer.frame.contains(previousLocation) { 233 | lowThumbLayer.highlighted = true 234 | } else if upThumbLayer.frame.contains(previousLocation) { 235 | upThumbLayer.highlighted = true 236 | } else if (lowThumbLayer.frame.union(upThumbLayer.frame).contains(previousLocation)){ //between handles 237 | lowThumbLayer.highlighted = true 238 | upThumbLayer.highlighted = true 239 | } 240 | 241 | 242 | return lowThumbLayer.highlighted || upThumbLayer.highlighted 243 | } 244 | 245 | private func boundValue(_ value: Float, toLowerValue lowerValue: Float, upperValue: Float) -> Float { 246 | return Float.minimum(Float.maximum(value, lowerValue), upperValue) 247 | } 248 | 249 | override open func endTracking(_ touch: UITouch?, with event: UIEvent?) { 250 | lowThumbLayer.highlighted = false 251 | upThumbLayer.highlighted = false 252 | } 253 | 254 | 255 | override open func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { 256 | let location = touch.location(in: self) 257 | // 1. Determine by how much the user has dragged 258 | let deltaLocation = Float(location.x - previousLocation.x) 259 | let deltaValue = (maxValue - minValue) * deltaLocation / Float(bounds.width - thumbWidth) 260 | 261 | previousLocation = location 262 | 263 | // 2. Update the values 264 | if lowThumbLayer.highlighted { 265 | lowValue += deltaValue 266 | let lowValueTmp = boundValue(lowValue, toLowerValue: minValue, upperValue: upValue - 0.02) 267 | lowValue = Float.maximum(lowValueTmp, 0) 268 | } 269 | if upThumbLayer.highlighted { 270 | upValue += deltaValue 271 | let upValueTmp = boundValue(upValue, toLowerValue: lowValue + 0.02, upperValue: maxValue) 272 | upValue = Float.minimum(upValueTmp, 1.0) 273 | } 274 | 275 | // 3. Update the UI 276 | CATransaction.begin() 277 | CATransaction.setDisableActions(false) 278 | self.updateLayerFrames() 279 | CATransaction.commit() 280 | return super.continueTracking(touch, with: event) 281 | } 282 | } 283 | -------------------------------------------------------------------------------- /RangeControlExample/.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | # *.xcodeproj 44 | # 45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 46 | # hence it is not needed unless you have added a package configuration file to your project 47 | # .swiftpm 48 | 49 | .build/ 50 | 51 | # CocoaPods 52 | # 53 | # We recommend against adding the Pods directory to your .gitignore. However 54 | # you should judge for yourself, the pros and cons are mentioned at: 55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 56 | # 57 | Pods/ 58 | # 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | 62 | # Carthage 63 | # 64 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 65 | # Carthage/Checkouts 66 | 67 | Carthage/Build/ 68 | 69 | # Accio dependency management 70 | Dependencies/ 71 | .accio/ 72 | 73 | # fastlane 74 | # 75 | # It is recommended to not store the screenshots in the git repo. 76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 77 | # For more information about the recommended setup visit: 78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 79 | 80 | fastlane/report.xml 81 | fastlane/Preview.html 82 | fastlane/screenshots/**/*.png 83 | fastlane/test_output 84 | 85 | # Code Injection 86 | # 87 | # After new code Injection tools there's a generated folder /iOSInjectionProject 88 | # https://github.com/johnno1962/injectionforxcode 89 | 90 | iOSInjectionProject/ 91 | -------------------------------------------------------------------------------- /RangeControlExample/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | platform :ios, '10.0' 3 | 4 | source 'https://github.com/CocoaPods/Specs.git' 5 | 6 | target 'RangeControlExample' do 7 | use_frameworks! 8 | pod 'RangeControl' 9 | end 10 | 11 | -------------------------------------------------------------------------------- /RangeControlExample/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - RangeControl (0.0.3) 3 | 4 | DEPENDENCIES: 5 | - RangeControl 6 | 7 | SPEC REPOS: 8 | https://github.com/AlexeyIS/RCPodSpecs.git: 9 | - RangeControl 10 | 11 | SPEC CHECKSUMS: 12 | RangeControl: 986ea268e4eb72c1527f394daeaccaffd520625e 13 | 14 | PODFILE CHECKSUM: ccd6a7f2e28bfaf3bd8644edc5314af7e3e69748 15 | 16 | COCOAPODS: 1.6.1 17 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - RangeControl (0.0.3) 3 | 4 | DEPENDENCIES: 5 | - RangeControl 6 | 7 | SPEC REPOS: 8 | https://github.com/AlexeyIS/RCPodSpecs.git: 9 | - RangeControl 10 | 11 | SPEC CHECKSUMS: 12 | RangeControl: 986ea268e4eb72c1527f394daeaccaffd520625e 13 | 14 | PODFILE CHECKSUM: ccd6a7f2e28bfaf3bd8644edc5314af7e3e69748 15 | 16 | COCOAPODS: 1.6.1 17 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Pods.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1231212A19B679E4D47D6BFD3DF5CAF1 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ECF2A2B0720AE923C22BED3192888BE0 /* UIKit.framework */; }; 11 | 14A4965F6F63C05E689D1C7878E976AB /* RangeControl-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 20AF08BB601F56FE040CF4CA1680B002 /* RangeControl-dummy.m */; }; 12 | 1FF295E4128D350F2E89B71E9D125EC3 /* RangeControl-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = E2DE5B038E9E561B9113A9973FECDEF7 /* RangeControl-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | 482556BBA426E3081303DC0ED1D116FA /* Pods-RangeControlExample-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = E4516C6759402B3EDCFF02CA0458E5C8 /* Pods-RangeControlExample-dummy.m */; }; 14 | 5CB8ECFB2F083857FD277AE231882AA1 /* RangeControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB954DC14A06AD852E2A325FE89C5618 /* RangeControl.swift */; }; 15 | 734DEB18271C4EB4ED56CD22600D259E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 40CB39E715FBCDAA142E6513E126200A /* Foundation.framework */; }; 16 | DD52E644562B28DFE3CF45B2C5741C55 /* Pods-RangeControlExample-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 2F0369FABCEBEE0E29F187A6B2F2FE54 /* Pods-RangeControlExample-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17 | F431807CEF258ABF7B52E2F2C75859A7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 40CB39E715FBCDAA142E6513E126200A /* Foundation.framework */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXContainerItemProxy section */ 21 | C39E8D95FF0DE965CF1CC7A5A8781667 /* PBXContainerItemProxy */ = { 22 | isa = PBXContainerItemProxy; 23 | containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; 24 | proxyType = 1; 25 | remoteGlobalIDString = 523229D3359C9B2A1C75AC5CAB512BC9; 26 | remoteInfo = RangeControl; 27 | }; 28 | /* End PBXContainerItemProxy section */ 29 | 30 | /* Begin PBXFileReference section */ 31 | 20AF08BB601F56FE040CF4CA1680B002 /* RangeControl-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "RangeControl-dummy.m"; sourceTree = ""; }; 32 | 2F0369FABCEBEE0E29F187A6B2F2FE54 /* Pods-RangeControlExample-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-RangeControlExample-umbrella.h"; sourceTree = ""; }; 33 | 3A6CD6C683A5E3DAE91C7EF9C15A22D2 /* RangeControl.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = RangeControl.framework; path = RangeControl.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | 40CB39E715FBCDAA142E6513E126200A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 35 | 55F7FCCE67CB65D35476BC7D64CC66EB /* RangeControl.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = RangeControl.modulemap; sourceTree = ""; }; 36 | 74481C1015FD74CC5B7C6C25AC77D6C2 /* Pods-RangeControlExample-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-RangeControlExample-acknowledgements.markdown"; sourceTree = ""; }; 37 | 7C7329CC52742AAD7C30EFBA3806A9A9 /* Pods-RangeControlExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-RangeControlExample.debug.xcconfig"; sourceTree = ""; }; 38 | 98EE4B64EFE198ADC82A92450FB97C5E /* RangeControl-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "RangeControl-Info.plist"; sourceTree = ""; }; 39 | 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 40 | A20030A7A85CD007F7EBE2115702A346 /* RangeControl-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RangeControl-prefix.pch"; sourceTree = ""; }; 41 | ADB5D7305F292456C6C5F9EC0CF57502 /* Pods-RangeControlExample-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-RangeControlExample-acknowledgements.plist"; sourceTree = ""; }; 42 | B7E6FAD09DA076BD59CA546832FCC746 /* Pods-RangeControlExample-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-RangeControlExample-Info.plist"; sourceTree = ""; }; 43 | BB954DC14A06AD852E2A325FE89C5618 /* RangeControl.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RangeControl.swift; path = RangeControl/RangeControl.swift; sourceTree = ""; }; 44 | CAF87FBDD3EE2543AABA1A63AF4A928A /* Pods-RangeControlExample-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-RangeControlExample-frameworks.sh"; sourceTree = ""; }; 45 | CC26B9DF1A436369864FD38499E94A0E /* Pods_RangeControlExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_RangeControlExample.framework; path = "Pods-RangeControlExample.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | CCEA90F795548B3234C46A5220C21C99 /* Pods-RangeControlExample.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-RangeControlExample.modulemap"; sourceTree = ""; }; 47 | CE5326E097499D5CD62B80F61067747F /* Pods-RangeControlExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-RangeControlExample.release.xcconfig"; sourceTree = ""; }; 48 | D4F01B56A0E6C27893A067223A1EA0E9 /* RangeControl.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = RangeControl.xcconfig; sourceTree = ""; }; 49 | E2DE5B038E9E561B9113A9973FECDEF7 /* RangeControl-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "RangeControl-umbrella.h"; sourceTree = ""; }; 50 | E4516C6759402B3EDCFF02CA0458E5C8 /* Pods-RangeControlExample-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-RangeControlExample-dummy.m"; sourceTree = ""; }; 51 | ECF2A2B0720AE923C22BED3192888BE0 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; 52 | /* End PBXFileReference section */ 53 | 54 | /* Begin PBXFrameworksBuildPhase section */ 55 | D8AE6F7405689155AB8ADA3CDB8FC02C /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | 734DEB18271C4EB4ED56CD22600D259E /* Foundation.framework in Frameworks */, 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | E48A22945BBB722497D426CC5F0AA270 /* Frameworks */ = { 64 | isa = PBXFrameworksBuildPhase; 65 | buildActionMask = 2147483647; 66 | files = ( 67 | F431807CEF258ABF7B52E2F2C75859A7 /* Foundation.framework in Frameworks */, 68 | 1231212A19B679E4D47D6BFD3DF5CAF1 /* UIKit.framework in Frameworks */, 69 | ); 70 | runOnlyForDeploymentPostprocessing = 0; 71 | }; 72 | /* End PBXFrameworksBuildPhase section */ 73 | 74 | /* Begin PBXGroup section */ 75 | 03FCE88098553F7835B61D657590FA1B /* Products */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | CC26B9DF1A436369864FD38499E94A0E /* Pods_RangeControlExample.framework */, 79 | 3A6CD6C683A5E3DAE91C7EF9C15A22D2 /* RangeControl.framework */, 80 | ); 81 | name = Products; 82 | sourceTree = ""; 83 | }; 84 | 1628BF05B4CAFDCC3549A101F5A10A17 /* Frameworks */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | E169A450ED27AC725DF52953F66D11E0 /* iOS */, 88 | ); 89 | name = Frameworks; 90 | sourceTree = ""; 91 | }; 92 | 274A6950D94757A5DE6DD93DD7834E7C /* Support Files */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | 55F7FCCE67CB65D35476BC7D64CC66EB /* RangeControl.modulemap */, 96 | D4F01B56A0E6C27893A067223A1EA0E9 /* RangeControl.xcconfig */, 97 | 20AF08BB601F56FE040CF4CA1680B002 /* RangeControl-dummy.m */, 98 | 98EE4B64EFE198ADC82A92450FB97C5E /* RangeControl-Info.plist */, 99 | A20030A7A85CD007F7EBE2115702A346 /* RangeControl-prefix.pch */, 100 | E2DE5B038E9E561B9113A9973FECDEF7 /* RangeControl-umbrella.h */, 101 | ); 102 | name = "Support Files"; 103 | path = "../Target Support Files/RangeControl"; 104 | sourceTree = ""; 105 | }; 106 | 2F718BCFE5E926DDF2F5E7E5CAA73209 /* Pods-RangeControlExample */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | CCEA90F795548B3234C46A5220C21C99 /* Pods-RangeControlExample.modulemap */, 110 | 74481C1015FD74CC5B7C6C25AC77D6C2 /* Pods-RangeControlExample-acknowledgements.markdown */, 111 | ADB5D7305F292456C6C5F9EC0CF57502 /* Pods-RangeControlExample-acknowledgements.plist */, 112 | E4516C6759402B3EDCFF02CA0458E5C8 /* Pods-RangeControlExample-dummy.m */, 113 | CAF87FBDD3EE2543AABA1A63AF4A928A /* Pods-RangeControlExample-frameworks.sh */, 114 | B7E6FAD09DA076BD59CA546832FCC746 /* Pods-RangeControlExample-Info.plist */, 115 | 2F0369FABCEBEE0E29F187A6B2F2FE54 /* Pods-RangeControlExample-umbrella.h */, 116 | 7C7329CC52742AAD7C30EFBA3806A9A9 /* Pods-RangeControlExample.debug.xcconfig */, 117 | CE5326E097499D5CD62B80F61067747F /* Pods-RangeControlExample.release.xcconfig */, 118 | ); 119 | name = "Pods-RangeControlExample"; 120 | path = "Target Support Files/Pods-RangeControlExample"; 121 | sourceTree = ""; 122 | }; 123 | 884B845190DCF9AC797CF2D33F0CA2EC /* Targets Support Files */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 2F718BCFE5E926DDF2F5E7E5CAA73209 /* Pods-RangeControlExample */, 127 | ); 128 | name = "Targets Support Files"; 129 | sourceTree = ""; 130 | }; 131 | 967E9796A9C521EEC6D4013109519636 /* Pods */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | F5D4E21D0863C4714D1D0552047F2E62 /* RangeControl */, 135 | ); 136 | name = Pods; 137 | sourceTree = ""; 138 | }; 139 | CF1408CF629C7361332E53B88F7BD30C = { 140 | isa = PBXGroup; 141 | children = ( 142 | 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, 143 | 1628BF05B4CAFDCC3549A101F5A10A17 /* Frameworks */, 144 | 967E9796A9C521EEC6D4013109519636 /* Pods */, 145 | 03FCE88098553F7835B61D657590FA1B /* Products */, 146 | 884B845190DCF9AC797CF2D33F0CA2EC /* Targets Support Files */, 147 | ); 148 | sourceTree = ""; 149 | }; 150 | E169A450ED27AC725DF52953F66D11E0 /* iOS */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 40CB39E715FBCDAA142E6513E126200A /* Foundation.framework */, 154 | ECF2A2B0720AE923C22BED3192888BE0 /* UIKit.framework */, 155 | ); 156 | name = iOS; 157 | sourceTree = ""; 158 | }; 159 | F5D4E21D0863C4714D1D0552047F2E62 /* RangeControl */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | BB954DC14A06AD852E2A325FE89C5618 /* RangeControl.swift */, 163 | 274A6950D94757A5DE6DD93DD7834E7C /* Support Files */, 164 | ); 165 | name = RangeControl; 166 | path = RangeControl; 167 | sourceTree = ""; 168 | }; 169 | /* End PBXGroup section */ 170 | 171 | /* Begin PBXHeadersBuildPhase section */ 172 | 5B3DA4EB22DC2C88A17CD8EC100A6140 /* Headers */ = { 173 | isa = PBXHeadersBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | DD52E644562B28DFE3CF45B2C5741C55 /* Pods-RangeControlExample-umbrella.h in Headers */, 177 | ); 178 | runOnlyForDeploymentPostprocessing = 0; 179 | }; 180 | 6914755266B31B09A645CA379594C37F /* Headers */ = { 181 | isa = PBXHeadersBuildPhase; 182 | buildActionMask = 2147483647; 183 | files = ( 184 | 1FF295E4128D350F2E89B71E9D125EC3 /* RangeControl-umbrella.h in Headers */, 185 | ); 186 | runOnlyForDeploymentPostprocessing = 0; 187 | }; 188 | /* End PBXHeadersBuildPhase section */ 189 | 190 | /* Begin PBXNativeTarget section */ 191 | 523229D3359C9B2A1C75AC5CAB512BC9 /* RangeControl */ = { 192 | isa = PBXNativeTarget; 193 | buildConfigurationList = 0CB9338E3CE7D2A340D957EE106C688C /* Build configuration list for PBXNativeTarget "RangeControl" */; 194 | buildPhases = ( 195 | 6914755266B31B09A645CA379594C37F /* Headers */, 196 | EB2B6A98AA3E4ABDBBC2E2F1FD2BE955 /* Sources */, 197 | E48A22945BBB722497D426CC5F0AA270 /* Frameworks */, 198 | 8C3EFF38F9BD00B36A3A16AC225DE54C /* Resources */, 199 | ); 200 | buildRules = ( 201 | ); 202 | dependencies = ( 203 | ); 204 | name = RangeControl; 205 | productName = RangeControl; 206 | productReference = 3A6CD6C683A5E3DAE91C7EF9C15A22D2 /* RangeControl.framework */; 207 | productType = "com.apple.product-type.framework"; 208 | }; 209 | 98F8692761F2EECD7FB69DA55F21C443 /* Pods-RangeControlExample */ = { 210 | isa = PBXNativeTarget; 211 | buildConfigurationList = 1DF7769CAC3B791680F4FC2DB61AF155 /* Build configuration list for PBXNativeTarget "Pods-RangeControlExample" */; 212 | buildPhases = ( 213 | 5B3DA4EB22DC2C88A17CD8EC100A6140 /* Headers */, 214 | B3CAF69F0F88CA7270CA4D3D350EA893 /* Sources */, 215 | D8AE6F7405689155AB8ADA3CDB8FC02C /* Frameworks */, 216 | 00D2EF30C23F294F0A2E345AF1062B3B /* Resources */, 217 | ); 218 | buildRules = ( 219 | ); 220 | dependencies = ( 221 | A7D81918B7CB3AC8081B5E1B8D026099 /* PBXTargetDependency */, 222 | ); 223 | name = "Pods-RangeControlExample"; 224 | productName = "Pods-RangeControlExample"; 225 | productReference = CC26B9DF1A436369864FD38499E94A0E /* Pods_RangeControlExample.framework */; 226 | productType = "com.apple.product-type.framework"; 227 | }; 228 | /* End PBXNativeTarget section */ 229 | 230 | /* Begin PBXProject section */ 231 | BFDFE7DC352907FC980B868725387E98 /* Project object */ = { 232 | isa = PBXProject; 233 | attributes = { 234 | LastSwiftUpdateCheck = 0930; 235 | LastUpgradeCheck = 0930; 236 | }; 237 | buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; 238 | compatibilityVersion = "Xcode 9.3"; 239 | developmentRegion = English; 240 | hasScannedForEncodings = 0; 241 | knownRegions = ( 242 | en, 243 | ); 244 | mainGroup = CF1408CF629C7361332E53B88F7BD30C; 245 | productRefGroup = 03FCE88098553F7835B61D657590FA1B /* Products */; 246 | projectDirPath = ""; 247 | projectRoot = ""; 248 | targets = ( 249 | 98F8692761F2EECD7FB69DA55F21C443 /* Pods-RangeControlExample */, 250 | 523229D3359C9B2A1C75AC5CAB512BC9 /* RangeControl */, 251 | ); 252 | }; 253 | /* End PBXProject section */ 254 | 255 | /* Begin PBXResourcesBuildPhase section */ 256 | 00D2EF30C23F294F0A2E345AF1062B3B /* Resources */ = { 257 | isa = PBXResourcesBuildPhase; 258 | buildActionMask = 2147483647; 259 | files = ( 260 | ); 261 | runOnlyForDeploymentPostprocessing = 0; 262 | }; 263 | 8C3EFF38F9BD00B36A3A16AC225DE54C /* Resources */ = { 264 | isa = PBXResourcesBuildPhase; 265 | buildActionMask = 2147483647; 266 | files = ( 267 | ); 268 | runOnlyForDeploymentPostprocessing = 0; 269 | }; 270 | /* End PBXResourcesBuildPhase section */ 271 | 272 | /* Begin PBXSourcesBuildPhase section */ 273 | B3CAF69F0F88CA7270CA4D3D350EA893 /* Sources */ = { 274 | isa = PBXSourcesBuildPhase; 275 | buildActionMask = 2147483647; 276 | files = ( 277 | 482556BBA426E3081303DC0ED1D116FA /* Pods-RangeControlExample-dummy.m in Sources */, 278 | ); 279 | runOnlyForDeploymentPostprocessing = 0; 280 | }; 281 | EB2B6A98AA3E4ABDBBC2E2F1FD2BE955 /* Sources */ = { 282 | isa = PBXSourcesBuildPhase; 283 | buildActionMask = 2147483647; 284 | files = ( 285 | 14A4965F6F63C05E689D1C7878E976AB /* RangeControl-dummy.m in Sources */, 286 | 5CB8ECFB2F083857FD277AE231882AA1 /* RangeControl.swift in Sources */, 287 | ); 288 | runOnlyForDeploymentPostprocessing = 0; 289 | }; 290 | /* End PBXSourcesBuildPhase section */ 291 | 292 | /* Begin PBXTargetDependency section */ 293 | A7D81918B7CB3AC8081B5E1B8D026099 /* PBXTargetDependency */ = { 294 | isa = PBXTargetDependency; 295 | name = RangeControl; 296 | target = 523229D3359C9B2A1C75AC5CAB512BC9 /* RangeControl */; 297 | targetProxy = C39E8D95FF0DE965CF1CC7A5A8781667 /* PBXContainerItemProxy */; 298 | }; 299 | /* End PBXTargetDependency section */ 300 | 301 | /* Begin XCBuildConfiguration section */ 302 | 84A06F28E9E7D9EB0A9B476A8668FD60 /* Release */ = { 303 | isa = XCBuildConfiguration; 304 | buildSettings = { 305 | ALWAYS_SEARCH_USER_PATHS = NO; 306 | CLANG_ANALYZER_NONNULL = YES; 307 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 308 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 309 | CLANG_CXX_LIBRARY = "libc++"; 310 | CLANG_ENABLE_MODULES = YES; 311 | CLANG_ENABLE_OBJC_ARC = YES; 312 | CLANG_ENABLE_OBJC_WEAK = YES; 313 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 314 | CLANG_WARN_BOOL_CONVERSION = YES; 315 | CLANG_WARN_COMMA = YES; 316 | CLANG_WARN_CONSTANT_CONVERSION = YES; 317 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 318 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 319 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 320 | CLANG_WARN_EMPTY_BODY = YES; 321 | CLANG_WARN_ENUM_CONVERSION = YES; 322 | CLANG_WARN_INFINITE_RECURSION = YES; 323 | CLANG_WARN_INT_CONVERSION = YES; 324 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 325 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 326 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 327 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 328 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 329 | CLANG_WARN_STRICT_PROTOTYPES = YES; 330 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 331 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 332 | CLANG_WARN_UNREACHABLE_CODE = YES; 333 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 334 | COPY_PHASE_STRIP = NO; 335 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 336 | ENABLE_NS_ASSERTIONS = NO; 337 | ENABLE_STRICT_OBJC_MSGSEND = YES; 338 | GCC_C_LANGUAGE_STANDARD = gnu11; 339 | GCC_NO_COMMON_BLOCKS = YES; 340 | GCC_PREPROCESSOR_DEFINITIONS = ( 341 | "POD_CONFIGURATION_RELEASE=1", 342 | "$(inherited)", 343 | ); 344 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 345 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 346 | GCC_WARN_UNDECLARED_SELECTOR = YES; 347 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 348 | GCC_WARN_UNUSED_FUNCTION = YES; 349 | GCC_WARN_UNUSED_VARIABLE = YES; 350 | IPHONEOS_DEPLOYMENT_TARGET = 12.2; 351 | MTL_ENABLE_DEBUG_INFO = NO; 352 | MTL_FAST_MATH = YES; 353 | PRODUCT_NAME = "$(TARGET_NAME)"; 354 | STRIP_INSTALLED_PRODUCT = NO; 355 | SWIFT_COMPILATION_MODE = wholemodule; 356 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 357 | SWIFT_VERSION = 4.2; 358 | SYMROOT = "${SRCROOT}/../build"; 359 | }; 360 | name = Release; 361 | }; 362 | 881F70C6B35BFB1FBF346EAC5AB4FB40 /* Release */ = { 363 | isa = XCBuildConfiguration; 364 | baseConfigurationReference = CE5326E097499D5CD62B80F61067747F /* Pods-RangeControlExample.release.xcconfig */; 365 | buildSettings = { 366 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 367 | CLANG_ENABLE_OBJC_WEAK = NO; 368 | CODE_SIGN_IDENTITY = ""; 369 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 370 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 371 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 372 | CURRENT_PROJECT_VERSION = 1; 373 | DEFINES_MODULE = YES; 374 | DYLIB_COMPATIBILITY_VERSION = 1; 375 | DYLIB_CURRENT_VERSION = 1; 376 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 377 | INFOPLIST_FILE = "Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample-Info.plist"; 378 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 379 | IPHONEOS_DEPLOYMENT_TARGET = 12.2; 380 | LD_RUNPATH_SEARCH_PATHS = ( 381 | "$(inherited)", 382 | "@executable_path/Frameworks", 383 | "@loader_path/Frameworks", 384 | ); 385 | MACH_O_TYPE = staticlib; 386 | MODULEMAP_FILE = "Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample.modulemap"; 387 | OTHER_LDFLAGS = ""; 388 | OTHER_LIBTOOLFLAGS = ""; 389 | PODS_ROOT = "$(SRCROOT)"; 390 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 391 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 392 | SDKROOT = iphoneos; 393 | SKIP_INSTALL = YES; 394 | TARGETED_DEVICE_FAMILY = "1,2"; 395 | VALIDATE_PRODUCT = YES; 396 | VERSIONING_SYSTEM = "apple-generic"; 397 | VERSION_INFO_PREFIX = ""; 398 | }; 399 | name = Release; 400 | }; 401 | 8FE3339BA45A63A932490FDD954F5D05 /* Debug */ = { 402 | isa = XCBuildConfiguration; 403 | baseConfigurationReference = 7C7329CC52742AAD7C30EFBA3806A9A9 /* Pods-RangeControlExample.debug.xcconfig */; 404 | buildSettings = { 405 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 406 | CLANG_ENABLE_OBJC_WEAK = NO; 407 | CODE_SIGN_IDENTITY = ""; 408 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 409 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 410 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 411 | CURRENT_PROJECT_VERSION = 1; 412 | DEFINES_MODULE = YES; 413 | DYLIB_COMPATIBILITY_VERSION = 1; 414 | DYLIB_CURRENT_VERSION = 1; 415 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 416 | INFOPLIST_FILE = "Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample-Info.plist"; 417 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 418 | IPHONEOS_DEPLOYMENT_TARGET = 12.2; 419 | LD_RUNPATH_SEARCH_PATHS = ( 420 | "$(inherited)", 421 | "@executable_path/Frameworks", 422 | "@loader_path/Frameworks", 423 | ); 424 | MACH_O_TYPE = staticlib; 425 | MODULEMAP_FILE = "Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample.modulemap"; 426 | OTHER_LDFLAGS = ""; 427 | OTHER_LIBTOOLFLAGS = ""; 428 | PODS_ROOT = "$(SRCROOT)"; 429 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 430 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 431 | SDKROOT = iphoneos; 432 | SKIP_INSTALL = YES; 433 | TARGETED_DEVICE_FAMILY = "1,2"; 434 | VERSIONING_SYSTEM = "apple-generic"; 435 | VERSION_INFO_PREFIX = ""; 436 | }; 437 | name = Debug; 438 | }; 439 | 91831DF4E1C5B065586CE46670EAAF36 /* Release */ = { 440 | isa = XCBuildConfiguration; 441 | baseConfigurationReference = D4F01B56A0E6C27893A067223A1EA0E9 /* RangeControl.xcconfig */; 442 | buildSettings = { 443 | CLANG_ENABLE_OBJC_WEAK = NO; 444 | CODE_SIGN_IDENTITY = ""; 445 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 446 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 447 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 448 | CURRENT_PROJECT_VERSION = 1; 449 | DEFINES_MODULE = YES; 450 | DYLIB_COMPATIBILITY_VERSION = 1; 451 | DYLIB_CURRENT_VERSION = 1; 452 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 453 | GCC_PREFIX_HEADER = "Target Support Files/RangeControl/RangeControl-prefix.pch"; 454 | INFOPLIST_FILE = "Target Support Files/RangeControl/RangeControl-Info.plist"; 455 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 456 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 457 | LD_RUNPATH_SEARCH_PATHS = ( 458 | "$(inherited)", 459 | "@executable_path/Frameworks", 460 | "@loader_path/Frameworks", 461 | ); 462 | MODULEMAP_FILE = "Target Support Files/RangeControl/RangeControl.modulemap"; 463 | PRODUCT_MODULE_NAME = RangeControl; 464 | PRODUCT_NAME = RangeControl; 465 | SDKROOT = iphoneos; 466 | SKIP_INSTALL = YES; 467 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; 468 | SWIFT_VERSION = 4.2; 469 | TARGETED_DEVICE_FAMILY = "1,2"; 470 | VALIDATE_PRODUCT = YES; 471 | VERSIONING_SYSTEM = "apple-generic"; 472 | VERSION_INFO_PREFIX = ""; 473 | }; 474 | name = Release; 475 | }; 476 | BDAEC6F86D8E278C517C34E1B3690886 /* Debug */ = { 477 | isa = XCBuildConfiguration; 478 | baseConfigurationReference = D4F01B56A0E6C27893A067223A1EA0E9 /* RangeControl.xcconfig */; 479 | buildSettings = { 480 | CLANG_ENABLE_OBJC_WEAK = NO; 481 | CODE_SIGN_IDENTITY = ""; 482 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 483 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 484 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 485 | CURRENT_PROJECT_VERSION = 1; 486 | DEFINES_MODULE = YES; 487 | DYLIB_COMPATIBILITY_VERSION = 1; 488 | DYLIB_CURRENT_VERSION = 1; 489 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 490 | GCC_PREFIX_HEADER = "Target Support Files/RangeControl/RangeControl-prefix.pch"; 491 | INFOPLIST_FILE = "Target Support Files/RangeControl/RangeControl-Info.plist"; 492 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 493 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 494 | LD_RUNPATH_SEARCH_PATHS = ( 495 | "$(inherited)", 496 | "@executable_path/Frameworks", 497 | "@loader_path/Frameworks", 498 | ); 499 | MODULEMAP_FILE = "Target Support Files/RangeControl/RangeControl.modulemap"; 500 | PRODUCT_MODULE_NAME = RangeControl; 501 | PRODUCT_NAME = RangeControl; 502 | SDKROOT = iphoneos; 503 | SKIP_INSTALL = YES; 504 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; 505 | SWIFT_VERSION = 4.2; 506 | TARGETED_DEVICE_FAMILY = "1,2"; 507 | VERSIONING_SYSTEM = "apple-generic"; 508 | VERSION_INFO_PREFIX = ""; 509 | }; 510 | name = Debug; 511 | }; 512 | D0FE574C7B3479C6425BC136AA57D8C2 /* Debug */ = { 513 | isa = XCBuildConfiguration; 514 | buildSettings = { 515 | ALWAYS_SEARCH_USER_PATHS = NO; 516 | CLANG_ANALYZER_NONNULL = YES; 517 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 518 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 519 | CLANG_CXX_LIBRARY = "libc++"; 520 | CLANG_ENABLE_MODULES = YES; 521 | CLANG_ENABLE_OBJC_ARC = YES; 522 | CLANG_ENABLE_OBJC_WEAK = YES; 523 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 524 | CLANG_WARN_BOOL_CONVERSION = YES; 525 | CLANG_WARN_COMMA = YES; 526 | CLANG_WARN_CONSTANT_CONVERSION = YES; 527 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 528 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 529 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 530 | CLANG_WARN_EMPTY_BODY = YES; 531 | CLANG_WARN_ENUM_CONVERSION = YES; 532 | CLANG_WARN_INFINITE_RECURSION = YES; 533 | CLANG_WARN_INT_CONVERSION = YES; 534 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 535 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 536 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 537 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 538 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 539 | CLANG_WARN_STRICT_PROTOTYPES = YES; 540 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 541 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 542 | CLANG_WARN_UNREACHABLE_CODE = YES; 543 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 544 | COPY_PHASE_STRIP = NO; 545 | DEBUG_INFORMATION_FORMAT = dwarf; 546 | ENABLE_STRICT_OBJC_MSGSEND = YES; 547 | ENABLE_TESTABILITY = YES; 548 | GCC_C_LANGUAGE_STANDARD = gnu11; 549 | GCC_DYNAMIC_NO_PIC = NO; 550 | GCC_NO_COMMON_BLOCKS = YES; 551 | GCC_OPTIMIZATION_LEVEL = 0; 552 | GCC_PREPROCESSOR_DEFINITIONS = ( 553 | "POD_CONFIGURATION_DEBUG=1", 554 | "DEBUG=1", 555 | "$(inherited)", 556 | ); 557 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 558 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 559 | GCC_WARN_UNDECLARED_SELECTOR = YES; 560 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 561 | GCC_WARN_UNUSED_FUNCTION = YES; 562 | GCC_WARN_UNUSED_VARIABLE = YES; 563 | IPHONEOS_DEPLOYMENT_TARGET = 12.2; 564 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 565 | MTL_FAST_MATH = YES; 566 | ONLY_ACTIVE_ARCH = YES; 567 | PRODUCT_NAME = "$(TARGET_NAME)"; 568 | STRIP_INSTALLED_PRODUCT = NO; 569 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 570 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 571 | SWIFT_VERSION = 4.2; 572 | SYMROOT = "${SRCROOT}/../build"; 573 | }; 574 | name = Debug; 575 | }; 576 | /* End XCBuildConfiguration section */ 577 | 578 | /* Begin XCConfigurationList section */ 579 | 0CB9338E3CE7D2A340D957EE106C688C /* Build configuration list for PBXNativeTarget "RangeControl" */ = { 580 | isa = XCConfigurationList; 581 | buildConfigurations = ( 582 | BDAEC6F86D8E278C517C34E1B3690886 /* Debug */, 583 | 91831DF4E1C5B065586CE46670EAAF36 /* Release */, 584 | ); 585 | defaultConfigurationIsVisible = 0; 586 | defaultConfigurationName = Release; 587 | }; 588 | 1DF7769CAC3B791680F4FC2DB61AF155 /* Build configuration list for PBXNativeTarget "Pods-RangeControlExample" */ = { 589 | isa = XCConfigurationList; 590 | buildConfigurations = ( 591 | 8FE3339BA45A63A932490FDD954F5D05 /* Debug */, 592 | 881F70C6B35BFB1FBF346EAC5AB4FB40 /* Release */, 593 | ); 594 | defaultConfigurationIsVisible = 0; 595 | defaultConfigurationName = Release; 596 | }; 597 | 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { 598 | isa = XCConfigurationList; 599 | buildConfigurations = ( 600 | D0FE574C7B3479C6425BC136AA57D8C2 /* Debug */, 601 | 84A06F28E9E7D9EB0A9B476A8668FD60 /* Release */, 602 | ); 603 | defaultConfigurationIsVisible = 0; 604 | defaultConfigurationName = Release; 605 | }; 606 | /* End XCConfigurationList section */ 607 | }; 608 | rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */; 609 | } 610 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Pods.xcodeproj/xcuserdata/alexeyledovskiy.xcuserdatad/xcschemes/Pods-RangeControlExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Pods.xcodeproj/xcuserdata/alexeyledovskiy.xcuserdatad/xcschemes/RangeControl.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Pods.xcodeproj/xcuserdata/alexeyledovskiy.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Pods-RangeControlExample.xcscheme 8 | 9 | isShown 10 | 11 | orderHint 12 | 0 13 | 14 | RangeControl.xcscheme 15 | 16 | isShown 17 | 18 | orderHint 19 | 1 20 | 21 | 22 | SuppressBuildableAutocreation 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/RangeControl/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [2019] [Alexey Ledovskiy] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /RangeControlExample/Pods/RangeControl/RangeControl/RangeControl.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RangeControl.swift 3 | // Chart 4 | // 5 | // Created by Alexey Ledovskiy on 3/12/19. 6 | // Copyright © 2019 Alexey Ledovskiy. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import QuartzCore 11 | 12 | class RangeControlThumbLayer: CALayer { 13 | private let arrowHeight = CGFloat(36.0/128.0) 14 | private let arrowWidth = CGFloat(16.0/32.0) 15 | 16 | var isLeft = false 17 | var highlighted: Bool = false 18 | 19 | override func action(forKey event: String) -> CAAction? { 20 | if(event == "position"){ return nil } 21 | return super.action(forKey: event) 22 | } 23 | 24 | weak var rangeControl: RangeControl? 25 | override func draw(in ctx: CGContext) { 26 | if let slider = rangeControl { 27 | let thumbFrame = bounds 28 | let path = UIBezierPath(roundedRect: thumbFrame, cornerRadius: 2) 29 | ctx.addPath(path.cgPath) 30 | 31 | //Thumb 32 | ctx.setFillColor( slider.thumbColor.cgColor) 33 | ctx.addPath(path.cgPath) 34 | ctx.fillPath() 35 | 36 | //Arrows 37 | let arrow = UIBezierPath() 38 | let center = CGPoint(x: bounds.width/2.0, y: bounds.height/2.0) 39 | let arrowSize = CGSize(width: bounds.width * arrowWidth/1.5, height: bounds.height * arrowHeight) 40 | let arrowRect = CGRect(x: center.x - arrowSize.width/2, y: center.y - arrowSize.height/2, width: arrowSize.width, height: arrowSize.height) 41 | 42 | if(!isLeft){ 43 | arrow.move(to: arrowRect.origin) 44 | arrow.addLine(to: CGPoint(x: center.x + arrowSize.width/2.0, y: center.y)) 45 | arrow.move(to: CGPoint(x: center.x + arrowSize.width/2.0, y: center.y)) 46 | arrow.addLine(to: CGPoint(x: arrowRect.origin.x, y: arrowRect.origin.y + arrowRect.height)) 47 | }else{ 48 | arrow.move(to: CGPoint(x: arrowRect.origin.x + arrowSize.width, y: arrowRect.origin.y)) 49 | arrow.addLine(to: CGPoint(x: center.x - arrowSize.width/2.0, y: center.y)) 50 | arrow.move(to: CGPoint(x: center.x - arrowSize.width/2.0, y: center.y)) 51 | arrow.addLine(to: CGPoint(x: arrowRect.origin.x + arrowSize.width, y: arrowRect.origin.y + arrowRect.height)) 52 | } 53 | 54 | ctx.setLineWidth(2.5) 55 | ctx.setLineCap(.round) 56 | ctx.setStrokeColor(UIColor.white.cgColor) 57 | ctx.addPath(arrow.cgPath) 58 | ctx.strokePath() 59 | } 60 | } 61 | } 62 | 63 | class RangeControlTrackLayer: CALayer { 64 | weak var rangeControl: RangeControl? 65 | override func action(forKey event: String) -> CAAction? { 66 | if(event == "position" || event == "contents"){ return nil } 67 | return super.action(forKey: event) 68 | } 69 | 70 | override func draw(in ctx: CGContext) { 71 | if let slider = rangeControl { 72 | //Tack 73 | let rectTrack = CGRect(x: 0, y: slider.margin, width: bounds.width, height: bounds.height - slider.margin*2) 74 | let path = UIBezierPath(rect: rectTrack) 75 | 76 | let lowerValuePosition = CGFloat(slider.positionForValue(slider.lowValue)) 77 | let upperValuePosition = CGFloat(slider.positionForValue(slider.upValue)) 78 | //Cut rect 79 | let rect = CGRect(x: lowerValuePosition - slider.thumbWidth/2.0, y: slider.margin, width: upperValuePosition - lowerValuePosition + slider.thumbWidth, height: bounds.height - slider.margin*2 ) 80 | 81 | let cutout = UIBezierPath(rect: rect) 82 | path.append(cutout.reversing()) 83 | ctx.addPath(path.cgPath) 84 | 85 | // Fill the track 86 | ctx.setFillColor( slider.trackColor.cgColor) 87 | ctx.addPath(path.cgPath) 88 | ctx.fillPath() 89 | 90 | //Frame borders 91 | let border = CGRect(x: lowerValuePosition, y: 0, width: upperValuePosition - lowerValuePosition , height: bounds.height) 92 | let borderPath = UIBezierPath(rect: border) 93 | 94 | let borderCut = CGRect(x: lowerValuePosition, y: 1, width: upperValuePosition - lowerValuePosition , height: bounds.height-2) 95 | let borderCutPath = UIBezierPath(rect: borderCut) 96 | 97 | borderPath.append(borderCutPath.reversing()) 98 | ctx.setFillColor(slider.thumbColor.cgColor) 99 | ctx.addPath(borderPath.cgPath) 100 | ctx.fillPath() 101 | 102 | } 103 | } 104 | } 105 | 106 | public typealias OnRangeValueChanged = ((_ low:Float, _ up:Float)->Void) 107 | 108 | open class RangeControl: UIControl{ 109 | 110 | static let height = CGFloat(50.0) 111 | let margin = CGFloat(4.0) 112 | 113 | private let trackLayer = RangeControlTrackLayer() 114 | private let lowThumbLayer = RangeControlThumbLayer() 115 | private let upThumbLayer = RangeControlThumbLayer() 116 | public let backgroundView = UIStackView() 117 | private let contentView = UIView() 118 | 119 | private var previousLocation = CGPoint() 120 | 121 | open var minValue:Float = 0.0 { didSet { updateLayerFrames() } } 122 | open var maxValue:Float = 1.0 { didSet { updateLayerFrames() } } 123 | open var lowValue:Float = 0.8 { didSet { updateLayerFrames() } } 124 | open var upValue:Float = 1.0 { didSet { updateLayerFrames() } } 125 | open var onRangeValueChanged: OnRangeValueChanged? 126 | 127 | open var trackColor: UIColor = UIColor.lightGray.withAlphaComponent(0.45) { 128 | didSet { trackLayer.setNeedsDisplay() } 129 | } 130 | 131 | open var thumbColor: UIColor = UIColor.lightGray.withAlphaComponent(0.95) { 132 | didSet { 133 | lowThumbLayer.setNeedsDisplay() 134 | upThumbLayer.setNeedsDisplay() 135 | } 136 | } 137 | 138 | open var thumbWidth:CGFloat{ 139 | return CGFloat(bounds.height/4.0) 140 | } 141 | 142 | open var thumbHeight:CGFloat{ 143 | return CGFloat(bounds.height) 144 | } 145 | 146 | override open var frame: CGRect { didSet { updateLayerFrames() } } 147 | 148 | public override init(frame: CGRect) { 149 | super.init(frame: frame) 150 | setup() 151 | 152 | } 153 | 154 | public required init?(coder aDecoder: NSCoder) { 155 | super.init(coder: aDecoder) 156 | setup() 157 | } 158 | 159 | override open func layoutSubviews() { 160 | super.layoutSubviews() 161 | updateLayerFrames() 162 | } 163 | 164 | private func setup() { 165 | translatesAutoresizingMaskIntoConstraints = false 166 | backgroundView.translatesAutoresizingMaskIntoConstraints = false 167 | 168 | addSubview(backgroundView) 169 | backgroundView.isUserInteractionEnabled = false 170 | backgroundView.topAnchor.constraint(equalTo: self.topAnchor, constant: margin).isActive = true 171 | backgroundView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -margin).isActive = true 172 | backgroundView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0).isActive = true 173 | backgroundView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0).isActive = true 174 | setNeedsLayout() 175 | contentView.translatesAutoresizingMaskIntoConstraints = false 176 | addSubview(contentView) 177 | contentView.frame = bounds 178 | contentView.isUserInteractionEnabled = false 179 | contentView.backgroundColor = UIColor.clear 180 | contentView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true 181 | contentView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true 182 | contentView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true 183 | contentView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true 184 | 185 | 186 | trackLayer.isOpaque = false 187 | lowThumbLayer.isOpaque = false 188 | upThumbLayer.isOpaque = false 189 | 190 | 191 | lowThumbLayer.isLeft = true 192 | contentView.layer.addSublayer(trackLayer) 193 | contentView.layer.addSublayer(lowThumbLayer) 194 | contentView.layer.addSublayer(upThumbLayer) 195 | updateLayerFrames() 196 | lowThumbLayer.rangeControl = self 197 | upThumbLayer.rangeControl = self 198 | trackLayer.rangeControl = self 199 | 200 | trackLayer.contentsScale = UIScreen.main.scale 201 | lowThumbLayer.contentsScale = UIScreen.main.scale 202 | upThumbLayer.contentsScale = UIScreen.main.scale 203 | setNeedsDisplay() 204 | } 205 | 206 | open func updateLayerFrames() { 207 | if(minValue == Float.nan || lowValue == Float.nan || upValue == Float.nan || maxValue == Float.nan){ 208 | return 209 | } 210 | 211 | trackLayer.frame = bounds 212 | 213 | let lowThumbCenter = CGFloat(positionForValue(lowValue)) 214 | let upThumbCenter = CGFloat(positionForValue(upValue)) 215 | lowThumbLayer.frame = CGRect(x: lowThumbCenter - thumbWidth / 2.0, y: 0.0, width: thumbWidth, height: thumbHeight) 216 | upThumbLayer.frame = CGRect(x: upThumbCenter - thumbWidth / 2.0, y: 0.0, width: thumbWidth, height: thumbHeight) 217 | 218 | trackLayer.setNeedsDisplay() 219 | lowThumbLayer.setNeedsDisplay() 220 | upThumbLayer.setNeedsDisplay() 221 | onRangeValueChanged?(lowValue,upValue) 222 | } 223 | 224 | func positionForValue(_ value: Float) -> Float { 225 | return Float(bounds.width - thumbWidth) * (value - minValue) / 226 | (maxValue - minValue) + Float(thumbWidth / 2.0) 227 | } 228 | 229 | override open func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { 230 | previousLocation = touch.location(in: self) 231 | 232 | if lowThumbLayer.frame.contains(previousLocation) { 233 | lowThumbLayer.highlighted = true 234 | } else if upThumbLayer.frame.contains(previousLocation) { 235 | upThumbLayer.highlighted = true 236 | } else if (lowThumbLayer.frame.union(upThumbLayer.frame).contains(previousLocation)){ //between handles 237 | lowThumbLayer.highlighted = true 238 | upThumbLayer.highlighted = true 239 | } 240 | 241 | 242 | return lowThumbLayer.highlighted || upThumbLayer.highlighted 243 | } 244 | 245 | private func boundValue(_ value: Float, toLowerValue lowerValue: Float, upperValue: Float) -> Float { 246 | return Float.minimum(Float.maximum(value, lowerValue), upperValue) 247 | } 248 | 249 | override open func endTracking(_ touch: UITouch?, with event: UIEvent?) { 250 | lowThumbLayer.highlighted = false 251 | upThumbLayer.highlighted = false 252 | } 253 | 254 | 255 | override open func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { 256 | let location = touch.location(in: self) 257 | // 1. Determine by how much the user has dragged 258 | let deltaLocation = Float(location.x - previousLocation.x) 259 | let deltaValue = (maxValue - minValue) * deltaLocation / Float(bounds.width - thumbWidth) 260 | 261 | previousLocation = location 262 | 263 | // 2. Update the values 264 | if lowThumbLayer.highlighted { 265 | lowValue += deltaValue 266 | let lowValueTmp = boundValue(lowValue, toLowerValue: minValue, upperValue: upValue - 0.02) 267 | lowValue = Float.maximum(lowValueTmp, 0) 268 | } 269 | if upThumbLayer.highlighted { 270 | upValue += deltaValue 271 | let upValueTmp = boundValue(upValue, toLowerValue: lowValue + 0.02, upperValue: maxValue) 272 | upValue = Float.minimum(upValueTmp, 1.0) 273 | } 274 | 275 | // 3. Update the UI 276 | CATransaction.begin() 277 | CATransaction.setDisableActions(false) 278 | self.updateLayerFrames() 279 | CATransaction.commit() 280 | return super.continueTracking(touch, with: event) 281 | } 282 | } 283 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample-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.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## RangeControl 5 | 6 | MIT License 7 | 8 | Copyright (c) [2019] [Alexey Ledovskiy] 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | Generated by CocoaPods - https://cocoapods.org 28 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | MIT License 18 | 19 | Copyright (c) [2019] [Alexey Ledovskiy] 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | License 39 | MIT 40 | Title 41 | RangeControl 42 | Type 43 | PSGroupSpecifier 44 | 45 | 46 | FooterText 47 | Generated by CocoaPods - https://cocoapods.org 48 | Title 49 | 50 | Type 51 | PSGroupSpecifier 52 | 53 | 54 | StringsTable 55 | Acknowledgements 56 | Title 57 | Acknowledgements 58 | 59 | 60 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_RangeControlExample : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_RangeControlExample 5 | @end 6 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | function on_error { 7 | echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" 8 | } 9 | trap 'on_error $LINENO' ERR 10 | 11 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 12 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 13 | # frameworks to, so exit 0 (signalling the script phase was successful). 14 | exit 0 15 | fi 16 | 17 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 18 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 19 | 20 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 21 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 22 | 23 | # Used as a return value for each invocation of `strip_invalid_archs` function. 24 | STRIP_BINARY_RETVAL=0 25 | 26 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 27 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 28 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 29 | 30 | # Copies and strips a vendored framework 31 | install_framework() 32 | { 33 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 34 | local source="${BUILT_PRODUCTS_DIR}/$1" 35 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 36 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 37 | elif [ -r "$1" ]; then 38 | local source="$1" 39 | fi 40 | 41 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 42 | 43 | if [ -L "${source}" ]; then 44 | echo "Symlinked..." 45 | source="$(readlink "${source}")" 46 | fi 47 | 48 | # Use filter instead of exclude so missing patterns don't throw errors. 49 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 50 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 51 | 52 | local basename 53 | basename="$(basename -s .framework "$1")" 54 | binary="${destination}/${basename}.framework/${basename}" 55 | 56 | if ! [ -r "$binary" ]; then 57 | binary="${destination}/${basename}" 58 | elif [ -L "${binary}" ]; then 59 | echo "Destination binary is symlinked..." 60 | dirname="$(dirname "${binary}")" 61 | binary="${dirname}/$(readlink "${binary}")" 62 | fi 63 | 64 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 65 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 66 | strip_invalid_archs "$binary" 67 | fi 68 | 69 | # Resign the code if required by the build settings to avoid unstable apps 70 | code_sign_if_enabled "${destination}/$(basename "$1")" 71 | 72 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 73 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 74 | local swift_runtime_libs 75 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) 76 | for lib in $swift_runtime_libs; do 77 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 78 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 79 | code_sign_if_enabled "${destination}/${lib}" 80 | done 81 | fi 82 | } 83 | 84 | # Copies and strips a vendored dSYM 85 | install_dsym() { 86 | local source="$1" 87 | if [ -r "$source" ]; then 88 | # Copy the dSYM into a the targets temp dir. 89 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 90 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 91 | 92 | local basename 93 | basename="$(basename -s .framework.dSYM "$source")" 94 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" 95 | 96 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 97 | if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then 98 | strip_invalid_archs "$binary" 99 | fi 100 | 101 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then 102 | # Move the stripped file into its final destination. 103 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 104 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 105 | else 106 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 107 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" 108 | fi 109 | fi 110 | } 111 | 112 | # Signs a framework with the provided identity 113 | code_sign_if_enabled() { 114 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 115 | # Use the current code_sign_identity 116 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 117 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 118 | 119 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 120 | code_sign_cmd="$code_sign_cmd &" 121 | fi 122 | echo "$code_sign_cmd" 123 | eval "$code_sign_cmd" 124 | fi 125 | } 126 | 127 | # Strip invalid architectures 128 | strip_invalid_archs() { 129 | binary="$1" 130 | # Get architectures for current target binary 131 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 132 | # Intersect them with the architectures we are building for 133 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 134 | # If there are no archs supported by this binary then warn the user 135 | if [[ -z "$intersected_archs" ]]; then 136 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 137 | STRIP_BINARY_RETVAL=0 138 | return 139 | fi 140 | stripped="" 141 | for arch in $binary_archs; do 142 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 143 | # Strip non-valid architectures in-place 144 | lipo -remove "$arch" -output "$binary" "$binary" 145 | stripped="$stripped $arch" 146 | fi 147 | done 148 | if [[ "$stripped" ]]; then 149 | echo "Stripped $binary of architectures:$stripped" 150 | fi 151 | STRIP_BINARY_RETVAL=1 152 | } 153 | 154 | 155 | if [[ "$CONFIGURATION" == "Debug" ]]; then 156 | install_framework "${BUILT_PRODUCTS_DIR}/RangeControl/RangeControl.framework" 157 | fi 158 | if [[ "$CONFIGURATION" == "Release" ]]; then 159 | install_framework "${BUILT_PRODUCTS_DIR}/RangeControl/RangeControl.framework" 160 | fi 161 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 162 | wait 163 | fi 164 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_RangeControlExampleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_RangeControlExampleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/RangeControl" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/RangeControl/RangeControl.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "RangeControl" -framework "UIKit" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_RangeControlExample { 2 | umbrella header "Pods-RangeControlExample-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/RangeControl" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/RangeControl/RangeControl.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "RangeControl" -framework "UIKit" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Target Support Files/RangeControl/RangeControl-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 | 0.0.3 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Target Support Files/RangeControl/RangeControl-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_RangeControl : NSObject 3 | @end 4 | @implementation PodsDummy_RangeControl 5 | @end 6 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Target Support Files/RangeControl/RangeControl-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Target Support Files/RangeControl/RangeControl-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double RangeControlVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char RangeControlVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Target Support Files/RangeControl/RangeControl.modulemap: -------------------------------------------------------------------------------- 1 | framework module RangeControl { 2 | umbrella header "RangeControl-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /RangeControlExample/Pods/Target Support Files/RangeControl/RangeControl.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/RangeControl 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_LDFLAGS = $(inherited) -framework "UIKit" 4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/RangeControl 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 51; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 41AEA4F9224E99C6006D747E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 41AEA4F8224E99C6006D747E /* Assets.xcassets */; }; 11 | 41FBE962224DEF0C00C6AD7E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41FBE961224DEF0C00C6AD7E /* AppDelegate.swift */; }; 12 | 41FBE964224DEF0C00C6AD7E /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41FBE963224DEF0C00C6AD7E /* ViewController.swift */; }; 13 | 41FBE967224DEF0C00C6AD7E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 41FBE965224DEF0C00C6AD7E /* Main.storyboard */; }; 14 | 41FBE96C224DEF0D00C6AD7E /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 41FBE96A224DEF0D00C6AD7E /* LaunchScreen.storyboard */; }; 15 | 8F3920A94F12480E75C7EA30 /* Pods_RangeControlExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0F9B92E9CA157EFC50D23628 /* Pods_RangeControlExample.framework */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | 0F9B92E9CA157EFC50D23628 /* Pods_RangeControlExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RangeControlExample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 20 | 310C8476A2737515F9AD37CC /* Pods-RangeControlExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RangeControlExample.release.xcconfig"; path = "Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample.release.xcconfig"; sourceTree = ""; }; 21 | 41AEA4F8224E99C6006D747E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 22 | 41FBE95E224DEF0C00C6AD7E /* RangeControlExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RangeControlExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 23 | 41FBE961224DEF0C00C6AD7E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 24 | 41FBE963224DEF0C00C6AD7E /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 25 | 41FBE966224DEF0C00C6AD7E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 26 | 41FBE96B224DEF0D00C6AD7E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 27 | 41FBE96D224DEF0D00C6AD7E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 28 | 4A040825DD5055E023E192D6 /* Pods-RangeControlExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RangeControlExample.debug.xcconfig"; path = "Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample.debug.xcconfig"; sourceTree = ""; }; 29 | 66D75BB941DC591CCEE6B499 /* Pods-tvOSExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-tvOSExample.release.xcconfig"; path = "Target Support Files/Pods-tvOSExample/Pods-tvOSExample.release.xcconfig"; sourceTree = ""; }; 30 | C3A5F45D780B190C1185FA67 /* Pods_tvOSExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_tvOSExample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | D27EA652ED334CA3D86D9E57 /* Pods-tvOSExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-tvOSExample.debug.xcconfig"; path = "Target Support Files/Pods-tvOSExample/Pods-tvOSExample.debug.xcconfig"; sourceTree = ""; }; 32 | /* End PBXFileReference section */ 33 | 34 | /* Begin PBXFrameworksBuildPhase section */ 35 | 41FBE95B224DEF0C00C6AD7E /* Frameworks */ = { 36 | isa = PBXFrameworksBuildPhase; 37 | buildActionMask = 2147483647; 38 | files = ( 39 | 8F3920A94F12480E75C7EA30 /* Pods_RangeControlExample.framework in Frameworks */, 40 | ); 41 | runOnlyForDeploymentPostprocessing = 0; 42 | }; 43 | /* End PBXFrameworksBuildPhase section */ 44 | 45 | /* Begin PBXGroup section */ 46 | 0E1D3DBC39DAC2982DD0D766 /* Pods */ = { 47 | isa = PBXGroup; 48 | children = ( 49 | 4A040825DD5055E023E192D6 /* Pods-RangeControlExample.debug.xcconfig */, 50 | 310C8476A2737515F9AD37CC /* Pods-RangeControlExample.release.xcconfig */, 51 | D27EA652ED334CA3D86D9E57 /* Pods-tvOSExample.debug.xcconfig */, 52 | 66D75BB941DC591CCEE6B499 /* Pods-tvOSExample.release.xcconfig */, 53 | ); 54 | path = Pods; 55 | sourceTree = ""; 56 | }; 57 | 369FCF2E97D506B177B38F9A /* Frameworks */ = { 58 | isa = PBXGroup; 59 | children = ( 60 | 0F9B92E9CA157EFC50D23628 /* Pods_RangeControlExample.framework */, 61 | C3A5F45D780B190C1185FA67 /* Pods_tvOSExample.framework */, 62 | ); 63 | name = Frameworks; 64 | sourceTree = ""; 65 | }; 66 | 41FBE955224DEF0C00C6AD7E = { 67 | isa = PBXGroup; 68 | children = ( 69 | 41FBE960224DEF0C00C6AD7E /* RangeControlExample */, 70 | 41FBE95F224DEF0C00C6AD7E /* Products */, 71 | 0E1D3DBC39DAC2982DD0D766 /* Pods */, 72 | 369FCF2E97D506B177B38F9A /* Frameworks */, 73 | ); 74 | sourceTree = ""; 75 | }; 76 | 41FBE95F224DEF0C00C6AD7E /* Products */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 41FBE95E224DEF0C00C6AD7E /* RangeControlExample.app */, 80 | ); 81 | name = Products; 82 | sourceTree = ""; 83 | }; 84 | 41FBE960224DEF0C00C6AD7E /* RangeControlExample */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 41FBE961224DEF0C00C6AD7E /* AppDelegate.swift */, 88 | 41FBE963224DEF0C00C6AD7E /* ViewController.swift */, 89 | 41AEA4F8224E99C6006D747E /* Assets.xcassets */, 90 | 41FBE965224DEF0C00C6AD7E /* Main.storyboard */, 91 | 41FBE96A224DEF0D00C6AD7E /* LaunchScreen.storyboard */, 92 | 41FBE96D224DEF0D00C6AD7E /* Info.plist */, 93 | ); 94 | path = RangeControlExample; 95 | sourceTree = ""; 96 | }; 97 | /* End PBXGroup section */ 98 | 99 | /* Begin PBXNativeTarget section */ 100 | 41FBE95D224DEF0C00C6AD7E /* RangeControlExample */ = { 101 | isa = PBXNativeTarget; 102 | buildConfigurationList = 41FBE970224DEF0D00C6AD7E /* Build configuration list for PBXNativeTarget "RangeControlExample" */; 103 | buildPhases = ( 104 | 2BBACB9594107BE236E8A6DC /* [CP] Check Pods Manifest.lock */, 105 | 41FBE95A224DEF0C00C6AD7E /* Sources */, 106 | 41FBE95B224DEF0C00C6AD7E /* Frameworks */, 107 | 41FBE95C224DEF0C00C6AD7E /* Resources */, 108 | D4F056E145647796FEF84B39 /* [CP] Embed Pods Frameworks */, 109 | ); 110 | buildRules = ( 111 | ); 112 | dependencies = ( 113 | ); 114 | name = RangeControlExample; 115 | productName = RangeControlExample; 116 | productReference = 41FBE95E224DEF0C00C6AD7E /* RangeControlExample.app */; 117 | productType = "com.apple.product-type.application"; 118 | }; 119 | /* End PBXNativeTarget section */ 120 | 121 | /* Begin PBXProject section */ 122 | 41FBE956224DEF0C00C6AD7E /* Project object */ = { 123 | isa = PBXProject; 124 | attributes = { 125 | LastSwiftUpdateCheck = 1020; 126 | LastUpgradeCheck = 1240; 127 | ORGANIZATIONNAME = "Alexey Ledovskiy"; 128 | TargetAttributes = { 129 | 41FBE95D224DEF0C00C6AD7E = { 130 | CreatedOnToolsVersion = 10.2; 131 | }; 132 | }; 133 | }; 134 | buildConfigurationList = 41FBE959224DEF0C00C6AD7E /* Build configuration list for PBXProject "RangeControlExample" */; 135 | compatibilityVersion = "Xcode 9.3"; 136 | developmentRegion = en; 137 | hasScannedForEncodings = 0; 138 | knownRegions = ( 139 | en, 140 | Base, 141 | ); 142 | mainGroup = 41FBE955224DEF0C00C6AD7E; 143 | productRefGroup = 41FBE95F224DEF0C00C6AD7E /* Products */; 144 | projectDirPath = ""; 145 | projectRoot = ""; 146 | targets = ( 147 | 41FBE95D224DEF0C00C6AD7E /* RangeControlExample */, 148 | ); 149 | }; 150 | /* End PBXProject section */ 151 | 152 | /* Begin PBXResourcesBuildPhase section */ 153 | 41FBE95C224DEF0C00C6AD7E /* Resources */ = { 154 | isa = PBXResourcesBuildPhase; 155 | buildActionMask = 2147483647; 156 | files = ( 157 | 41FBE96C224DEF0D00C6AD7E /* LaunchScreen.storyboard in Resources */, 158 | 41AEA4F9224E99C6006D747E /* Assets.xcassets in Resources */, 159 | 41FBE967224DEF0C00C6AD7E /* Main.storyboard in Resources */, 160 | ); 161 | runOnlyForDeploymentPostprocessing = 0; 162 | }; 163 | /* End PBXResourcesBuildPhase section */ 164 | 165 | /* Begin PBXShellScriptBuildPhase section */ 166 | 2BBACB9594107BE236E8A6DC /* [CP] Check Pods Manifest.lock */ = { 167 | isa = PBXShellScriptBuildPhase; 168 | buildActionMask = 2147483647; 169 | files = ( 170 | ); 171 | inputFileListPaths = ( 172 | ); 173 | inputPaths = ( 174 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 175 | "${PODS_ROOT}/Manifest.lock", 176 | ); 177 | name = "[CP] Check Pods Manifest.lock"; 178 | outputFileListPaths = ( 179 | ); 180 | outputPaths = ( 181 | "$(DERIVED_FILE_DIR)/Pods-RangeControlExample-checkManifestLockResult.txt", 182 | ); 183 | runOnlyForDeploymentPostprocessing = 0; 184 | shellPath = /bin/sh; 185 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 186 | showEnvVarsInLog = 0; 187 | }; 188 | D4F056E145647796FEF84B39 /* [CP] Embed Pods Frameworks */ = { 189 | isa = PBXShellScriptBuildPhase; 190 | buildActionMask = 2147483647; 191 | files = ( 192 | ); 193 | inputFileListPaths = ( 194 | "${PODS_ROOT}/Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", 195 | ); 196 | name = "[CP] Embed Pods Frameworks"; 197 | outputFileListPaths = ( 198 | "${PODS_ROOT}/Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", 199 | ); 200 | runOnlyForDeploymentPostprocessing = 0; 201 | shellPath = /bin/sh; 202 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RangeControlExample/Pods-RangeControlExample-frameworks.sh\"\n"; 203 | showEnvVarsInLog = 0; 204 | }; 205 | /* End PBXShellScriptBuildPhase section */ 206 | 207 | /* Begin PBXSourcesBuildPhase section */ 208 | 41FBE95A224DEF0C00C6AD7E /* Sources */ = { 209 | isa = PBXSourcesBuildPhase; 210 | buildActionMask = 2147483647; 211 | files = ( 212 | 41FBE964224DEF0C00C6AD7E /* ViewController.swift in Sources */, 213 | 41FBE962224DEF0C00C6AD7E /* AppDelegate.swift in Sources */, 214 | ); 215 | runOnlyForDeploymentPostprocessing = 0; 216 | }; 217 | /* End PBXSourcesBuildPhase section */ 218 | 219 | /* Begin PBXVariantGroup section */ 220 | 41FBE965224DEF0C00C6AD7E /* Main.storyboard */ = { 221 | isa = PBXVariantGroup; 222 | children = ( 223 | 41FBE966224DEF0C00C6AD7E /* Base */, 224 | ); 225 | name = Main.storyboard; 226 | sourceTree = ""; 227 | }; 228 | 41FBE96A224DEF0D00C6AD7E /* LaunchScreen.storyboard */ = { 229 | isa = PBXVariantGroup; 230 | children = ( 231 | 41FBE96B224DEF0D00C6AD7E /* Base */, 232 | ); 233 | name = LaunchScreen.storyboard; 234 | sourceTree = ""; 235 | }; 236 | /* End PBXVariantGroup section */ 237 | 238 | /* Begin XCBuildConfiguration section */ 239 | 41FBE96E224DEF0D00C6AD7E /* Debug */ = { 240 | isa = XCBuildConfiguration; 241 | buildSettings = { 242 | ALWAYS_SEARCH_USER_PATHS = NO; 243 | CLANG_ANALYZER_NONNULL = YES; 244 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 245 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 246 | CLANG_CXX_LIBRARY = "libc++"; 247 | CLANG_ENABLE_MODULES = YES; 248 | CLANG_ENABLE_OBJC_ARC = YES; 249 | CLANG_ENABLE_OBJC_WEAK = YES; 250 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 251 | CLANG_WARN_BOOL_CONVERSION = YES; 252 | CLANG_WARN_COMMA = YES; 253 | CLANG_WARN_CONSTANT_CONVERSION = YES; 254 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 255 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 256 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 257 | CLANG_WARN_EMPTY_BODY = YES; 258 | CLANG_WARN_ENUM_CONVERSION = YES; 259 | CLANG_WARN_INFINITE_RECURSION = YES; 260 | CLANG_WARN_INT_CONVERSION = YES; 261 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 262 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 263 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 264 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 265 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 266 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 267 | CLANG_WARN_STRICT_PROTOTYPES = YES; 268 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 269 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 270 | CLANG_WARN_UNREACHABLE_CODE = YES; 271 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 272 | CODE_SIGN_IDENTITY = "iPhone Developer"; 273 | COPY_PHASE_STRIP = NO; 274 | DEBUG_INFORMATION_FORMAT = dwarf; 275 | ENABLE_STRICT_OBJC_MSGSEND = YES; 276 | ENABLE_TESTABILITY = YES; 277 | GCC_C_LANGUAGE_STANDARD = gnu11; 278 | GCC_DYNAMIC_NO_PIC = NO; 279 | GCC_NO_COMMON_BLOCKS = YES; 280 | GCC_OPTIMIZATION_LEVEL = 0; 281 | GCC_PREPROCESSOR_DEFINITIONS = ( 282 | "DEBUG=1", 283 | "$(inherited)", 284 | ); 285 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 286 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 287 | GCC_WARN_UNDECLARED_SELECTOR = YES; 288 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 289 | GCC_WARN_UNUSED_FUNCTION = YES; 290 | GCC_WARN_UNUSED_VARIABLE = YES; 291 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 292 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 293 | MTL_FAST_MATH = YES; 294 | ONLY_ACTIVE_ARCH = YES; 295 | SDKROOT = iphoneos; 296 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 297 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 298 | }; 299 | name = Debug; 300 | }; 301 | 41FBE96F224DEF0D00C6AD7E /* Release */ = { 302 | isa = XCBuildConfiguration; 303 | buildSettings = { 304 | ALWAYS_SEARCH_USER_PATHS = NO; 305 | CLANG_ANALYZER_NONNULL = YES; 306 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 307 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 308 | CLANG_CXX_LIBRARY = "libc++"; 309 | CLANG_ENABLE_MODULES = YES; 310 | CLANG_ENABLE_OBJC_ARC = YES; 311 | CLANG_ENABLE_OBJC_WEAK = YES; 312 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 313 | CLANG_WARN_BOOL_CONVERSION = YES; 314 | CLANG_WARN_COMMA = YES; 315 | CLANG_WARN_CONSTANT_CONVERSION = YES; 316 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 317 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 318 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 319 | CLANG_WARN_EMPTY_BODY = YES; 320 | CLANG_WARN_ENUM_CONVERSION = YES; 321 | CLANG_WARN_INFINITE_RECURSION = YES; 322 | CLANG_WARN_INT_CONVERSION = YES; 323 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 324 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 325 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 326 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 327 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 328 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 329 | CLANG_WARN_STRICT_PROTOTYPES = YES; 330 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 331 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 332 | CLANG_WARN_UNREACHABLE_CODE = YES; 333 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 334 | CODE_SIGN_IDENTITY = "iPhone Developer"; 335 | COPY_PHASE_STRIP = NO; 336 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 337 | ENABLE_NS_ASSERTIONS = NO; 338 | ENABLE_STRICT_OBJC_MSGSEND = YES; 339 | GCC_C_LANGUAGE_STANDARD = gnu11; 340 | GCC_NO_COMMON_BLOCKS = YES; 341 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 342 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 343 | GCC_WARN_UNDECLARED_SELECTOR = YES; 344 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 345 | GCC_WARN_UNUSED_FUNCTION = YES; 346 | GCC_WARN_UNUSED_VARIABLE = YES; 347 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 348 | MTL_ENABLE_DEBUG_INFO = NO; 349 | MTL_FAST_MATH = YES; 350 | SDKROOT = iphoneos; 351 | SWIFT_COMPILATION_MODE = wholemodule; 352 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 353 | VALIDATE_PRODUCT = YES; 354 | }; 355 | name = Release; 356 | }; 357 | 41FBE971224DEF0D00C6AD7E /* Debug */ = { 358 | isa = XCBuildConfiguration; 359 | baseConfigurationReference = 4A040825DD5055E023E192D6 /* Pods-RangeControlExample.debug.xcconfig */; 360 | buildSettings = { 361 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 362 | CODE_SIGN_STYLE = Automatic; 363 | DEVELOPMENT_TEAM = PS9F2MA7E5; 364 | INFOPLIST_FILE = RangeControlExample/Info.plist; 365 | IPHONEOS_DEPLOYMENT_TARGET = 10; 366 | LD_RUNPATH_SEARCH_PATHS = ( 367 | "$(inherited)", 368 | "@executable_path/Frameworks", 369 | ); 370 | PRODUCT_BUNDLE_IDENTIFIER = com.ledovskiy.RangeControlExample; 371 | PRODUCT_NAME = "$(TARGET_NAME)"; 372 | SWIFT_VERSION = 5.0; 373 | TARGETED_DEVICE_FAMILY = "1,2"; 374 | }; 375 | name = Debug; 376 | }; 377 | 41FBE972224DEF0D00C6AD7E /* Release */ = { 378 | isa = XCBuildConfiguration; 379 | baseConfigurationReference = 310C8476A2737515F9AD37CC /* Pods-RangeControlExample.release.xcconfig */; 380 | buildSettings = { 381 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 382 | CODE_SIGN_STYLE = Automatic; 383 | DEVELOPMENT_TEAM = PS9F2MA7E5; 384 | INFOPLIST_FILE = RangeControlExample/Info.plist; 385 | IPHONEOS_DEPLOYMENT_TARGET = 10; 386 | LD_RUNPATH_SEARCH_PATHS = ( 387 | "$(inherited)", 388 | "@executable_path/Frameworks", 389 | ); 390 | PRODUCT_BUNDLE_IDENTIFIER = com.ledovskiy.RangeControlExample; 391 | PRODUCT_NAME = "$(TARGET_NAME)"; 392 | SWIFT_VERSION = 5.0; 393 | TARGETED_DEVICE_FAMILY = "1,2"; 394 | }; 395 | name = Release; 396 | }; 397 | /* End XCBuildConfiguration section */ 398 | 399 | /* Begin XCConfigurationList section */ 400 | 41FBE959224DEF0C00C6AD7E /* Build configuration list for PBXProject "RangeControlExample" */ = { 401 | isa = XCConfigurationList; 402 | buildConfigurations = ( 403 | 41FBE96E224DEF0D00C6AD7E /* Debug */, 404 | 41FBE96F224DEF0D00C6AD7E /* Release */, 405 | ); 406 | defaultConfigurationIsVisible = 0; 407 | defaultConfigurationName = Release; 408 | }; 409 | 41FBE970224DEF0D00C6AD7E /* Build configuration list for PBXNativeTarget "RangeControlExample" */ = { 410 | isa = XCConfigurationList; 411 | buildConfigurations = ( 412 | 41FBE971224DEF0D00C6AD7E /* Debug */, 413 | 41FBE972224DEF0D00C6AD7E /* Release */, 414 | ); 415 | defaultConfigurationIsVisible = 0; 416 | defaultConfigurationName = Release; 417 | }; 418 | /* End XCConfigurationList section */ 419 | }; 420 | rootObject = 41FBE956224DEF0C00C6AD7E /* Project object */; 421 | } 422 | -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample.xcodeproj/project.xcworkspace/xcuserdata/alexeyledovskiy.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexeyIS/RangeControl/44c80cb49a3e258bfa4987daf2df57d20736c4b1/RangeControlExample/RangeControlExample.xcodeproj/project.xcworkspace/xcuserdata/alexeyledovskiy.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample.xcodeproj/xcuserdata/alexeyledovskiy.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | RangeControlExample.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 2 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample.xcworkspace/xcuserdata/alexeyledovskiy.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexeyIS/RangeControl/44c80cb49a3e258bfa4987daf2df57d20736c4b1/RangeControlExample/RangeControlExample.xcworkspace/xcuserdata/alexeyledovskiy.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // RangeControlExample 4 | // 5 | // Created by Alexey Ledovskiy on 3/28/19. 6 | // Copyright © 2019 Alexey Ledovskiy. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // 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. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // 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. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // 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. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample/Assets.xcassets/testImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "milky-way-starry-sky-night-sky-star-956983.jpeg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "milky-way-starry-sky-night-sky-star-956982.jpeg", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "milky-way-starry-sky-night-sky-star-956981.jpeg", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample/Assets.xcassets/testImage.imageset/milky-way-starry-sky-night-sky-star-956981.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexeyIS/RangeControl/44c80cb49a3e258bfa4987daf2df57d20736c4b1/RangeControlExample/RangeControlExample/Assets.xcassets/testImage.imageset/milky-way-starry-sky-night-sky-star-956981.jpeg -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample/Assets.xcassets/testImage.imageset/milky-way-starry-sky-night-sky-star-956982.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexeyIS/RangeControl/44c80cb49a3e258bfa4987daf2df57d20736c4b1/RangeControlExample/RangeControlExample/Assets.xcassets/testImage.imageset/milky-way-starry-sky-night-sky-star-956982.jpeg -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample/Assets.xcassets/testImage.imageset/milky-way-starry-sky-night-sky-star-956983.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexeyIS/RangeControl/44c80cb49a3e258bfa4987daf2df57d20736c4b1/RangeControlExample/RangeControlExample/Assets.xcassets/testImage.imageset/milky-way-starry-sky-night-sky-star-956983.jpeg -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 37 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /RangeControlExample/RangeControlExample/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // RangeControlExample 4 | // 5 | // Created by Alexey Ledovskiy on 3/28/19. 6 | // Copyright © 2019 Alexey Ledovskiy. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import RangeControl 11 | 12 | class ViewController: UIViewController { 13 | @IBOutlet weak var lowLabel: UILabel! 14 | @IBOutlet weak var upLabel: UILabel! 15 | 16 | @IBOutlet weak var rangeControl: RangeControl! 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | // Do any additional setup after loading the view. 20 | let imageView = UIImageView(image: UIImage(named: "testImage")) 21 | imageView.contentMode = .scaleAspectFill 22 | imageView.translatesAutoresizingMaskIntoConstraints = false 23 | imageView.clipsToBounds = true 24 | rangeControl.backgroundView.addArrangedSubview(imageView) 25 | lowLabel.text = rangeControl.lowValue.description 26 | upLabel.text = rangeControl.upValue.description 27 | rangeControl.onRangeValueChanged = { (low,up) in 28 | self.lowLabel.text = low.description 29 | self.upLabel.text = up.description 30 | print("Low: \(low) up: \(up)") 31 | } 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /UITest/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /UITest/UITest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UITest.swift 3 | // UITest 4 | // 5 | // Created by Alexey Ledovskiy on 3/13/21. 6 | // Copyright © 2021 Alexey Ledovskiy. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class UITest: XCTestCase { 12 | 13 | override func setUpWithError() throws { 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | 16 | // In UI tests it is usually best to stop immediately when a failure occurs. 17 | continueAfterFailure = false 18 | 19 | // 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. 20 | } 21 | 22 | override func tearDownWithError() throws { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | } 25 | 26 | func testExample() throws { 27 | // UI tests must launch the application that they test. 28 | let app = XCUIApplication() 29 | app.launch() 30 | 31 | // Use recording to get started writing UI tests. 32 | // Use XCTAssert and related functions to verify your tests produce the correct results. 33 | } 34 | 35 | func testLaunchPerformance() throws { 36 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, *) { 37 | // This measures how long it takes to launch your application. 38 | measure(metrics: [XCTApplicationLaunchMetric()]) { 39 | XCUIApplication().launch() 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexeyIS/RangeControl/44c80cb49a3e258bfa4987daf2df57d20736c4b1/screenshot1.png -------------------------------------------------------------------------------- /screenshot2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexeyIS/RangeControl/44c80cb49a3e258bfa4987daf2df57d20736c4b1/screenshot2.gif -------------------------------------------------------------------------------- /screenshot3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexeyIS/RangeControl/44c80cb49a3e258bfa4987daf2df57d20736c4b1/screenshot3.gif --------------------------------------------------------------------------------