├── .swift-version ├── screenshot.png ├── docs ├── img │ ├── gh.png │ ├── carat.png │ └── dash.png ├── screenshot.png ├── docsets │ ├── NHRangeSlider.tgz │ └── NHRangeSlider.docset │ │ └── Contents │ │ ├── Resources │ │ ├── docSet.dsidx │ │ └── Documents │ │ │ ├── img │ │ │ ├── gh.png │ │ │ ├── carat.png │ │ │ └── dash.png │ │ │ ├── screenshot.png │ │ │ ├── js │ │ │ └── jazzy.js │ │ │ ├── undocumented.json │ │ │ ├── Enums.html │ │ │ ├── Protocols.html │ │ │ ├── css │ │ │ ├── highlight.css │ │ │ └── jazzy.css │ │ │ ├── Protocols │ │ │ └── NHRangeSliderViewDelegate.html │ │ │ ├── Classes │ │ │ ├── RangeSliderTrackLayer.html │ │ │ └── RangeSliderThumbLayer.html │ │ │ ├── Enums │ │ │ └── NHSliderLabelStyle.html │ │ │ └── Classes.html │ │ └── Info.plist ├── js │ └── jazzy.js ├── undocumented.json ├── Enums.html ├── Protocols.html ├── css │ ├── highlight.css │ └── jazzy.css ├── Protocols │ └── NHRangeSliderViewDelegate.html ├── Classes │ ├── RangeSliderTrackLayer.html │ └── RangeSliderThumbLayer.html ├── Enums │ └── NHSliderLabelStyle.html └── Classes.html ├── NHRangeSlider ├── NHRangeSlider.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── visenze.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ ├── xcuserdata │ │ └── visenze.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── NHRangeSlider.xcscheme │ └── project.pbxproj ├── NHRangeSlider │ ├── NHRangeSlider.h │ ├── Info.plist │ ├── NHRangeSliderView.swift │ └── NHRangeSlider.swift └── NHRangeSliderTests │ ├── Info.plist │ └── NHRangeSliderTests.swift ├── SliderExample ├── SliderExample.xcodeproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── SliderExampleTests │ ├── Info.plist │ └── SliderExampleTests.swift └── SliderExample │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Info.plist │ ├── Base.lproj │ ├── Main.storyboard │ └── LaunchScreen.storyboard │ ├── AppDelegate.swift │ └── ViewController.swift ├── LICENSE ├── .gitignore ├── NHRangeSlider.podspec └── README.md /.swift-version: -------------------------------------------------------------------------------- 1 | 3.0 -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thehung111/NHRangeSlider/HEAD/screenshot.png -------------------------------------------------------------------------------- /docs/img/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thehung111/NHRangeSlider/HEAD/docs/img/gh.png -------------------------------------------------------------------------------- /docs/img/carat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thehung111/NHRangeSlider/HEAD/docs/img/carat.png -------------------------------------------------------------------------------- /docs/img/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thehung111/NHRangeSlider/HEAD/docs/img/dash.png -------------------------------------------------------------------------------- /docs/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thehung111/NHRangeSlider/HEAD/docs/screenshot.png -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thehung111/NHRangeSlider/HEAD/docs/docsets/NHRangeSlider.tgz -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.docset/Contents/Resources/docSet.dsidx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thehung111/NHRangeSlider/HEAD/docs/docsets/NHRangeSlider.docset/Contents/Resources/docSet.dsidx -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/img/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thehung111/NHRangeSlider/HEAD/docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/img/gh.png -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/img/carat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thehung111/NHRangeSlider/HEAD/docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/img/carat.png -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/img/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thehung111/NHRangeSlider/HEAD/docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/img/dash.png -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thehung111/NHRangeSlider/HEAD/docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/screenshot.png -------------------------------------------------------------------------------- /NHRangeSlider/NHRangeSlider.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SliderExample/SliderExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /NHRangeSlider/NHRangeSlider.xcodeproj/project.xcworkspace/xcuserdata/visenze.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thehung111/NHRangeSlider/HEAD/NHRangeSlider/NHRangeSlider.xcodeproj/project.xcworkspace/xcuserdata/visenze.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /NHRangeSlider/NHRangeSlider/NHRangeSlider.h: -------------------------------------------------------------------------------- 1 | // 2 | // NHRangeSlider.h 3 | // NHRangeSlider 4 | // 5 | // Created by Hung on 18/12/16. 6 | // Copyright © 2016 Hung. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for NHRangeSlider. 12 | FOUNDATION_EXPORT double NHRangeSliderVersionNumber; 13 | 14 | //! Project version string for NHRangeSlider. 15 | FOUNDATION_EXPORT const unsigned char NHRangeSliderVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.docset/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIdentifier 6 | com.jazzy.nhrangeslider 7 | CFBundleName 8 | NHRangeSlider 9 | DocSetPlatformFamily 10 | nhrangeslider 11 | isDashDocset 12 | 13 | dashIndexFilePath 14 | index.html 15 | isJavaScriptEnabled 16 | 17 | DashDocSetFamily 18 | dashtoc 19 | 20 | 21 | -------------------------------------------------------------------------------- /NHRangeSlider/NHRangeSlider.xcodeproj/xcuserdata/visenze.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | NHRangeSlider.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | BDBEB3841E06606100FE2D6F 16 | 17 | primary 18 | 19 | 20 | BDBEB38D1E06606100FE2D6F 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /NHRangeSlider/NHRangeSliderTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /SliderExample/SliderExampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /SliderExample/SliderExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /NHRangeSlider/NHRangeSlider/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.2 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 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. 22 | -------------------------------------------------------------------------------- /NHRangeSlider/NHRangeSliderTests/NHRangeSliderTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NHRangeSliderTests.swift 3 | // NHRangeSliderTests 4 | // 5 | // Created by Hung on 18/12/16. 6 | // Copyright © 2016 Hung. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import NHRangeSlider 11 | 12 | class NHRangeSliderTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /SliderExample/SliderExampleTests/SliderExampleTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SliderExampleTests.swift 3 | // SliderExampleTests 4 | // 5 | // Created by Hung on 18/12/16. 6 | // Copyright © 2016 Hung. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import SliderExample 11 | 12 | class SliderExampleTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /SliderExample/SliderExample/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 | 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 | 38 | 39 | -------------------------------------------------------------------------------- /docs/js/jazzy.js: -------------------------------------------------------------------------------- 1 | window.jazzy = {'docset': false} 2 | if (typeof window.dash != 'undefined') { 3 | document.documentElement.className += ' dash' 4 | window.jazzy.docset = true 5 | } 6 | if (navigator.userAgent.match(/xcode/i)) { 7 | document.documentElement.className += ' xcode' 8 | window.jazzy.docset = true 9 | } 10 | 11 | // On doc load, toggle the URL hash discussion if present 12 | $(document).ready(function() { 13 | if (!window.jazzy.docset) { 14 | var linkToHash = $('a[href="' + window.location.hash +'"]'); 15 | linkToHash.trigger("click"); 16 | } 17 | }); 18 | 19 | // On token click, toggle its discussion and animate token.marginLeft 20 | $(".token").click(function(event) { 21 | if (window.jazzy.docset) { 22 | return; 23 | } 24 | var link = $(this); 25 | var animationDuration = 300; 26 | var tokenOffset = "15px"; 27 | var original = link.css('marginLeft') == tokenOffset; 28 | link.animate({'margin-left':original ? "0px" : tokenOffset}, animationDuration); 29 | $content = link.parent().parent().next(); 30 | $content.slideToggle(animationDuration); 31 | 32 | // Keeps the document from jumping to the hash. 33 | var href = $(this).attr('href'); 34 | if (history.pushState) { 35 | history.pushState({}, '', href); 36 | } else { 37 | location.hash = href; 38 | } 39 | event.preventDefault(); 40 | }); 41 | -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/js/jazzy.js: -------------------------------------------------------------------------------- 1 | window.jazzy = {'docset': false} 2 | if (typeof window.dash != 'undefined') { 3 | document.documentElement.className += ' dash' 4 | window.jazzy.docset = true 5 | } 6 | if (navigator.userAgent.match(/xcode/i)) { 7 | document.documentElement.className += ' xcode' 8 | window.jazzy.docset = true 9 | } 10 | 11 | // On doc load, toggle the URL hash discussion if present 12 | $(document).ready(function() { 13 | if (!window.jazzy.docset) { 14 | var linkToHash = $('a[href="' + window.location.hash +'"]'); 15 | linkToHash.trigger("click"); 16 | } 17 | }); 18 | 19 | // On token click, toggle its discussion and animate token.marginLeft 20 | $(".token").click(function(event) { 21 | if (window.jazzy.docset) { 22 | return; 23 | } 24 | var link = $(this); 25 | var animationDuration = 300; 26 | var tokenOffset = "15px"; 27 | var original = link.css('marginLeft') == tokenOffset; 28 | link.animate({'margin-left':original ? "0px" : tokenOffset}, animationDuration); 29 | $content = link.parent().parent().next(); 30 | $content.slideToggle(animationDuration); 31 | 32 | // Keeps the document from jumping to the hash. 33 | var href = $(this).attr('href'); 34 | if (history.pushState) { 35 | history.pushState({}, '', href); 36 | } else { 37 | location.hash = href; 38 | } 39 | event.preventDefault(); 40 | }); 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | # Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | 55 | #Code Injection 56 | # 57 | # After new code Injection tools there's a generated folder /iOSInjectionProject 58 | # https://github.com/johnno1962/injectionforxcode 59 | 60 | iOSInjectionProject/ 61 | -------------------------------------------------------------------------------- /SliderExample/SliderExample/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 | -------------------------------------------------------------------------------- /SliderExample/SliderExample/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 | 27 | 28 | -------------------------------------------------------------------------------- /SliderExample/SliderExample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SliderExample 4 | // 5 | // Created by Hung on 18/12/16. 6 | // Copyright © 2016 Hung. 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: [UIApplicationLaunchOptionsKey: 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 | -------------------------------------------------------------------------------- /docs/undocumented.json: -------------------------------------------------------------------------------- 1 | { 2 | "warnings": [ 3 | { 4 | "file": "/Users/visenze/Desktop/xcode_workspace/NHRangeSlider/NHRangeSlider/NHRangeSlider/NHRangeSlider.swift", 5 | "line": 263, 6 | "symbol": "NHRangeSlider.init(coder:)", 7 | "symbol_kind": "source.lang.swift.decl.function.method.instance", 8 | "warning": "undocumented" 9 | }, 10 | { 11 | "file": "/Users/visenze/Desktop/xcode_workspace/NHRangeSlider/NHRangeSlider/NHRangeSlider/NHRangeSliderView.swift", 12 | "line": 36, 13 | "symbol": "NHRangeSliderView.delegate", 14 | "symbol_kind": "source.lang.swift.decl.var.instance", 15 | "warning": "undocumented" 16 | }, 17 | { 18 | "file": "/Users/visenze/Desktop/xcode_workspace/NHRangeSlider/NHRangeSlider/NHRangeSlider/NHRangeSliderView.swift", 19 | "line": 45, 20 | "symbol": "NHRangeSliderView.lowerLabel", 21 | "symbol_kind": "source.lang.swift.decl.var.instance", 22 | "warning": "undocumented" 23 | }, 24 | { 25 | "file": "/Users/visenze/Desktop/xcode_workspace/NHRangeSlider/NHRangeSlider/NHRangeSlider/NHRangeSliderView.swift", 26 | "line": 173, 27 | "symbol": "NHRangeSliderView.init(frame:)", 28 | "symbol_kind": "source.lang.swift.decl.function.method.instance", 29 | "warning": "undocumented" 30 | }, 31 | { 32 | "file": "/Users/visenze/Desktop/xcode_workspace/NHRangeSlider/NHRangeSlider/NHRangeSlider/NHRangeSliderView.swift", 33 | "line": 179, 34 | "symbol": "NHRangeSliderView.init(coder:)", 35 | "symbol_kind": "source.lang.swift.decl.function.method.instance", 36 | "warning": "undocumented" 37 | }, 38 | { 39 | "file": "/Users/visenze/Desktop/xcode_workspace/NHRangeSlider/NHRangeSlider/NHRangeSlider/NHRangeSliderView.swift", 40 | "line": 234, 41 | "symbol": "NHRangeSliderView.updateLabelDisplay()", 42 | "symbol_kind": "source.lang.swift.decl.function.method.instance", 43 | "warning": "undocumented" 44 | }, 45 | { 46 | "file": "/Users/visenze/Desktop/xcode_workspace/NHRangeSlider/NHRangeSlider/NHRangeSlider/NHRangeSliderView.swift", 47 | "line": 310, 48 | "symbol": "NHRangeSliderView.sizeThatFits(_:)", 49 | "symbol_kind": "source.lang.swift.decl.function.method.instance", 50 | "warning": "undocumented" 51 | } 52 | ], 53 | "source_directory": "/Users/visenze/Desktop/xcode_workspace/NHRangeSlider/NHRangeSlider" 54 | } -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/undocumented.json: -------------------------------------------------------------------------------- 1 | { 2 | "warnings": [ 3 | { 4 | "file": "/Users/visenze/Desktop/xcode_workspace/NHRangeSlider/NHRangeSlider/NHRangeSlider/NHRangeSlider.swift", 5 | "line": 263, 6 | "symbol": "NHRangeSlider.init(coder:)", 7 | "symbol_kind": "source.lang.swift.decl.function.method.instance", 8 | "warning": "undocumented" 9 | }, 10 | { 11 | "file": "/Users/visenze/Desktop/xcode_workspace/NHRangeSlider/NHRangeSlider/NHRangeSlider/NHRangeSliderView.swift", 12 | "line": 36, 13 | "symbol": "NHRangeSliderView.delegate", 14 | "symbol_kind": "source.lang.swift.decl.var.instance", 15 | "warning": "undocumented" 16 | }, 17 | { 18 | "file": "/Users/visenze/Desktop/xcode_workspace/NHRangeSlider/NHRangeSlider/NHRangeSlider/NHRangeSliderView.swift", 19 | "line": 45, 20 | "symbol": "NHRangeSliderView.lowerLabel", 21 | "symbol_kind": "source.lang.swift.decl.var.instance", 22 | "warning": "undocumented" 23 | }, 24 | { 25 | "file": "/Users/visenze/Desktop/xcode_workspace/NHRangeSlider/NHRangeSlider/NHRangeSlider/NHRangeSliderView.swift", 26 | "line": 173, 27 | "symbol": "NHRangeSliderView.init(frame:)", 28 | "symbol_kind": "source.lang.swift.decl.function.method.instance", 29 | "warning": "undocumented" 30 | }, 31 | { 32 | "file": "/Users/visenze/Desktop/xcode_workspace/NHRangeSlider/NHRangeSlider/NHRangeSlider/NHRangeSliderView.swift", 33 | "line": 179, 34 | "symbol": "NHRangeSliderView.init(coder:)", 35 | "symbol_kind": "source.lang.swift.decl.function.method.instance", 36 | "warning": "undocumented" 37 | }, 38 | { 39 | "file": "/Users/visenze/Desktop/xcode_workspace/NHRangeSlider/NHRangeSlider/NHRangeSlider/NHRangeSliderView.swift", 40 | "line": 234, 41 | "symbol": "NHRangeSliderView.updateLabelDisplay()", 42 | "symbol_kind": "source.lang.swift.decl.function.method.instance", 43 | "warning": "undocumented" 44 | }, 45 | { 46 | "file": "/Users/visenze/Desktop/xcode_workspace/NHRangeSlider/NHRangeSlider/NHRangeSlider/NHRangeSliderView.swift", 47 | "line": 310, 48 | "symbol": "NHRangeSliderView.sizeThatFits(_:)", 49 | "symbol_kind": "source.lang.swift.decl.function.method.instance", 50 | "warning": "undocumented" 51 | } 52 | ], 53 | "source_directory": "/Users/visenze/Desktop/xcode_workspace/NHRangeSlider/NHRangeSlider" 54 | } -------------------------------------------------------------------------------- /NHRangeSlider.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint NHRangeSlider.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | s.name = "NHRangeSlider" 12 | s.version = "0.2" 13 | s.summary = "A custom range slider in Swift." 14 | 15 | s.description = <<-DESC 16 | A custom range slider in Swift. Circle/square left right thumbs with labels and custom string format. 17 | DESC 18 | 19 | s.homepage = "https://github.com/thehung111/NHRangeSlider" 20 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 21 | 22 | s.license = { :type => "MIT", :file => "LICENSE" } 23 | 24 | s.author = { "Ngo Hung" => "hung@visenze.com" , "The Hung " => "thehung111@gmail.com"} 25 | 26 | # s.platform = :ios 27 | s.platform = :ios, "8.0" 28 | 29 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 30 | # 31 | # Specify the location from where the source should be retrieved. 32 | # Supports git, hg, bzr, svn and HTTP. 33 | # 34 | 35 | s.source = { :git => "https://github.com/thehung111/NHRangeSlider.git", :tag => "#{s.version}" } 36 | 37 | 38 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 39 | # 40 | # CocoaPods is smart about how it includes source code. For source files 41 | # giving a folder will include any swift, h, m, mm, c & cpp files. 42 | # For header files it will include any header in the folder. 43 | # Not including the public_header_files will make all headers public. 44 | # 45 | 46 | s.source_files = "NHRangeSlider/NHRangeSlider/**/*.{h,swift}" 47 | #s.exclude_files = "Classes/Exclude" 48 | 49 | # s.public_header_files = "Classes/**/*.h" 50 | 51 | # s.resource = "icon.png" 52 | # s.resources = "Resources/*.png" 53 | 54 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 55 | 56 | # s.framework = "SomeFramework" 57 | # s.frameworks = "SomeFramework", "AnotherFramework" 58 | 59 | # s.library = "iconv" 60 | # s.libraries = "iconv", "xml2" 61 | 62 | 63 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 64 | # 65 | # If your library depends on compiler flags you can set them in the xcconfig hash 66 | # where they will only apply to your library. If you depend on other Podspecs 67 | # you can include multiple dependencies to ensure it works. 68 | 69 | s.requires_arc = true 70 | 71 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 72 | # s.dependency "JSONKit", "~> 1.4" 73 | 74 | end 75 | -------------------------------------------------------------------------------- /NHRangeSlider/NHRangeSlider.xcodeproj/xcshareddata/xcschemes/NHRangeSlider.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /SliderExample/SliderExample/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SliderExample 4 | // 5 | // Created by Hung on 18/12/16. 6 | // Copyright © 2016 Hung. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import NHRangeSlider 11 | 12 | class ViewController: UIViewController { 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | // Do any additional setup after loading the view, typically from a nib. 17 | 18 | // default slider 19 | let sliderView = NHRangeSliderView(frame: CGRect(x: 16, y: 20, width: self.view.bounds.width - 32, height: 80) ) 20 | sliderView.sizeToFit() 21 | self.view.addSubview(sliderView) 22 | 23 | let sliderSquareView = NHRangeSliderView(frame: CGRect(x: 16, y: sliderView.frame.maxY + 8, 24 | width: sliderView.frame.size.width, 25 | height: sliderView.frame.size.height) ) 26 | sliderSquareView.curvaceousness = 0.0 27 | sliderSquareView.trackHighlightTintColor = UIColor.red 28 | sliderSquareView.lowerValue = 20.0 29 | sliderSquareView.upperValue = 80.0 30 | sliderSquareView.sizeToFit() 31 | self.view.addSubview(sliderSquareView) 32 | 33 | 34 | let sliderSquareWithLabelView = NHRangeSliderView(frame: CGRect(x: 16, y: sliderSquareView.frame.maxY + 8, 35 | width: sliderView.frame.size.width, 36 | height: sliderView.frame.size.height) ) 37 | sliderSquareWithLabelView.curvaceousness = 0.0 38 | sliderSquareWithLabelView.trackHighlightTintColor = UIColor.brown 39 | sliderSquareWithLabelView.lowerValue = 20.0 40 | sliderSquareWithLabelView.upperValue = 80.0 41 | sliderSquareWithLabelView.stepValue = 5.0 42 | sliderSquareWithLabelView.titleLabel?.text = "Slider with title label and step value (5)" 43 | sliderSquareWithLabelView.sizeToFit() 44 | self.view.addSubview(sliderSquareWithLabelView) 45 | 46 | // slider with labels following the text 47 | let sliderWithLabelFollowView = NHRangeSliderView(frame: CGRect(x: 16, y: sliderSquareWithLabelView.frame.maxY + 8, 48 | width: sliderView.frame.size.width, 49 | height: sliderView.frame.size.height) ) 50 | sliderWithLabelFollowView.trackHighlightTintColor = UIColor.black 51 | sliderWithLabelFollowView.lowerValue = 30.0 52 | sliderWithLabelFollowView.upperValue = 70.0 53 | sliderWithLabelFollowView.gapBetweenThumbs = 5 54 | 55 | sliderWithLabelFollowView.thumbLabelStyle = .FOLLOW 56 | sliderWithLabelFollowView.titleLabel?.text = "Slider with labels follow thumbs" 57 | sliderWithLabelFollowView.sizeToFit() 58 | self.view.addSubview(sliderWithLabelFollowView) 59 | 60 | // custom string format example 61 | let sliderCustomStringView = NHRangeSliderView(frame: CGRect(x: 16, y: sliderWithLabelFollowView.frame.maxY + 8, 62 | width: sliderView.frame.size.width, 63 | height: sliderView.frame.size.height) ) 64 | sliderCustomStringView.trackHighlightTintColor = UIColor.black 65 | sliderCustomStringView.lowerValue = 30.0 66 | sliderCustomStringView.upperValue = 70.0 67 | sliderCustomStringView.stepValue = 10 68 | sliderCustomStringView.gapBetweenThumbs = 10 69 | 70 | sliderCustomStringView.thumbLabelStyle = .FOLLOW 71 | 72 | sliderCustomStringView.titleLabel?.text = "Stepped slider with custom format" 73 | sliderCustomStringView.lowerDisplayStringFormat = "Min: $%.0f" 74 | sliderCustomStringView.upperDisplayStringFormat = "Max: $%.0f" 75 | 76 | sliderCustomStringView.sizeToFit() 77 | self.view.addSubview(sliderCustomStringView) 78 | 79 | 80 | } 81 | 82 | override func didReceiveMemoryWarning() { 83 | super.didReceiveMemoryWarning() 84 | // Dispose of any resources that can be recreated. 85 | } 86 | 87 | 88 | } 89 | 90 | -------------------------------------------------------------------------------- /docs/Enums.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Enums Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |

NHRangeSlider Docs (89% documented)

17 |

View on GitHub

18 |
19 |
20 |
21 | 26 |
27 |
28 | 65 |
66 |
67 |
68 |

Enums

69 |

The following enums are available globally.

70 | 71 |
72 |
73 |
74 |
    75 |
  • 76 |
    77 | 78 | 79 | 80 | NHSliderLabelStyle 81 | 82 |
    83 |
    84 |
    85 |
    86 |
    87 |
    88 |

    enum for label positions

    89 | 90 | See more 91 |
    92 |
    93 |

    Declaration

    94 |
    95 |

    Swift

    96 |
    public enum NHSliderLabelStyle : Int
    97 | 98 |
    99 |
    100 |
    101 |
    102 |
  • 103 |
104 |
105 |
106 |
107 | 111 |
112 |
113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/Enums.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Enums Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |

NHRangeSlider Docs (89% documented)

17 |

View on GitHub

18 |
19 |
20 |
21 | 26 |
27 |
28 | 65 |
66 |
67 |
68 |

Enums

69 |

The following enums are available globally.

70 | 71 |
72 |
73 |
74 |
    75 |
  • 76 |
    77 | 78 | 79 | 80 | NHSliderLabelStyle 81 | 82 |
    83 |
    84 |
    85 |
    86 |
    87 |
    88 |

    enum for label positions

    89 | 90 | See more 91 |
    92 |
    93 |

    Declaration

    94 |
    95 |

    Swift

    96 |
    public enum NHSliderLabelStyle : Int
    97 | 98 |
    99 |
    100 |
    101 |
    102 |
  • 103 |
104 |
105 |
106 |
107 | 111 |
112 |
113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /docs/Protocols.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Protocols Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |

NHRangeSlider Docs (89% documented)

17 |

View on GitHub

18 |
19 |
20 |
21 | 26 |
27 |
28 | 65 |
66 |
67 |
68 |

Protocols

69 |

The following protocols are available globally.

70 | 71 |
72 |
73 |
74 |
    75 |
  • 76 |
    77 | 78 | 79 | 80 | NHRangeSliderViewDelegate 81 | 82 |
    83 |
    84 |
    85 |
    86 |
    87 |
    88 |

    delegate for changed value

    89 | 90 | See more 91 |
    92 |
    93 |

    Declaration

    94 |
    95 |

    Swift

    96 |
    public protocol NHRangeSliderViewDelegate: class
    97 | 98 |
    99 |
    100 |
    101 |
    102 |
  • 103 |
104 |
105 |
106 |
107 | 111 |
112 |
113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/Protocols.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Protocols Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |

NHRangeSlider Docs (89% documented)

17 |

View on GitHub

18 |
19 |
20 |
21 | 26 |
27 |
28 | 65 |
66 |
67 |
68 |

Protocols

69 |

The following protocols are available globally.

70 | 71 |
72 |
73 |
74 |
    75 |
  • 76 |
    77 | 78 | 79 | 80 | NHRangeSliderViewDelegate 81 | 82 |
    83 |
    84 |
    85 |
    86 |
    87 |
    88 |

    delegate for changed value

    89 | 90 | See more 91 |
    92 |
    93 |

    Declaration

    94 |
    95 |

    Swift

    96 |
    public protocol NHRangeSliderViewDelegate: class
    97 | 98 |
    99 |
    100 |
    101 |
    102 |
  • 103 |
104 |
105 |
106 |
107 | 111 |
112 |
113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /docs/css/highlight.css: -------------------------------------------------------------------------------- 1 | /* Credit to https://gist.github.com/wataru420/2048287 */ 2 | .highlight { 3 | /* Comment */ 4 | /* Error */ 5 | /* Keyword */ 6 | /* Operator */ 7 | /* Comment.Multiline */ 8 | /* Comment.Preproc */ 9 | /* Comment.Single */ 10 | /* Comment.Special */ 11 | /* Generic.Deleted */ 12 | /* Generic.Deleted.Specific */ 13 | /* Generic.Emph */ 14 | /* Generic.Error */ 15 | /* Generic.Heading */ 16 | /* Generic.Inserted */ 17 | /* Generic.Inserted.Specific */ 18 | /* Generic.Output */ 19 | /* Generic.Prompt */ 20 | /* Generic.Strong */ 21 | /* Generic.Subheading */ 22 | /* Generic.Traceback */ 23 | /* Keyword.Constant */ 24 | /* Keyword.Declaration */ 25 | /* Keyword.Pseudo */ 26 | /* Keyword.Reserved */ 27 | /* Keyword.Type */ 28 | /* Literal.Number */ 29 | /* Literal.String */ 30 | /* Name.Attribute */ 31 | /* Name.Builtin */ 32 | /* Name.Class */ 33 | /* Name.Constant */ 34 | /* Name.Entity */ 35 | /* Name.Exception */ 36 | /* Name.Function */ 37 | /* Name.Namespace */ 38 | /* Name.Tag */ 39 | /* Name.Variable */ 40 | /* Operator.Word */ 41 | /* Text.Whitespace */ 42 | /* Literal.Number.Float */ 43 | /* Literal.Number.Hex */ 44 | /* Literal.Number.Integer */ 45 | /* Literal.Number.Oct */ 46 | /* Literal.String.Backtick */ 47 | /* Literal.String.Char */ 48 | /* Literal.String.Doc */ 49 | /* Literal.String.Double */ 50 | /* Literal.String.Escape */ 51 | /* Literal.String.Heredoc */ 52 | /* Literal.String.Interpol */ 53 | /* Literal.String.Other */ 54 | /* Literal.String.Regex */ 55 | /* Literal.String.Single */ 56 | /* Literal.String.Symbol */ 57 | /* Name.Builtin.Pseudo */ 58 | /* Name.Variable.Class */ 59 | /* Name.Variable.Global */ 60 | /* Name.Variable.Instance */ 61 | /* Literal.Number.Integer.Long */ } 62 | .highlight .c { 63 | color: #999988; 64 | font-style: italic; } 65 | .highlight .err { 66 | color: #a61717; 67 | background-color: #e3d2d2; } 68 | .highlight .k { 69 | color: #000000; 70 | font-weight: bold; } 71 | .highlight .o { 72 | color: #000000; 73 | font-weight: bold; } 74 | .highlight .cm { 75 | color: #999988; 76 | font-style: italic; } 77 | .highlight .cp { 78 | color: #999999; 79 | font-weight: bold; } 80 | .highlight .c1 { 81 | color: #999988; 82 | font-style: italic; } 83 | .highlight .cs { 84 | color: #999999; 85 | font-weight: bold; 86 | font-style: italic; } 87 | .highlight .gd { 88 | color: #000000; 89 | background-color: #ffdddd; } 90 | .highlight .gd .x { 91 | color: #000000; 92 | background-color: #ffaaaa; } 93 | .highlight .ge { 94 | color: #000000; 95 | font-style: italic; } 96 | .highlight .gr { 97 | color: #aa0000; } 98 | .highlight .gh { 99 | color: #999999; } 100 | .highlight .gi { 101 | color: #000000; 102 | background-color: #ddffdd; } 103 | .highlight .gi .x { 104 | color: #000000; 105 | background-color: #aaffaa; } 106 | .highlight .go { 107 | color: #888888; } 108 | .highlight .gp { 109 | color: #555555; } 110 | .highlight .gs { 111 | font-weight: bold; } 112 | .highlight .gu { 113 | color: #aaaaaa; } 114 | .highlight .gt { 115 | color: #aa0000; } 116 | .highlight .kc { 117 | color: #000000; 118 | font-weight: bold; } 119 | .highlight .kd { 120 | color: #000000; 121 | font-weight: bold; } 122 | .highlight .kp { 123 | color: #000000; 124 | font-weight: bold; } 125 | .highlight .kr { 126 | color: #000000; 127 | font-weight: bold; } 128 | .highlight .kt { 129 | color: #445588; } 130 | .highlight .m { 131 | color: #009999; } 132 | .highlight .s { 133 | color: #d14; } 134 | .highlight .na { 135 | color: #008080; } 136 | .highlight .nb { 137 | color: #0086B3; } 138 | .highlight .nc { 139 | color: #445588; 140 | font-weight: bold; } 141 | .highlight .no { 142 | color: #008080; } 143 | .highlight .ni { 144 | color: #800080; } 145 | .highlight .ne { 146 | color: #990000; 147 | font-weight: bold; } 148 | .highlight .nf { 149 | color: #990000; } 150 | .highlight .nn { 151 | color: #555555; } 152 | .highlight .nt { 153 | color: #000080; } 154 | .highlight .nv { 155 | color: #008080; } 156 | .highlight .ow { 157 | color: #000000; 158 | font-weight: bold; } 159 | .highlight .w { 160 | color: #bbbbbb; } 161 | .highlight .mf { 162 | color: #009999; } 163 | .highlight .mh { 164 | color: #009999; } 165 | .highlight .mi { 166 | color: #009999; } 167 | .highlight .mo { 168 | color: #009999; } 169 | .highlight .sb { 170 | color: #d14; } 171 | .highlight .sc { 172 | color: #d14; } 173 | .highlight .sd { 174 | color: #d14; } 175 | .highlight .s2 { 176 | color: #d14; } 177 | .highlight .se { 178 | color: #d14; } 179 | .highlight .sh { 180 | color: #d14; } 181 | .highlight .si { 182 | color: #d14; } 183 | .highlight .sx { 184 | color: #d14; } 185 | .highlight .sr { 186 | color: #009926; } 187 | .highlight .s1 { 188 | color: #d14; } 189 | .highlight .ss { 190 | color: #990073; } 191 | .highlight .bp { 192 | color: #999999; } 193 | .highlight .vc { 194 | color: #008080; } 195 | .highlight .vg { 196 | color: #008080; } 197 | .highlight .vi { 198 | color: #008080; } 199 | .highlight .il { 200 | color: #009999; } 201 | -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/css/highlight.css: -------------------------------------------------------------------------------- 1 | /* Credit to https://gist.github.com/wataru420/2048287 */ 2 | .highlight { 3 | /* Comment */ 4 | /* Error */ 5 | /* Keyword */ 6 | /* Operator */ 7 | /* Comment.Multiline */ 8 | /* Comment.Preproc */ 9 | /* Comment.Single */ 10 | /* Comment.Special */ 11 | /* Generic.Deleted */ 12 | /* Generic.Deleted.Specific */ 13 | /* Generic.Emph */ 14 | /* Generic.Error */ 15 | /* Generic.Heading */ 16 | /* Generic.Inserted */ 17 | /* Generic.Inserted.Specific */ 18 | /* Generic.Output */ 19 | /* Generic.Prompt */ 20 | /* Generic.Strong */ 21 | /* Generic.Subheading */ 22 | /* Generic.Traceback */ 23 | /* Keyword.Constant */ 24 | /* Keyword.Declaration */ 25 | /* Keyword.Pseudo */ 26 | /* Keyword.Reserved */ 27 | /* Keyword.Type */ 28 | /* Literal.Number */ 29 | /* Literal.String */ 30 | /* Name.Attribute */ 31 | /* Name.Builtin */ 32 | /* Name.Class */ 33 | /* Name.Constant */ 34 | /* Name.Entity */ 35 | /* Name.Exception */ 36 | /* Name.Function */ 37 | /* Name.Namespace */ 38 | /* Name.Tag */ 39 | /* Name.Variable */ 40 | /* Operator.Word */ 41 | /* Text.Whitespace */ 42 | /* Literal.Number.Float */ 43 | /* Literal.Number.Hex */ 44 | /* Literal.Number.Integer */ 45 | /* Literal.Number.Oct */ 46 | /* Literal.String.Backtick */ 47 | /* Literal.String.Char */ 48 | /* Literal.String.Doc */ 49 | /* Literal.String.Double */ 50 | /* Literal.String.Escape */ 51 | /* Literal.String.Heredoc */ 52 | /* Literal.String.Interpol */ 53 | /* Literal.String.Other */ 54 | /* Literal.String.Regex */ 55 | /* Literal.String.Single */ 56 | /* Literal.String.Symbol */ 57 | /* Name.Builtin.Pseudo */ 58 | /* Name.Variable.Class */ 59 | /* Name.Variable.Global */ 60 | /* Name.Variable.Instance */ 61 | /* Literal.Number.Integer.Long */ } 62 | .highlight .c { 63 | color: #999988; 64 | font-style: italic; } 65 | .highlight .err { 66 | color: #a61717; 67 | background-color: #e3d2d2; } 68 | .highlight .k { 69 | color: #000000; 70 | font-weight: bold; } 71 | .highlight .o { 72 | color: #000000; 73 | font-weight: bold; } 74 | .highlight .cm { 75 | color: #999988; 76 | font-style: italic; } 77 | .highlight .cp { 78 | color: #999999; 79 | font-weight: bold; } 80 | .highlight .c1 { 81 | color: #999988; 82 | font-style: italic; } 83 | .highlight .cs { 84 | color: #999999; 85 | font-weight: bold; 86 | font-style: italic; } 87 | .highlight .gd { 88 | color: #000000; 89 | background-color: #ffdddd; } 90 | .highlight .gd .x { 91 | color: #000000; 92 | background-color: #ffaaaa; } 93 | .highlight .ge { 94 | color: #000000; 95 | font-style: italic; } 96 | .highlight .gr { 97 | color: #aa0000; } 98 | .highlight .gh { 99 | color: #999999; } 100 | .highlight .gi { 101 | color: #000000; 102 | background-color: #ddffdd; } 103 | .highlight .gi .x { 104 | color: #000000; 105 | background-color: #aaffaa; } 106 | .highlight .go { 107 | color: #888888; } 108 | .highlight .gp { 109 | color: #555555; } 110 | .highlight .gs { 111 | font-weight: bold; } 112 | .highlight .gu { 113 | color: #aaaaaa; } 114 | .highlight .gt { 115 | color: #aa0000; } 116 | .highlight .kc { 117 | color: #000000; 118 | font-weight: bold; } 119 | .highlight .kd { 120 | color: #000000; 121 | font-weight: bold; } 122 | .highlight .kp { 123 | color: #000000; 124 | font-weight: bold; } 125 | .highlight .kr { 126 | color: #000000; 127 | font-weight: bold; } 128 | .highlight .kt { 129 | color: #445588; } 130 | .highlight .m { 131 | color: #009999; } 132 | .highlight .s { 133 | color: #d14; } 134 | .highlight .na { 135 | color: #008080; } 136 | .highlight .nb { 137 | color: #0086B3; } 138 | .highlight .nc { 139 | color: #445588; 140 | font-weight: bold; } 141 | .highlight .no { 142 | color: #008080; } 143 | .highlight .ni { 144 | color: #800080; } 145 | .highlight .ne { 146 | color: #990000; 147 | font-weight: bold; } 148 | .highlight .nf { 149 | color: #990000; } 150 | .highlight .nn { 151 | color: #555555; } 152 | .highlight .nt { 153 | color: #000080; } 154 | .highlight .nv { 155 | color: #008080; } 156 | .highlight .ow { 157 | color: #000000; 158 | font-weight: bold; } 159 | .highlight .w { 160 | color: #bbbbbb; } 161 | .highlight .mf { 162 | color: #009999; } 163 | .highlight .mh { 164 | color: #009999; } 165 | .highlight .mi { 166 | color: #009999; } 167 | .highlight .mo { 168 | color: #009999; } 169 | .highlight .sb { 170 | color: #d14; } 171 | .highlight .sc { 172 | color: #d14; } 173 | .highlight .sd { 174 | color: #d14; } 175 | .highlight .s2 { 176 | color: #d14; } 177 | .highlight .se { 178 | color: #d14; } 179 | .highlight .sh { 180 | color: #d14; } 181 | .highlight .si { 182 | color: #d14; } 183 | .highlight .sx { 184 | color: #d14; } 185 | .highlight .sr { 186 | color: #009926; } 187 | .highlight .s1 { 188 | color: #d14; } 189 | .highlight .ss { 190 | color: #990073; } 191 | .highlight .bp { 192 | color: #999999; } 193 | .highlight .vc { 194 | color: #008080; } 195 | .highlight .vg { 196 | color: #008080; } 197 | .highlight .vi { 198 | color: #008080; } 199 | .highlight .il { 200 | color: #009999; } 201 | -------------------------------------------------------------------------------- /docs/Protocols/NHRangeSliderViewDelegate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | NHRangeSliderViewDelegate Protocol Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

NHRangeSlider Docs (89% documented)

18 |

View on GitHub

19 |
20 |
21 |
22 | 27 |
28 |
29 | 66 |
67 |
68 |
69 |

NHRangeSliderViewDelegate

70 |
71 |
72 |
public protocol NHRangeSliderViewDelegate: class
73 | 74 |
75 |
76 |

delegate for changed value

77 | 78 |
79 |
80 |
81 |
    82 |
  • 83 |
    84 | 85 | 86 | 87 | sliderValueChanged(slider:) 88 | 89 | 90 | Default implementation 91 | 92 |
    93 |
    94 |
    95 |
    96 |
    97 |
    98 |

    slider value changed

    99 | 100 |
    101 |

    Default Implementation

    102 |
    103 |

    optional implementation

    104 | 105 |
    106 |
    107 |

    Declaration

    108 |
    109 |

    Swift

    110 |
    func sliderValueChanged(slider: NHRangeSlider?)
    111 | 112 |
    113 |
    114 |
    115 |
    116 |
  • 117 |
118 |
119 |
120 |
121 | 125 |
126 |
127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/Protocols/NHRangeSliderViewDelegate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | NHRangeSliderViewDelegate Protocol Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

NHRangeSlider Docs (89% documented)

18 |

View on GitHub

19 |
20 |
21 |
22 | 27 |
28 |
29 | 66 |
67 |
68 |
69 |

NHRangeSliderViewDelegate

70 |
71 |
72 |
public protocol NHRangeSliderViewDelegate: class
73 | 74 |
75 |
76 |

delegate for changed value

77 | 78 |
79 |
80 |
81 |
    82 |
  • 83 |
    84 | 85 | 86 | 87 | sliderValueChanged(slider:) 88 | 89 | 90 | Default implementation 91 | 92 |
    93 |
    94 |
    95 |
    96 |
    97 |
    98 |

    slider value changed

    99 | 100 |
    101 |

    Default Implementation

    102 |
    103 |

    optional implementation

    104 | 105 |
    106 |
    107 |

    Declaration

    108 |
    109 |

    Swift

    110 |
    func sliderValueChanged(slider: NHRangeSlider?)
    111 | 112 |
    113 |
    114 |
    115 |
    116 |
  • 117 |
118 |
119 |
120 |
121 | 125 |
126 |
127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NHRangeSlider 2 | ![Swift](http://img.shields.io/badge/swift-3.0-brightgreen.svg) [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![CocoaPods](https://img.shields.io/cocoapods/v/NHRangeSlider.svg)](https://github.com/thehung111/NHRangeSlider) 3 | 4 | 5 | A custom range slider in Swift. Well-documented with examples. Forked from [RangeSlider](https://github.com/warchimede/RangeSlider) with some enhancements. 6 | 7 | 8 | 9 | ## Requirements 10 | 11 | - iOS: 8.0+ 12 | - Xcode 8.1+ 13 | - Swift 3.0+ 14 | 15 | ## Installation 16 | 17 | ### CocoaPods 18 | 19 | > CocoaPods 1.1.0+ is required to build NHRangeSlider. 20 | 21 | ```ruby 22 | source 'https://github.com/CocoaPods/Specs.git' 23 | platform :ios, '10.0' 24 | use_frameworks! 25 | 26 | target '' do 27 | pod 'NHRangeSlider', '~> 0.2' 28 | end 29 | ``` 30 | 31 | Then, run the: 32 | 33 | ```bash 34 | $ pod install 35 | ``` 36 | 37 | ### Carthage 38 | 39 | Put the following in your Cartfile: 40 | 41 | ```ogdl 42 | github "thehung111/NHRangeSlider" ~> 0.2 43 | ``` 44 | 45 | Run `carthage update --platform iOS --no-use-binaries` 46 | 47 | 48 | ### Manual 49 | 50 | You can just copy the 2 source files (NHRangeSlider and NHRangeSliderView) under NHRangeSlider/NHRangeSlider folder into your project. 51 | 52 | ## Usage 53 | 54 | ### Default Slider 55 | 56 | By default, the title label is not shown and the left and right thumbs will be circles (`curvaceousness` set to 1). You can add the view in code or via story board: 57 | 58 | ```swift 59 | override func viewDidLoad() { 60 | super.viewDidLoad() 61 | 62 | // default slider. Configure the frame 63 | let sliderView = NHRangeSliderView(frame: CGRect(x: 16, y: 20, width: self.view.bounds.width - 32, height: 80) ) 64 | // call size to fit to resize the height to fit exactly 65 | sliderView.sizeToFit() 66 | self.view.addSubview(sliderView) 67 | 68 | } 69 | ``` 70 | 71 | ### Slider with Square Thumbs 72 | 73 | ```swift 74 | let sliderSquareView = NHRangeSliderView(frame: ...) 75 | 76 | // set to 0 for square 77 | sliderSquareView.curvaceousness = 0.0 78 | 79 | sliderSquareView.trackHighlightTintColor = UIColor.red 80 | sliderSquareView.lowerValue = 20.0 81 | sliderSquareView.upperValue = 80.0 82 | sliderSquareView.sizeToFit() 83 | self.view.addSubview(sliderSquareView) 84 | ``` 85 | 86 | ### Slider with title 87 | 88 | ```swift 89 | let sliderSquareWithLabelView = NHRangeSliderView(frame: ...) 90 | sliderSquareWithLabelView.curvaceousness = 0.0 91 | sliderSquareWithLabelView.trackHighlightTintColor = UIColor.brown 92 | sliderSquareWithLabelView.lowerValue = 20.0 93 | sliderSquareWithLabelView.upperValue = 80.0 94 | 95 | // set title text 96 | sliderSquareWithLabelView.titleLabel?.text = "Slider with title label" 97 | 98 | sliderSquareWithLabelView.sizeToFit() 99 | self.view.addSubview(sliderSquareWithLabelView) 100 | ``` 101 | 102 | ### Slider with labels following thumbs 103 | 104 | ```swift 105 | let sliderWithLabelFollowView = NHRangeSliderView(frame: ...) 106 | sliderWithLabelFollowView.trackHighlightTintColor = UIColor.black 107 | sliderWithLabelFollowView.lowerValue = 30.0 108 | sliderWithLabelFollowView.upperValue = 70.0 109 | sliderWithLabelFollowView.gapBetweenThumbs = 5 110 | 111 | // set style to follow 112 | sliderWithLabelFollowView.thumbLabelStyle = .FOLLOW 113 | 114 | sliderWithLabelFollowView.titleLabel?.text = "Slider with labels follow thumbs" 115 | sliderWithLabelFollowView.sizeToFit() 116 | self.view.addSubview(sliderWithLabelFollowView) 117 | ``` 118 | 119 | ### Slider with custom format 120 | 121 | ```swift 122 | let sliderCustomStringView = NHRangeSliderView(frame: ...) 123 | sliderCustomStringView.trackHighlightTintColor = UIColor.black 124 | sliderCustomStringView.lowerValue = 30.0 125 | sliderCustomStringView.upperValue = 70.0 126 | sliderCustomStringView.stepValue = 10 127 | sliderCustomStringView.gapBetweenThumbs = 10 128 | 129 | sliderCustomStringView.thumbLabelStyle = .FOLLOW 130 | 131 | sliderCustomStringView.titleLabel?.text = "Stepped slider with custom format" 132 | sliderCustomStringView.lowerDisplayStringFormat = "Min: $%.0f" 133 | sliderCustomStringView.upperDisplayStringFormat = "Max: $%.0f" 134 | sliderCustomStringView.sizeToFit() 135 | self.view.addSubview(sliderCustomStringView) 136 | 137 | ``` 138 | 139 | ### Stepped Slider 140 | 141 | Handle stepped values. The slider will snap to discrete points (after dragging stopped) along the slider based on the stepped value. 142 | 143 | ```swift 144 | sliderSquareWithLabelView.stepValue = 5.0 145 | ``` 146 | 147 | ## Configuration 148 | 149 | The range slider view (**NHRangeSliderView**) can be customized and information can be accessed through these properties : 150 | 151 | + `titleLabel` : label for title (optional) 152 | + `lowerLabel` : label for lower thumb 153 | + `upperLabel` : label for upper thumb 154 | + `minimumValue` : The minimum possible value of the range 155 | + `maximumValue` : The maximum possible value of the range 156 | + `lowerValue` : The value corresponding to the left thumb current position 157 | + `upperValue` : The value corresponding to the right thumb current position 158 | + `stepValue` : If set, will snap to discrete step points along the slider . Default to nil. 159 | + `trackTintColor` : The track color 160 | + `trackHighlightTintColor` : The color of the section of the track located between the two thumbs 161 | + `thumbTintColor`: The thumb color 162 | + `thumbBorderColor`: The thumb border color 163 | + `thumbBorderWidth`: The width of the thumb border 164 | + `curvaceousness` : From 0.0 for square thumbs to 1.0 for circle thumbs 165 | + `lowerDisplayStringFormat` : display format for lower thumb value. Default to `%.0f` to display value as Int. Change this if you need to display decimal places or want a different label. 166 | + `upperDisplayStringFormat` : display format for upper thumb value. Default to `%.0f` to display value as Int. Change this if you need to display decimal places or want a different label. 167 | + `spacing` : vertical spacing between the labels and thumbs 168 | + `thumbLabelStyle` : position of thumb labels. Set to STICKY to stick to left and right positions. Set to FOLLOW to follow left and right thumbs 169 | + `gapBetweenThumbs` : minimum distance between thumbs 170 | 171 | To listen for value changes event, you can set the delegate (`NHRangeSliderViewDelegate`): sliderValueChanged(slider:) 172 | 173 | ## API Reference 174 | 175 | [https://thehung111.github.io/NHRangeSlider/](https://thehung111.github.io/NHRangeSlider/) 176 | 177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /docs/Classes/RangeSliderTrackLayer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | RangeSliderTrackLayer Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

NHRangeSlider Docs (89% documented)

18 |

View on GitHub

19 |
20 |
21 |
22 | 27 |
28 |
29 | 66 |
67 |
68 |
69 |

RangeSliderTrackLayer

70 |
71 |
72 |
public class RangeSliderTrackLayer: CALayer
73 | 74 |
75 |
76 |

Range slider track layer. Responsible for drawing the horizontal track

77 | 78 |
79 |
80 |
81 |
    82 |
  • 83 |
    84 | 85 | 86 | 87 | draw(in:) 88 | 89 |
    90 |
    91 |
    92 |
    93 |
    94 |
    95 |

    draw the track between 2 thumbs

    96 | 97 |
    98 |

    Parameter

    99 | Parameter ctx: current graphics context 100 | 101 |
    102 | 103 |
    104 |
    105 |

    Declaration

    106 |
    107 |

    Swift

    108 |
    override open func draw(in ctx: CGContext)
    109 | 110 |
    111 |
    112 |
    113 |

    Parameters

    114 | 115 | 116 | 117 | 122 | 128 | 129 | 130 |
    118 | 119 | ctx 120 | 121 | 123 |
    124 |

    current graphics context

    125 | 126 |
    127 |
    131 |
    132 |
    133 |
    134 |
  • 135 |
136 |
137 |
138 |
139 | 143 |
144 |
145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/Classes/RangeSliderTrackLayer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | RangeSliderTrackLayer Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

NHRangeSlider Docs (89% documented)

18 |

View on GitHub

19 |
20 |
21 |
22 | 27 |
28 |
29 | 66 |
67 |
68 |
69 |

RangeSliderTrackLayer

70 |
71 |
72 |
public class RangeSliderTrackLayer: CALayer
73 | 74 |
75 |
76 |

Range slider track layer. Responsible for drawing the horizontal track

77 | 78 |
79 |
80 |
81 |
    82 |
  • 83 |
    84 | 85 | 86 | 87 | draw(in:) 88 | 89 |
    90 |
    91 |
    92 |
    93 |
    94 |
    95 |

    draw the track between 2 thumbs

    96 | 97 |
    98 |

    Parameter

    99 | Parameter ctx: current graphics context 100 | 101 |
    102 | 103 |
    104 |
    105 |

    Declaration

    106 |
    107 |

    Swift

    108 |
    override open func draw(in ctx: CGContext)
    109 | 110 |
    111 |
    112 |
    113 |

    Parameters

    114 | 115 | 116 | 117 | 122 | 128 | 129 | 130 |
    118 | 119 | ctx 120 | 121 | 123 |
    124 |

    current graphics context

    125 | 126 |
    127 |
    131 |
    132 |
    133 |
    134 |
  • 135 |
136 |
137 |
138 |
139 | 143 |
144 |
145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /docs/Enums/NHSliderLabelStyle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | NHSliderLabelStyle Enum Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

NHRangeSlider Docs (89% documented)

18 |

View on GitHub

19 |
20 |
21 |
22 | 27 |
28 |
29 | 66 |
67 |
68 |
69 |

NHSliderLabelStyle

70 |
71 |
72 |
public enum NHSliderLabelStyle : Int
73 | 74 |
75 |
76 |

enum for label positions

77 | 78 |
79 |
80 |
81 |
    82 |
  • 83 |
    84 | 85 | 86 | 87 | STICKY 88 | 89 |
    90 |
    91 |
    92 |
    93 |
    94 |
    95 |

    lower and upper labels stick to the left and right of slider

    96 | 97 |
    98 |
    99 |

    Declaration

    100 |
    101 |

    Swift

    102 |
    case STICKY
    103 | 104 |
    105 |
    106 |
    107 |
    108 |
  • 109 |
110 |
111 |
112 |
    113 |
  • 114 |
    115 | 116 | 117 | 118 | FOLLOW 119 | 120 |
    121 |
    122 |
    123 |
    124 |
    125 |
    126 |

    lower and upper labels follow position of lower and upper thumbs

    127 | 128 |
    129 |
    130 |

    Declaration

    131 |
    132 |

    Swift

    133 |
    case FOLLOW
    134 | 135 |
    136 |
    137 |
    138 |
    139 |
  • 140 |
141 |
142 |
143 |
144 | 148 |
149 |
150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/Enums/NHSliderLabelStyle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | NHSliderLabelStyle Enum Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

NHRangeSlider Docs (89% documented)

18 |

View on GitHub

19 |
20 |
21 |
22 | 27 |
28 |
29 | 66 |
67 |
68 |
69 |

NHSliderLabelStyle

70 |
71 |
72 |
public enum NHSliderLabelStyle : Int
73 | 74 |
75 |
76 |

enum for label positions

77 | 78 |
79 |
80 |
81 |
    82 |
  • 83 |
    84 | 85 | 86 | 87 | STICKY 88 | 89 |
    90 |
    91 |
    92 |
    93 |
    94 |
    95 |

    lower and upper labels stick to the left and right of slider

    96 | 97 |
    98 |
    99 |

    Declaration

    100 |
    101 |

    Swift

    102 |
    case STICKY
    103 | 104 |
    105 |
    106 |
    107 |
    108 |
  • 109 |
110 |
111 |
112 |
    113 |
  • 114 |
    115 | 116 | 117 | 118 | FOLLOW 119 | 120 |
    121 |
    122 |
    123 |
    124 |
    125 |
    126 |

    lower and upper labels follow position of lower and upper thumbs

    127 | 128 |
    129 |
    130 |

    Declaration

    131 |
    132 |

    Swift

    133 |
    case FOLLOW
    134 | 135 |
    136 |
    137 |
    138 |
    139 |
  • 140 |
141 |
142 |
143 |
144 | 148 |
149 |
150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /docs/css/jazzy.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { 2 | background: transparent; 3 | border: 0; 4 | margin: 0; 5 | outline: 0; 6 | padding: 0; 7 | vertical-align: baseline; } 8 | 9 | body { 10 | background-color: #f2f2f2; 11 | font-family: Helvetica, freesans, Arial, sans-serif; 12 | font-size: 14px; 13 | -webkit-font-smoothing: subpixel-antialiased; 14 | word-wrap: break-word; } 15 | 16 | h1, h2, h3 { 17 | margin-top: 0.8em; 18 | margin-bottom: 0.3em; 19 | font-weight: 100; 20 | color: black; } 21 | 22 | h1 { 23 | font-size: 2.5em; } 24 | 25 | h2 { 26 | font-size: 2em; 27 | border-bottom: 1px solid #e2e2e2; } 28 | 29 | h4 { 30 | font-size: 13px; 31 | line-height: 1.5; 32 | margin-top: 21px; } 33 | 34 | h5 { 35 | font-size: 1.1em; } 36 | 37 | h6 { 38 | font-size: 1.1em; 39 | color: #777; } 40 | 41 | .section-name { 42 | color: gray; 43 | display: block; 44 | font-family: Helvetica; 45 | font-size: 22px; 46 | font-weight: 100; 47 | margin-bottom: 15px; } 48 | 49 | pre, code { 50 | font: 0.95em Menlo, monospace; 51 | color: #777; 52 | word-wrap: normal; } 53 | 54 | p code, li code { 55 | background-color: #eee; 56 | padding: 2px 4px; 57 | border-radius: 4px; } 58 | 59 | a { 60 | color: #0088cc; 61 | text-decoration: none; } 62 | 63 | ul { 64 | padding-left: 15px; } 65 | 66 | li { 67 | line-height: 1.8em; } 68 | 69 | img { 70 | max-width: 100%; } 71 | 72 | blockquote { 73 | margin-left: 0; 74 | padding: 0 10px; 75 | border-left: 4px solid #ccc; } 76 | 77 | .content-wrapper { 78 | margin: 0 auto; 79 | width: 980px; } 80 | 81 | header { 82 | font-size: 0.85em; 83 | line-height: 26px; 84 | background-color: #414141; 85 | position: fixed; 86 | width: 100%; 87 | z-index: 1; } 88 | header img { 89 | padding-right: 6px; 90 | vertical-align: -4px; 91 | height: 16px; } 92 | header a { 93 | color: #fff; } 94 | header p { 95 | float: left; 96 | color: #999; } 97 | header .header-right { 98 | float: right; 99 | margin-left: 16px; } 100 | 101 | #breadcrumbs { 102 | background-color: #f2f2f2; 103 | height: 27px; 104 | padding-top: 17px; 105 | position: fixed; 106 | width: 100%; 107 | z-index: 1; 108 | margin-top: 26px; } 109 | #breadcrumbs #carat { 110 | height: 10px; 111 | margin: 0 5px; } 112 | 113 | .sidebar { 114 | background-color: #f9f9f9; 115 | border: 1px solid #e2e2e2; 116 | overflow-y: auto; 117 | overflow-x: hidden; 118 | position: fixed; 119 | top: 70px; 120 | bottom: 0; 121 | width: 230px; 122 | word-wrap: normal; } 123 | 124 | .nav-groups { 125 | list-style-type: none; 126 | background: #fff; 127 | padding-left: 0; } 128 | 129 | .nav-group-name { 130 | border-bottom: 1px solid #e2e2e2; 131 | font-size: 1.1em; 132 | font-weight: 100; 133 | padding: 15px 0 15px 20px; } 134 | .nav-group-name > a { 135 | color: #333; } 136 | 137 | .nav-group-tasks { 138 | margin-top: 5px; } 139 | 140 | .nav-group-task { 141 | font-size: 0.9em; 142 | list-style-type: none; 143 | white-space: nowrap; } 144 | .nav-group-task a { 145 | color: #888; } 146 | 147 | .main-content { 148 | background-color: #fff; 149 | border: 1px solid #e2e2e2; 150 | margin-left: 246px; 151 | position: absolute; 152 | overflow: hidden; 153 | padding-bottom: 60px; 154 | top: 70px; 155 | width: 734px; } 156 | .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { 157 | margin-bottom: 1em; } 158 | .main-content p { 159 | line-height: 1.8em; } 160 | .main-content section .section:first-child { 161 | margin-top: 0; 162 | padding-top: 0; } 163 | .main-content section .task-group-section .task-group:first-of-type { 164 | padding-top: 10px; } 165 | .main-content section .task-group-section .task-group:first-of-type .section-name { 166 | padding-top: 15px; } 167 | 168 | .section { 169 | padding: 0 25px; } 170 | 171 | .highlight { 172 | background-color: #eee; 173 | padding: 10px 12px; 174 | border: 1px solid #e2e2e2; 175 | border-radius: 4px; 176 | overflow-x: auto; } 177 | 178 | .declaration .highlight { 179 | overflow-x: initial; 180 | padding: 0 40px 40px 0; 181 | margin-bottom: -25px; 182 | background-color: transparent; 183 | border: none; } 184 | 185 | .section-name { 186 | margin: 0; 187 | margin-left: 18px; } 188 | 189 | .task-group-section { 190 | padding-left: 6px; 191 | border-top: 1px solid #e2e2e2; } 192 | 193 | .task-group { 194 | padding-top: 0px; } 195 | 196 | .task-name-container a[name]:before { 197 | content: ""; 198 | display: block; 199 | padding-top: 70px; 200 | margin: -70px 0 0; } 201 | 202 | .item { 203 | padding-top: 8px; 204 | width: 100%; 205 | list-style-type: none; } 206 | .item a[name]:before { 207 | content: ""; 208 | display: block; 209 | padding-top: 70px; 210 | margin: -70px 0 0; } 211 | .item code { 212 | background-color: transparent; 213 | padding: 0; } 214 | .item .token { 215 | padding-left: 3px; 216 | margin-left: 15px; 217 | font-size: 11.9px; } 218 | .item .declaration-note { 219 | font-size: .85em; 220 | color: gray; 221 | font-style: italic; } 222 | 223 | .pointer-container { 224 | border-bottom: 1px solid #e2e2e2; 225 | left: -23px; 226 | padding-bottom: 13px; 227 | position: relative; 228 | width: 110%; } 229 | 230 | .pointer { 231 | background: #f9f9f9; 232 | border-left: 1px solid #e2e2e2; 233 | border-top: 1px solid #e2e2e2; 234 | height: 12px; 235 | left: 21px; 236 | top: -7px; 237 | -webkit-transform: rotate(45deg); 238 | -moz-transform: rotate(45deg); 239 | -o-transform: rotate(45deg); 240 | transform: rotate(45deg); 241 | position: absolute; 242 | width: 12px; } 243 | 244 | .height-container { 245 | display: none; 246 | left: -25px; 247 | padding: 0 25px; 248 | position: relative; 249 | width: 100%; 250 | overflow: hidden; } 251 | .height-container .section { 252 | background: #f9f9f9; 253 | border-bottom: 1px solid #e2e2e2; 254 | left: -25px; 255 | position: relative; 256 | width: 100%; 257 | padding-top: 10px; 258 | padding-bottom: 5px; } 259 | 260 | .aside, .language { 261 | padding: 6px 12px; 262 | margin: 12px 0; 263 | border-left: 5px solid #dddddd; 264 | overflow-y: hidden; } 265 | .aside .aside-title, .language .aside-title { 266 | font-size: 9px; 267 | letter-spacing: 2px; 268 | text-transform: uppercase; 269 | padding-bottom: 0; 270 | margin: 0; 271 | color: #aaa; 272 | -webkit-user-select: none; } 273 | .aside p:last-child, .language p:last-child { 274 | margin-bottom: 0; } 275 | 276 | .language { 277 | border-left: 5px solid #cde9f4; } 278 | .language .aside-title { 279 | color: #4b8afb; } 280 | 281 | .aside-warning { 282 | border-left: 5px solid #ff6666; } 283 | .aside-warning .aside-title { 284 | color: #ff0000; } 285 | 286 | .graybox { 287 | border-collapse: collapse; 288 | width: 100%; } 289 | .graybox p { 290 | margin: 0; 291 | word-break: break-word; 292 | min-width: 50px; } 293 | .graybox td { 294 | border: 1px solid #e2e2e2; 295 | padding: 5px 25px 5px 10px; 296 | vertical-align: middle; } 297 | .graybox tr td:first-of-type { 298 | text-align: right; 299 | padding: 7px; 300 | vertical-align: top; 301 | word-break: normal; 302 | width: 40px; } 303 | 304 | .slightly-smaller { 305 | font-size: 0.9em; } 306 | 307 | #footer { 308 | position: absolute; 309 | bottom: 10px; 310 | margin-left: 25px; } 311 | #footer p { 312 | margin: 0; 313 | color: #aaa; 314 | font-size: 0.8em; } 315 | 316 | html.dash header, html.dash #breadcrumbs, html.dash .sidebar { 317 | display: none; } 318 | html.dash .main-content { 319 | width: 980px; 320 | margin-left: 0; 321 | border: none; 322 | width: 100%; 323 | top: 0; 324 | padding-bottom: 0; } 325 | html.dash .height-container { 326 | display: block; } 327 | html.dash .item .token { 328 | margin-left: 0; } 329 | html.dash .content-wrapper { 330 | width: auto; } 331 | html.dash #footer { 332 | position: static; } 333 | -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/css/jazzy.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { 2 | background: transparent; 3 | border: 0; 4 | margin: 0; 5 | outline: 0; 6 | padding: 0; 7 | vertical-align: baseline; } 8 | 9 | body { 10 | background-color: #f2f2f2; 11 | font-family: Helvetica, freesans, Arial, sans-serif; 12 | font-size: 14px; 13 | -webkit-font-smoothing: subpixel-antialiased; 14 | word-wrap: break-word; } 15 | 16 | h1, h2, h3 { 17 | margin-top: 0.8em; 18 | margin-bottom: 0.3em; 19 | font-weight: 100; 20 | color: black; } 21 | 22 | h1 { 23 | font-size: 2.5em; } 24 | 25 | h2 { 26 | font-size: 2em; 27 | border-bottom: 1px solid #e2e2e2; } 28 | 29 | h4 { 30 | font-size: 13px; 31 | line-height: 1.5; 32 | margin-top: 21px; } 33 | 34 | h5 { 35 | font-size: 1.1em; } 36 | 37 | h6 { 38 | font-size: 1.1em; 39 | color: #777; } 40 | 41 | .section-name { 42 | color: gray; 43 | display: block; 44 | font-family: Helvetica; 45 | font-size: 22px; 46 | font-weight: 100; 47 | margin-bottom: 15px; } 48 | 49 | pre, code { 50 | font: 0.95em Menlo, monospace; 51 | color: #777; 52 | word-wrap: normal; } 53 | 54 | p code, li code { 55 | background-color: #eee; 56 | padding: 2px 4px; 57 | border-radius: 4px; } 58 | 59 | a { 60 | color: #0088cc; 61 | text-decoration: none; } 62 | 63 | ul { 64 | padding-left: 15px; } 65 | 66 | li { 67 | line-height: 1.8em; } 68 | 69 | img { 70 | max-width: 100%; } 71 | 72 | blockquote { 73 | margin-left: 0; 74 | padding: 0 10px; 75 | border-left: 4px solid #ccc; } 76 | 77 | .content-wrapper { 78 | margin: 0 auto; 79 | width: 980px; } 80 | 81 | header { 82 | font-size: 0.85em; 83 | line-height: 26px; 84 | background-color: #414141; 85 | position: fixed; 86 | width: 100%; 87 | z-index: 1; } 88 | header img { 89 | padding-right: 6px; 90 | vertical-align: -4px; 91 | height: 16px; } 92 | header a { 93 | color: #fff; } 94 | header p { 95 | float: left; 96 | color: #999; } 97 | header .header-right { 98 | float: right; 99 | margin-left: 16px; } 100 | 101 | #breadcrumbs { 102 | background-color: #f2f2f2; 103 | height: 27px; 104 | padding-top: 17px; 105 | position: fixed; 106 | width: 100%; 107 | z-index: 1; 108 | margin-top: 26px; } 109 | #breadcrumbs #carat { 110 | height: 10px; 111 | margin: 0 5px; } 112 | 113 | .sidebar { 114 | background-color: #f9f9f9; 115 | border: 1px solid #e2e2e2; 116 | overflow-y: auto; 117 | overflow-x: hidden; 118 | position: fixed; 119 | top: 70px; 120 | bottom: 0; 121 | width: 230px; 122 | word-wrap: normal; } 123 | 124 | .nav-groups { 125 | list-style-type: none; 126 | background: #fff; 127 | padding-left: 0; } 128 | 129 | .nav-group-name { 130 | border-bottom: 1px solid #e2e2e2; 131 | font-size: 1.1em; 132 | font-weight: 100; 133 | padding: 15px 0 15px 20px; } 134 | .nav-group-name > a { 135 | color: #333; } 136 | 137 | .nav-group-tasks { 138 | margin-top: 5px; } 139 | 140 | .nav-group-task { 141 | font-size: 0.9em; 142 | list-style-type: none; 143 | white-space: nowrap; } 144 | .nav-group-task a { 145 | color: #888; } 146 | 147 | .main-content { 148 | background-color: #fff; 149 | border: 1px solid #e2e2e2; 150 | margin-left: 246px; 151 | position: absolute; 152 | overflow: hidden; 153 | padding-bottom: 60px; 154 | top: 70px; 155 | width: 734px; } 156 | .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { 157 | margin-bottom: 1em; } 158 | .main-content p { 159 | line-height: 1.8em; } 160 | .main-content section .section:first-child { 161 | margin-top: 0; 162 | padding-top: 0; } 163 | .main-content section .task-group-section .task-group:first-of-type { 164 | padding-top: 10px; } 165 | .main-content section .task-group-section .task-group:first-of-type .section-name { 166 | padding-top: 15px; } 167 | 168 | .section { 169 | padding: 0 25px; } 170 | 171 | .highlight { 172 | background-color: #eee; 173 | padding: 10px 12px; 174 | border: 1px solid #e2e2e2; 175 | border-radius: 4px; 176 | overflow-x: auto; } 177 | 178 | .declaration .highlight { 179 | overflow-x: initial; 180 | padding: 0 40px 40px 0; 181 | margin-bottom: -25px; 182 | background-color: transparent; 183 | border: none; } 184 | 185 | .section-name { 186 | margin: 0; 187 | margin-left: 18px; } 188 | 189 | .task-group-section { 190 | padding-left: 6px; 191 | border-top: 1px solid #e2e2e2; } 192 | 193 | .task-group { 194 | padding-top: 0px; } 195 | 196 | .task-name-container a[name]:before { 197 | content: ""; 198 | display: block; 199 | padding-top: 70px; 200 | margin: -70px 0 0; } 201 | 202 | .item { 203 | padding-top: 8px; 204 | width: 100%; 205 | list-style-type: none; } 206 | .item a[name]:before { 207 | content: ""; 208 | display: block; 209 | padding-top: 70px; 210 | margin: -70px 0 0; } 211 | .item code { 212 | background-color: transparent; 213 | padding: 0; } 214 | .item .token { 215 | padding-left: 3px; 216 | margin-left: 15px; 217 | font-size: 11.9px; } 218 | .item .declaration-note { 219 | font-size: .85em; 220 | color: gray; 221 | font-style: italic; } 222 | 223 | .pointer-container { 224 | border-bottom: 1px solid #e2e2e2; 225 | left: -23px; 226 | padding-bottom: 13px; 227 | position: relative; 228 | width: 110%; } 229 | 230 | .pointer { 231 | background: #f9f9f9; 232 | border-left: 1px solid #e2e2e2; 233 | border-top: 1px solid #e2e2e2; 234 | height: 12px; 235 | left: 21px; 236 | top: -7px; 237 | -webkit-transform: rotate(45deg); 238 | -moz-transform: rotate(45deg); 239 | -o-transform: rotate(45deg); 240 | transform: rotate(45deg); 241 | position: absolute; 242 | width: 12px; } 243 | 244 | .height-container { 245 | display: none; 246 | left: -25px; 247 | padding: 0 25px; 248 | position: relative; 249 | width: 100%; 250 | overflow: hidden; } 251 | .height-container .section { 252 | background: #f9f9f9; 253 | border-bottom: 1px solid #e2e2e2; 254 | left: -25px; 255 | position: relative; 256 | width: 100%; 257 | padding-top: 10px; 258 | padding-bottom: 5px; } 259 | 260 | .aside, .language { 261 | padding: 6px 12px; 262 | margin: 12px 0; 263 | border-left: 5px solid #dddddd; 264 | overflow-y: hidden; } 265 | .aside .aside-title, .language .aside-title { 266 | font-size: 9px; 267 | letter-spacing: 2px; 268 | text-transform: uppercase; 269 | padding-bottom: 0; 270 | margin: 0; 271 | color: #aaa; 272 | -webkit-user-select: none; } 273 | .aside p:last-child, .language p:last-child { 274 | margin-bottom: 0; } 275 | 276 | .language { 277 | border-left: 5px solid #cde9f4; } 278 | .language .aside-title { 279 | color: #4b8afb; } 280 | 281 | .aside-warning { 282 | border-left: 5px solid #ff6666; } 283 | .aside-warning .aside-title { 284 | color: #ff0000; } 285 | 286 | .graybox { 287 | border-collapse: collapse; 288 | width: 100%; } 289 | .graybox p { 290 | margin: 0; 291 | word-break: break-word; 292 | min-width: 50px; } 293 | .graybox td { 294 | border: 1px solid #e2e2e2; 295 | padding: 5px 25px 5px 10px; 296 | vertical-align: middle; } 297 | .graybox tr td:first-of-type { 298 | text-align: right; 299 | padding: 7px; 300 | vertical-align: top; 301 | word-break: normal; 302 | width: 40px; } 303 | 304 | .slightly-smaller { 305 | font-size: 0.9em; } 306 | 307 | #footer { 308 | position: absolute; 309 | bottom: 10px; 310 | margin-left: 25px; } 311 | #footer p { 312 | margin: 0; 313 | color: #aaa; 314 | font-size: 0.8em; } 315 | 316 | html.dash header, html.dash #breadcrumbs, html.dash .sidebar { 317 | display: none; } 318 | html.dash .main-content { 319 | width: 980px; 320 | margin-left: 0; 321 | border: none; 322 | width: 100%; 323 | top: 0; 324 | padding-bottom: 0; } 325 | html.dash .height-container { 326 | display: block; } 327 | html.dash .item .token { 328 | margin-left: 0; } 329 | html.dash .content-wrapper { 330 | width: auto; } 331 | html.dash #footer { 332 | position: static; } 333 | -------------------------------------------------------------------------------- /docs/Classes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Classes Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |

NHRangeSlider Docs (89% documented)

17 |

View on GitHub

18 |
19 |
20 |
21 | 26 |
27 |
28 | 65 |
66 |
67 |
68 |

Classes

69 |

The following classes are available globally.

70 | 71 |
72 |
73 |
74 |
    75 |
  • 76 |
    77 | 78 | 79 | 80 | RangeSliderTrackLayer 81 | 82 |
    83 |
    84 |
    85 |
    86 |
    87 |
    88 |

    Range slider track layer. Responsible for drawing the horizontal track

    89 | 90 | See more 91 |
    92 |
    93 |

    Declaration

    94 |
    95 |

    Swift

    96 |
    public class RangeSliderTrackLayer: CALayer
    97 | 98 |
    99 |
    100 |
    101 |
    102 |
  • 103 |
  • 104 |
    105 | 106 | 107 | 108 | RangeSliderThumbLayer 109 | 110 |
    111 |
    112 |
    113 |
    114 |
    115 |
    116 |

    the thumb for upper , lower bounds

    117 | 118 | See more 119 |
    120 |
    121 |

    Declaration

    122 |
    123 |

    Swift

    124 |
    public class RangeSliderThumbLayer: CALayer
    125 | 126 |
    127 |
    128 |
    129 |
    130 |
  • 131 |
  • 132 |
    133 | 134 | 135 | 136 | NHRangeSlider 137 | 138 |
    139 |
    140 |
    141 |
    142 |
    143 |
    144 |

    Range slider view with upper, lower bounds

    145 | 146 | See more 147 |
    148 |
    149 |

    Declaration

    150 |
    151 |

    Swift

    152 |
    open class NHRangeSlider: UIControl
    153 | 154 |
    155 |
    156 |
    157 |
    158 |
  • 159 |
160 |
161 |
162 |
    163 |
  • 164 |
    165 | 166 | 167 | 168 | NHRangeSliderView 169 | 170 |
    171 |
    172 |
    173 |
    174 |
    175 |
    176 |

    Range slider with labels for upper and lower thumbs, title label and configurable step value (optional)

    177 | 178 | See more 179 |
    180 |
    181 |

    Declaration

    182 |
    183 |

    Swift

    184 |
    open class NHRangeSliderView: UIView
    185 | 186 |
    187 |
    188 |
    189 |
    190 |
  • 191 |
192 |
193 |
194 |
195 | 199 |
200 |
201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/Classes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Classes Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |

NHRangeSlider Docs (89% documented)

17 |

View on GitHub

18 |
19 |
20 |
21 | 26 |
27 |
28 | 65 |
66 |
67 |
68 |

Classes

69 |

The following classes are available globally.

70 | 71 |
72 |
73 |
74 |
    75 |
  • 76 |
    77 | 78 | 79 | 80 | RangeSliderTrackLayer 81 | 82 |
    83 |
    84 |
    85 |
    86 |
    87 |
    88 |

    Range slider track layer. Responsible for drawing the horizontal track

    89 | 90 | See more 91 |
    92 |
    93 |

    Declaration

    94 |
    95 |

    Swift

    96 |
    public class RangeSliderTrackLayer: CALayer
    97 | 98 |
    99 |
    100 |
    101 |
    102 |
  • 103 |
  • 104 |
    105 | 106 | 107 | 108 | RangeSliderThumbLayer 109 | 110 |
    111 |
    112 |
    113 |
    114 |
    115 |
    116 |

    the thumb for upper , lower bounds

    117 | 118 | See more 119 |
    120 |
    121 |

    Declaration

    122 |
    123 |

    Swift

    124 |
    public class RangeSliderThumbLayer: CALayer
    125 | 126 |
    127 |
    128 |
    129 |
    130 |
  • 131 |
  • 132 |
    133 | 134 | 135 | 136 | NHRangeSlider 137 | 138 |
    139 |
    140 |
    141 |
    142 |
    143 |
    144 |

    Range slider view with upper, lower bounds

    145 | 146 | See more 147 |
    148 |
    149 |

    Declaration

    150 |
    151 |

    Swift

    152 |
    open class NHRangeSlider: UIControl
    153 | 154 |
    155 |
    156 |
    157 |
    158 |
  • 159 |
160 |
161 |
162 |
    163 |
  • 164 |
    165 | 166 | 167 | 168 | NHRangeSliderView 169 | 170 |
    171 |
    172 |
    173 |
    174 |
    175 |
    176 |

    Range slider with labels for upper and lower thumbs, title label and configurable step value (optional)

    177 | 178 | See more 179 |
    180 |
    181 |

    Declaration

    182 |
    183 |

    Swift

    184 |
    open class NHRangeSliderView: UIView
    185 | 186 |
    187 |
    188 |
    189 |
    190 |
  • 191 |
192 |
193 |
194 |
195 | 199 |
200 |
201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /docs/Classes/RangeSliderThumbLayer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | RangeSliderThumbLayer Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

NHRangeSlider Docs (89% documented)

18 |

View on GitHub

19 |
20 |
21 |
22 | 27 |
28 |
29 | 66 |
67 |
68 |
69 |

RangeSliderThumbLayer

70 |
71 |
72 |
public class RangeSliderThumbLayer: CALayer
73 | 74 |
75 |
76 |

the thumb for upper , lower bounds

77 | 78 |
79 |
80 |
81 |
    82 |
  • 83 |
    84 | 85 | 86 | 87 | highlighted 88 | 89 |
    90 |
    91 |
    92 |
    93 |
    94 |
    95 |

    whether this thumb is currently highlighted i.e. touched by user

    96 | 97 |
    98 |
    99 |

    Declaration

    100 |
    101 |

    Swift

    102 |
    public var highlighted: Bool = false
    103 | 104 |
    105 |
    106 |
    107 |
    108 |
  • 109 |
  • 110 |
    111 | 112 | 113 | 114 | strokeColor 115 | 116 |
    117 |
    118 |
    119 |
    120 |
    121 |
    122 |

    stroke color

    123 | 124 |
    125 |
    126 |

    Declaration

    127 |
    128 |

    Swift

    129 |
    public var strokeColor: UIColor = UIColor.gray
    130 | 131 |
    132 |
    133 |
    134 |
    135 |
  • 136 |
  • 137 |
    138 | 139 | 140 | 141 | lineWidth 142 | 143 |
    144 |
    145 |
    146 |
    147 |
    148 |
    149 |

    line width

    150 | 151 |
    152 |
    153 |

    Declaration

    154 |
    155 |

    Swift

    156 |
    public var lineWidth: CGFloat = 0.5
    157 | 158 |
    159 |
    160 |
    161 |
    162 |
  • 163 |
  • 164 |
    165 | 166 | 167 | 168 | draw(in:) 169 | 170 |
    171 |
    172 |
    173 |
    174 |
    175 |
    176 |

    draw the thumb

    177 | 178 |
    179 |

    Parameter

    180 | Parameter ctx: current graphics context 181 | 182 |
    183 | 184 |
    185 |
    186 |

    Declaration

    187 |
    188 |

    Swift

    189 |
    override open func draw(in ctx: CGContext)
    190 | 191 |
    192 |
    193 |
    194 |

    Parameters

    195 | 196 | 197 | 198 | 203 | 209 | 210 | 211 |
    199 | 200 | ctx 201 | 202 | 204 |
    205 |

    current graphics context

    206 | 207 |
    208 |
    212 |
    213 |
    214 |
    215 |
  • 216 |
217 |
218 |
219 |
220 | 224 |
225 |
226 | 227 | 228 | 229 | -------------------------------------------------------------------------------- /docs/docsets/NHRangeSlider.docset/Contents/Resources/Documents/Classes/RangeSliderThumbLayer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | RangeSliderThumbLayer Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

NHRangeSlider Docs (89% documented)

18 |

View on GitHub

19 |
20 |
21 |
22 | 27 |
28 |
29 | 66 |
67 |
68 |
69 |

RangeSliderThumbLayer

70 |
71 |
72 |
public class RangeSliderThumbLayer: CALayer
73 | 74 |
75 |
76 |

the thumb for upper , lower bounds

77 | 78 |
79 |
80 |
81 |
    82 |
  • 83 |
    84 | 85 | 86 | 87 | highlighted 88 | 89 |
    90 |
    91 |
    92 |
    93 |
    94 |
    95 |

    whether this thumb is currently highlighted i.e. touched by user

    96 | 97 |
    98 |
    99 |

    Declaration

    100 |
    101 |

    Swift

    102 |
    public var highlighted: Bool = false
    103 | 104 |
    105 |
    106 |
    107 |
    108 |
  • 109 |
  • 110 |
    111 | 112 | 113 | 114 | strokeColor 115 | 116 |
    117 |
    118 |
    119 |
    120 |
    121 |
    122 |

    stroke color

    123 | 124 |
    125 |
    126 |

    Declaration

    127 |
    128 |

    Swift

    129 |
    public var strokeColor: UIColor = UIColor.gray
    130 | 131 |
    132 |
    133 |
    134 |
    135 |
  • 136 |
  • 137 |
    138 | 139 | 140 | 141 | lineWidth 142 | 143 |
    144 |
    145 |
    146 |
    147 |
    148 |
    149 |

    line width

    150 | 151 |
    152 |
    153 |

    Declaration

    154 |
    155 |

    Swift

    156 |
    public var lineWidth: CGFloat = 0.5
    157 | 158 |
    159 |
    160 |
    161 |
    162 |
  • 163 |
  • 164 |
    165 | 166 | 167 | 168 | draw(in:) 169 | 170 |
    171 |
    172 |
    173 |
    174 |
    175 |
    176 |

    draw the thumb

    177 | 178 |
    179 |

    Parameter

    180 | Parameter ctx: current graphics context 181 | 182 |
    183 | 184 |
    185 |
    186 |

    Declaration

    187 |
    188 |

    Swift

    189 |
    override open func draw(in ctx: CGContext)
    190 | 191 |
    192 |
    193 |
    194 |

    Parameters

    195 | 196 | 197 | 198 | 203 | 209 | 210 | 211 |
    199 | 200 | ctx 201 | 202 | 204 |
    205 |

    current graphics context

    206 | 207 |
    208 |
    212 |
    213 |
    214 |
    215 |
  • 216 |
217 |
218 |
219 |
220 | 224 |
225 |
226 | 227 | 228 | 229 | -------------------------------------------------------------------------------- /NHRangeSlider/NHRangeSlider/NHRangeSliderView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NHRangeSliderView.swift 3 | // NHRangeSlider 4 | // 5 | // Created by Hung on 17/12/16. 6 | // Copyright © 2016 Hung. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | /// enum for label positions 12 | public enum NHSliderLabelStyle : Int { 13 | /// lower and upper labels stick to the left and right of slider 14 | case STICKY 15 | 16 | /// lower and upper labels follow position of lower and upper thumbs 17 | case FOLLOW 18 | } 19 | 20 | /// delegate for changed value 21 | public protocol NHRangeSliderViewDelegate: class { 22 | /// slider value changed 23 | func sliderValueChanged(slider: NHRangeSlider?) 24 | } 25 | 26 | /// optional implementation 27 | public extension NHRangeSliderViewDelegate{ 28 | func sliderValueChanged(slider: NHRangeSlider?){} 29 | } 30 | 31 | /// Range slider with labels for upper and lower thumbs, title label and configurable step value (optional) 32 | open class NHRangeSliderView: UIView { 33 | 34 | //MARK: properties 35 | 36 | open var delegate: NHRangeSliderViewDelegate? = nil 37 | 38 | /// Range slider 39 | open var rangeSlider : NHRangeSlider? = nil 40 | 41 | /// Display title 42 | open var titleLabel : UILabel? = nil 43 | 44 | // lower value label for displaying selected lower value 45 | open var lowerLabel : UILabel? = nil 46 | 47 | /// upper value label for displaying selected upper value 48 | open var upperLabel : UILabel? = nil 49 | 50 | /// display format for lower value. Default to %.0f to display value as Int 51 | open var lowerDisplayStringFormat: String = "%.0f" { 52 | didSet { 53 | updateLabelDisplay() 54 | } 55 | } 56 | 57 | /// display format for upper value. Default to %.0f to display value as Int 58 | open var upperDisplayStringFormat: String = "%.0f" { 59 | didSet { 60 | updateLabelDisplay() 61 | } 62 | } 63 | 64 | /// vertical spacing 65 | open var spacing: CGFloat = 4.0 66 | 67 | /// position of thumb labels. Set to STICKY to stick to left and right positions. Set to FOLLOW to follow left and right thumbs 68 | open var thumbLabelStyle: NHSliderLabelStyle = .STICKY 69 | 70 | /// minimum value 71 | @IBInspectable open var minimumValue: Double = 0.0 { 72 | didSet { 73 | self.rangeSlider?.minimumValue = minimumValue 74 | } 75 | } 76 | 77 | /// max value 78 | @IBInspectable open var maximumValue: Double = 100.0 { 79 | didSet { 80 | self.rangeSlider?.maximumValue = maximumValue 81 | } 82 | } 83 | 84 | /// value for lower thumb 85 | @IBInspectable open var lowerValue: Double = 0.0 { 86 | didSet { 87 | self.rangeSlider?.lowerValue = lowerValue 88 | self.updateLabelDisplay() 89 | } 90 | } 91 | 92 | /// value for upper thumb 93 | @IBInspectable open var upperValue: Double = 100.0 { 94 | didSet { 95 | self.rangeSlider?.upperValue = upperValue 96 | self.updateLabelDisplay() 97 | } 98 | } 99 | 100 | /// stepValue. If set, will snap to discrete step points along the slider . Default to nil 101 | @IBInspectable open var stepValue: Double? = nil { 102 | didSet { 103 | self.rangeSlider?.stepValue = stepValue 104 | } 105 | } 106 | 107 | /// minimum distance between the upper and lower thumbs. 108 | open var gapBetweenThumbs: Double = 2.0 { 109 | didSet { 110 | self.rangeSlider?.gapBetweenThumbs = gapBetweenThumbs 111 | } 112 | } 113 | 114 | /// tint color for track between 2 thumbs 115 | @IBInspectable open var trackTintColor: UIColor = UIColor(white: 0.9, alpha: 1.0) { 116 | didSet { 117 | self.rangeSlider?.trackTintColor = trackTintColor 118 | } 119 | } 120 | 121 | 122 | /// track highlight tint color 123 | @IBInspectable open var trackHighlightTintColor: UIColor = UIColor(red: 0.0, green: 0.45, blue: 0.94, alpha: 1.0) { 124 | didSet { 125 | self.rangeSlider?.trackHighlightTintColor = trackHighlightTintColor 126 | } 127 | } 128 | 129 | 130 | /// thumb tint color 131 | @IBInspectable open var thumbTintColor: UIColor = UIColor.white { 132 | didSet { 133 | self.rangeSlider?.thumbTintColor = thumbTintColor 134 | } 135 | } 136 | 137 | /// thumb border color 138 | @IBInspectable open var thumbBorderColor: UIColor = UIColor.gray { 139 | didSet { 140 | self.rangeSlider?.thumbBorderColor = thumbBorderColor 141 | } 142 | } 143 | 144 | 145 | /// thumb border width 146 | @IBInspectable open var thumbBorderWidth: CGFloat = 0.5 { 147 | didSet { 148 | self.rangeSlider?.thumbBorderWidth = thumbBorderWidth 149 | 150 | } 151 | } 152 | 153 | /// set 0.0 for square thumbs to 1.0 for circle thumbs 154 | @IBInspectable open var curvaceousness: CGFloat = 1.0 { 155 | didSet { 156 | self.rangeSlider?.curvaceousness = curvaceousness 157 | } 158 | } 159 | 160 | /// thumb width and height 161 | @IBInspectable open var thumbSize: CGFloat = 32.0 { 162 | didSet { 163 | if let slider = self.rangeSlider { 164 | var oldFrame = slider.frame 165 | oldFrame.size.height = thumbSize 166 | slider.frame = oldFrame 167 | } 168 | } 169 | } 170 | 171 | //MARK: init 172 | 173 | public override init(frame: CGRect) { 174 | super.init(frame: frame) 175 | 176 | setup() 177 | } 178 | 179 | required public init?(coder aDecoder: NSCoder) { 180 | super.init(coder: aDecoder) 181 | 182 | setup() 183 | } 184 | 185 | /// setup 186 | open func setup() { 187 | self.autoresizingMask = [.flexibleWidth] 188 | 189 | self.titleLabel = UILabel(frame: .zero) 190 | self.titleLabel?.numberOfLines = 1 191 | self.titleLabel?.font = UIFont.boldSystemFont(ofSize: 16.0) 192 | self.titleLabel?.text = "" 193 | self.addSubview(self.titleLabel!) 194 | 195 | self.lowerLabel = UILabel(frame: .zero) 196 | self.lowerLabel?.numberOfLines = 1 197 | self.lowerLabel?.font = UIFont.systemFont(ofSize: 14.0) 198 | self.lowerLabel?.text = "" 199 | self.lowerLabel?.textAlignment = .center 200 | self.addSubview(self.lowerLabel!) 201 | 202 | self.upperLabel = UILabel(frame: .zero) 203 | self.upperLabel?.numberOfLines = 1 204 | self.upperLabel?.font = UIFont.systemFont(ofSize: 14.0) 205 | self.upperLabel?.text = "" 206 | self.upperLabel?.textAlignment = .center 207 | self.addSubview(self.upperLabel!) 208 | 209 | self.rangeSlider = NHRangeSlider(frame: .zero) 210 | self.addSubview(self.rangeSlider!) 211 | 212 | self.updateLabelDisplay() 213 | 214 | self.rangeSlider?.addTarget(self, action: #selector(self.rangeSliderValueChanged(_:)), for: .valueChanged) 215 | } 216 | 217 | //MARK: range slider delegage 218 | 219 | /// Range slider change events. Upper / lower labels will be updated accordingly. 220 | /// Selected value for filterItem will also be updated 221 | /// 222 | /// - Parameter rangeSlider: the changed rangeSlider 223 | open func rangeSliderValueChanged(_ rangeSlider: NHRangeSlider) { 224 | 225 | delegate?.sliderValueChanged(slider: rangeSlider) 226 | 227 | self.updateLabelDisplay() 228 | 229 | } 230 | 231 | //MARK: - 232 | 233 | // update labels display 234 | open func updateLabelDisplay() { 235 | 236 | self.lowerLabel?.text = String(format: self.lowerDisplayStringFormat, rangeSlider!.lowerValue ) 237 | self.upperLabel?.text = String(format: self.upperDisplayStringFormat, rangeSlider!.upperValue ) 238 | 239 | if self.lowerLabel != nil { 240 | 241 | // for stepped value we animate the labels 242 | if self.stepValue != nil && self.thumbLabelStyle == .FOLLOW { 243 | UIView.animate(withDuration: 0.1, animations: { 244 | self.layoutSubviews() 245 | }) 246 | } 247 | else { 248 | self.setNeedsLayout() 249 | self.layoutIfNeeded() 250 | } 251 | } 252 | } 253 | 254 | /// layout subviews 255 | override open func layoutSubviews() { 256 | super.layoutSubviews() 257 | 258 | if let titleLabel = self.titleLabel , let lowerLabel = self.lowerLabel , 259 | let upperLabel = self.upperLabel , let rangeSlider = self.rangeSlider { 260 | 261 | let commonWidth = self.bounds.width 262 | var titleLabelMaxY : CGFloat = 0 263 | 264 | if !titleLabel.isHidden && titleLabel.text != nil && titleLabel.text!.characters.count > 0 { 265 | titleLabel.frame = CGRect(x: 0, 266 | y: 0, 267 | width: commonWidth , 268 | height: (titleLabel.font.lineHeight + self.spacing ) ) 269 | 270 | titleLabelMaxY = titleLabel.frame.origin.y + titleLabel.frame.size.height 271 | } 272 | 273 | rangeSlider.frame = CGRect(x: 0, 274 | y: titleLabelMaxY + lowerLabel.font.lineHeight + self.spacing, 275 | width: commonWidth , 276 | height: thumbSize ) 277 | 278 | let lowerWidth = self.estimatelabelSize(font: lowerLabel.font, string: lowerLabel.text!, constrainedToWidth: Double(commonWidth)).width 279 | let upperWidth = self.estimatelabelSize(font: upperLabel.font, string: upperLabel.text!, constrainedToWidth: Double(commonWidth)).width 280 | 281 | var lowerLabelX : CGFloat = 0 282 | var upperLabelX : CGFloat = 0 283 | 284 | 285 | if self.thumbLabelStyle == .FOLLOW { 286 | lowerLabelX = rangeSlider.lowerThumbLayer.frame.midX - lowerWidth / 2 287 | upperLabelX = rangeSlider.upperThumbLayer.frame.midX - upperWidth / 2 288 | } 289 | else { 290 | // fix lower label to left and upper label to right 291 | lowerLabelX = rangeSlider.frame.origin.x + self.spacing 292 | upperLabelX = rangeSlider.frame.origin.x + rangeSlider.frame.size.width - thumbSize + self.spacing 293 | } 294 | 295 | lowerLabel.frame = CGRect( x: lowerLabelX, 296 | y: titleLabelMaxY, 297 | width: lowerWidth , 298 | height: lowerLabel.font.lineHeight + self.spacing ) 299 | 300 | upperLabel.frame = CGRect( x: upperLabelX, 301 | y: titleLabelMaxY, 302 | width: upperWidth , 303 | height: upperLabel.font.lineHeight + self.spacing ) 304 | 305 | } 306 | 307 | } 308 | 309 | // return the best size that fit within the box 310 | open override func sizeThatFits(_ size: CGSize) -> CGSize { 311 | 312 | if let titleLabel = self.titleLabel , let lowerLabel = self.lowerLabel { 313 | 314 | var height : CGFloat = 0 315 | 316 | var titleLabelMaxY : CGFloat = 0 317 | 318 | if !titleLabel.isHidden && titleLabel.text != nil && titleLabel.text!.characters.count > 0 { 319 | titleLabelMaxY = titleLabel.font.lineHeight + self.spacing 320 | } 321 | 322 | height = titleLabelMaxY + lowerLabel.font.lineHeight + self.spacing + thumbSize 323 | 324 | return CGSize(width: size.width, height: height) 325 | 326 | } 327 | 328 | return size 329 | 330 | } 331 | 332 | /// get size for string of this font 333 | /// 334 | /// - parameter font: font 335 | /// - parameter string: a string 336 | /// - parameter width: constrained width 337 | /// 338 | /// - returns: string size for constrained width 339 | private func estimatelabelSize(font: UIFont,string: String, constrainedToWidth width: Double) -> CGSize{ 340 | return string.boundingRect(with: CGSize(width: width, height: DBL_MAX), 341 | options: NSStringDrawingOptions.usesLineFragmentOrigin, 342 | attributes: [NSFontAttributeName: font], 343 | context: nil).size 344 | 345 | } 346 | 347 | 348 | } 349 | -------------------------------------------------------------------------------- /NHRangeSlider/NHRangeSlider/NHRangeSlider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NHRangeSlider.swift 3 | // NHRangeSlider 4 | // 5 | // Created by Hung on 17/12/16. 6 | // Copyright © 2016 Hung. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import QuartzCore 11 | 12 | /// Range slider track layer. Responsible for drawing the horizontal track 13 | public class RangeSliderTrackLayer: CALayer { 14 | 15 | /// owner slider 16 | weak var rangeSlider: NHRangeSlider? 17 | 18 | /// draw the track between 2 thumbs 19 | /// 20 | /// - Parameter ctx: current graphics context 21 | override open func draw(in ctx: CGContext) { 22 | guard let slider = rangeSlider else { 23 | return 24 | } 25 | 26 | // Clip 27 | let cornerRadius = bounds.height * slider.curvaceousness / 2.0 28 | let path = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius) 29 | ctx.addPath(path.cgPath) 30 | 31 | // Fill the track 32 | ctx.setFillColor(slider.trackTintColor.cgColor) 33 | ctx.addPath(path.cgPath) 34 | ctx.fillPath() 35 | 36 | // Fill the highlighted range 37 | ctx.setFillColor(slider.trackHighlightTintColor.cgColor) 38 | let lowerValuePosition = CGFloat(slider.positionForValue(slider.lowerValue)) 39 | let upperValuePosition = CGFloat(slider.positionForValue(slider.upperValue)) 40 | let rect = CGRect(x: lowerValuePosition, y: 0.0, width: upperValuePosition - lowerValuePosition, height: bounds.height) 41 | ctx.fill(rect) 42 | } 43 | } 44 | 45 | /// the thumb for upper , lower bounds 46 | public class RangeSliderThumbLayer: CALayer { 47 | 48 | /// owner slider 49 | weak var rangeSlider: NHRangeSlider? 50 | 51 | /// whether this thumb is currently highlighted i.e. touched by user 52 | public var highlighted: Bool = false { 53 | didSet { 54 | setNeedsDisplay() 55 | } 56 | } 57 | 58 | /// stroke color 59 | public var strokeColor: UIColor = UIColor.gray { 60 | didSet { 61 | setNeedsDisplay() 62 | } 63 | } 64 | 65 | /// line width 66 | public var lineWidth: CGFloat = 0.5 { 67 | didSet { 68 | setNeedsDisplay() 69 | } 70 | } 71 | 72 | 73 | /// draw the thumb 74 | /// 75 | /// - Parameter ctx: current graphics context 76 | override open func draw(in ctx: CGContext) { 77 | guard let slider = rangeSlider else { 78 | return 79 | } 80 | 81 | let thumbFrame = bounds.insetBy(dx: 2.0, dy: 2.0) 82 | let cornerRadius = thumbFrame.height * slider.curvaceousness / 2.0 83 | let thumbPath = UIBezierPath(roundedRect: thumbFrame, cornerRadius: cornerRadius) 84 | 85 | // Fill 86 | ctx.setFillColor(slider.thumbTintColor.cgColor) 87 | ctx.addPath(thumbPath.cgPath) 88 | ctx.fillPath() 89 | 90 | // Outline 91 | ctx.setStrokeColor(strokeColor.cgColor) 92 | ctx.setLineWidth(lineWidth) 93 | ctx.addPath(thumbPath.cgPath) 94 | ctx.strokePath() 95 | 96 | if highlighted { 97 | ctx.setFillColor(UIColor(white: 0.0, alpha: 0.1).cgColor) 98 | ctx.addPath(thumbPath.cgPath) 99 | ctx.fillPath() 100 | } 101 | } 102 | } 103 | 104 | 105 | /// Range slider view with upper, lower bounds 106 | @IBDesignable 107 | open class NHRangeSlider: UIControl { 108 | 109 | //MARK: properties 110 | 111 | /// minimum value 112 | @IBInspectable open var minimumValue: Double = 0.0 { 113 | willSet(newValue) { 114 | assert(newValue < maximumValue, "NHRangeSlider: minimumValue should be lower than maximumValue") 115 | } 116 | didSet { 117 | updateLayerFrames() 118 | } 119 | } 120 | 121 | /// max value 122 | @IBInspectable open var maximumValue: Double = 100.0 { 123 | willSet(newValue) { 124 | assert(newValue > minimumValue, "NHRangeSlider: maximumValue should be greater than minimumValue") 125 | } 126 | didSet { 127 | updateLayerFrames() 128 | } 129 | } 130 | 131 | /// value for lower thumb 132 | @IBInspectable open var lowerValue: Double = 0.0 { 133 | didSet { 134 | if lowerValue < minimumValue { 135 | lowerValue = minimumValue 136 | } 137 | updateLayerFrames() 138 | } 139 | } 140 | 141 | /// value for upper thumb 142 | @IBInspectable open var upperValue: Double = 100.0 { 143 | didSet { 144 | if upperValue > maximumValue { 145 | upperValue = maximumValue 146 | } 147 | updateLayerFrames() 148 | } 149 | } 150 | 151 | 152 | /// stepValue. If set, will snap to discrete step points along the slider . Default to nil 153 | @IBInspectable open var stepValue: Double? = nil { 154 | willSet(newValue) { 155 | if newValue != nil { 156 | assert(newValue! > 0, "NHRangeSlider: stepValue must be positive") 157 | } 158 | } 159 | didSet { 160 | if let val = stepValue { 161 | if val <= 0 { 162 | stepValue = nil 163 | } 164 | } 165 | 166 | updateLayerFrames() 167 | } 168 | } 169 | 170 | 171 | 172 | /// minimum distance between the upper and lower thumbs. 173 | @IBInspectable open var gapBetweenThumbs: Double = 2.0 174 | 175 | /// tint color for track between 2 thumbs 176 | @IBInspectable open var trackTintColor: UIColor = UIColor(white: 0.9, alpha: 1.0) { 177 | didSet { 178 | trackLayer.setNeedsDisplay() 179 | } 180 | } 181 | 182 | /// track highlight tint color 183 | @IBInspectable open var trackHighlightTintColor: UIColor = UIColor(red: 0.0, green: 0.45, blue: 0.94, alpha: 1.0) { 184 | didSet { 185 | trackLayer.setNeedsDisplay() 186 | } 187 | } 188 | 189 | 190 | /// thumb tint color 191 | @IBInspectable open var thumbTintColor: UIColor = UIColor.white { 192 | didSet { 193 | lowerThumbLayer.setNeedsDisplay() 194 | upperThumbLayer.setNeedsDisplay() 195 | } 196 | } 197 | 198 | /// thumb border color 199 | @IBInspectable open var thumbBorderColor: UIColor = UIColor.gray { 200 | didSet { 201 | lowerThumbLayer.strokeColor = thumbBorderColor 202 | upperThumbLayer.strokeColor = thumbBorderColor 203 | } 204 | } 205 | 206 | 207 | /// thumb border width 208 | @IBInspectable open var thumbBorderWidth: CGFloat = 0.5 { 209 | didSet { 210 | lowerThumbLayer.lineWidth = thumbBorderWidth 211 | upperThumbLayer.lineWidth = thumbBorderWidth 212 | } 213 | } 214 | 215 | /// set 0.0 for square thumbs to 1.0 for circle thumbs 216 | @IBInspectable open var curvaceousness: CGFloat = 1.0 { 217 | didSet { 218 | if curvaceousness < 0.0 { 219 | curvaceousness = 0.0 220 | } 221 | 222 | if curvaceousness > 1.0 { 223 | curvaceousness = 1.0 224 | } 225 | 226 | trackLayer.setNeedsDisplay() 227 | lowerThumbLayer.setNeedsDisplay() 228 | upperThumbLayer.setNeedsDisplay() 229 | } 230 | } 231 | 232 | 233 | /// previous touch location 234 | fileprivate var previouslocation = CGPoint() 235 | 236 | /// track layer 237 | fileprivate let trackLayer = RangeSliderTrackLayer() 238 | 239 | /// lower thumb layer 240 | public let lowerThumbLayer = RangeSliderThumbLayer() 241 | 242 | /// upper thumb layer 243 | public let upperThumbLayer = RangeSliderThumbLayer() 244 | 245 | /// thumb width 246 | fileprivate var thumbWidth: CGFloat { 247 | return CGFloat(bounds.height) 248 | } 249 | 250 | /// frame 251 | override open var frame: CGRect { 252 | didSet { 253 | updateLayerFrames() 254 | } 255 | } 256 | 257 | //MARK: init methods 258 | override public init(frame: CGRect) { 259 | super.init(frame: frame) 260 | initializeLayers() 261 | } 262 | 263 | required public init?(coder: NSCoder) { 264 | super.init(coder: coder) 265 | initializeLayers() 266 | } 267 | 268 | //MARK: layers 269 | 270 | /// layout sub layers 271 | /// 272 | /// - Parameter of: layer 273 | override open func layoutSublayers(of: CALayer) { 274 | super.layoutSublayers(of:layer) 275 | updateLayerFrames() 276 | } 277 | 278 | /// init layers 279 | fileprivate func initializeLayers() { 280 | layer.backgroundColor = UIColor.clear.cgColor 281 | 282 | trackLayer.rangeSlider = self 283 | trackLayer.contentsScale = UIScreen.main.scale 284 | layer.addSublayer(trackLayer) 285 | 286 | lowerThumbLayer.rangeSlider = self 287 | lowerThumbLayer.contentsScale = UIScreen.main.scale 288 | layer.addSublayer(lowerThumbLayer) 289 | 290 | upperThumbLayer.rangeSlider = self 291 | upperThumbLayer.contentsScale = UIScreen.main.scale 292 | layer.addSublayer(upperThumbLayer) 293 | } 294 | 295 | /// update layer frames 296 | open func updateLayerFrames() { 297 | CATransaction.begin() 298 | CATransaction.setDisableActions(true) 299 | 300 | trackLayer.frame = bounds.insetBy(dx: 0.0, dy: bounds.height/3) 301 | trackLayer.setNeedsDisplay() 302 | 303 | let lowerThumbCenter = CGFloat(positionForValue(lowerValue)) 304 | lowerThumbLayer.frame = CGRect(x: lowerThumbCenter - thumbWidth/2.0, y: 0.0, width: thumbWidth, height: thumbWidth) 305 | lowerThumbLayer.setNeedsDisplay() 306 | 307 | let upperThumbCenter = CGFloat(positionForValue(upperValue)) 308 | upperThumbLayer.frame = CGRect(x: upperThumbCenter - thumbWidth/2.0, y: 0.0, width: thumbWidth, height: thumbWidth) 309 | upperThumbLayer.setNeedsDisplay() 310 | 311 | CATransaction.commit() 312 | } 313 | 314 | /// thumb x position for new value 315 | open func positionForValue(_ value: Double) -> Double { 316 | if (maximumValue == minimumValue) { 317 | return 0 318 | } 319 | 320 | return Double(bounds.width - thumbWidth) * (value - minimumValue) / (maximumValue - minimumValue) 321 | + Double(thumbWidth/2.0) 322 | } 323 | 324 | 325 | /// bound new value within lower and upper value 326 | /// 327 | /// - Parameters: 328 | /// - value: value to set 329 | /// - lowerValue: lower value 330 | /// - upperValue: upper value 331 | /// - Returns: current value 332 | open func boundValue(_ value: Double, toLowerValue lowerValue: Double, upperValue: Double) -> Double { 333 | return min(max(value, lowerValue), upperValue) 334 | } 335 | 336 | 337 | // MARK: - Touches 338 | 339 | /// begin tracking 340 | override open func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { 341 | previouslocation = touch.location(in: self) 342 | 343 | // set highlighted positions for lower and upper thumbs 344 | if lowerThumbLayer.frame.contains(previouslocation) { 345 | lowerThumbLayer.highlighted = true 346 | } 347 | 348 | if upperThumbLayer.frame.contains(previouslocation) { 349 | upperThumbLayer.highlighted = true 350 | } 351 | 352 | return lowerThumbLayer.highlighted || upperThumbLayer.highlighted 353 | } 354 | 355 | /// update positions for lower and upper thumbs 356 | override open func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { 357 | let location = touch.location(in: self) 358 | 359 | // Determine by how much the user has dragged 360 | let deltaLocation = Double(location.x - previouslocation.x) 361 | var deltaValue : Double = 0 362 | 363 | if (bounds.width != bounds.height) { 364 | deltaValue = (maximumValue - minimumValue) * deltaLocation / Double(bounds.width - bounds.height) 365 | } 366 | 367 | 368 | previouslocation = location 369 | 370 | // if both are highlighted. we need to decide which direction to drag 371 | if lowerThumbLayer.highlighted && upperThumbLayer.highlighted { 372 | 373 | if deltaLocation > 0 { 374 | // left to right 375 | upperValue = boundValue(upperValue + deltaValue, toLowerValue: lowerValue + gapBetweenThumbs, upperValue: maximumValue) 376 | } 377 | else { 378 | // right to left 379 | lowerValue = boundValue(lowerValue + deltaValue, toLowerValue: minimumValue, upperValue: upperValue - gapBetweenThumbs) 380 | } 381 | } 382 | else { 383 | 384 | // Update the values 385 | if lowerThumbLayer.highlighted { 386 | lowerValue = boundValue(lowerValue + deltaValue, toLowerValue: minimumValue, upperValue: upperValue - gapBetweenThumbs) 387 | } else if upperThumbLayer.highlighted { 388 | upperValue = boundValue(upperValue + deltaValue, toLowerValue: lowerValue + gapBetweenThumbs, upperValue: maximumValue) 389 | } 390 | } 391 | 392 | // only send changed value if stepValue is not set. We will trigger this later in endTracking 393 | if stepValue == nil { 394 | sendActions(for: .valueChanged) 395 | } 396 | 397 | return true 398 | } 399 | 400 | /// end touch tracking. Unhighlight the two thumbs 401 | override open func endTracking(_ touch: UITouch?, with event: UIEvent?) { 402 | lowerThumbLayer.highlighted = false 403 | upperThumbLayer.highlighted = false 404 | 405 | // let slider snap after user stop dragging 406 | if let stepValue = stepValue { 407 | lowerValue = round(lowerValue / stepValue) * stepValue 408 | upperValue = round(upperValue / stepValue) * stepValue 409 | sendActions(for: .valueChanged) 410 | } 411 | 412 | 413 | } 414 | 415 | } 416 | -------------------------------------------------------------------------------- /NHRangeSlider/NHRangeSlider.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | BDBEB38F1E06606100FE2D6F /* NHRangeSlider.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BDBEB3851E06606100FE2D6F /* NHRangeSlider.framework */; }; 11 | BDBEB3941E06606100FE2D6F /* NHRangeSliderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBEB3931E06606100FE2D6F /* NHRangeSliderTests.swift */; }; 12 | BDBEB3961E06606100FE2D6F /* NHRangeSlider.h in Headers */ = {isa = PBXBuildFile; fileRef = BDBEB3881E06606100FE2D6F /* NHRangeSlider.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | BDBEB3A11E06608900FE2D6F /* NHRangeSliderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBEB39F1E06608900FE2D6F /* NHRangeSliderView.swift */; }; 14 | BDBEB3A21E06608900FE2D6F /* NHRangeSlider.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDBEB3A01E06608900FE2D6F /* NHRangeSlider.swift */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXContainerItemProxy section */ 18 | BDBEB3901E06606100FE2D6F /* PBXContainerItemProxy */ = { 19 | isa = PBXContainerItemProxy; 20 | containerPortal = BDBEB37C1E06606100FE2D6F /* Project object */; 21 | proxyType = 1; 22 | remoteGlobalIDString = BDBEB3841E06606100FE2D6F; 23 | remoteInfo = NHRangeSlider; 24 | }; 25 | /* End PBXContainerItemProxy section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | BDBEB3851E06606100FE2D6F /* NHRangeSlider.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NHRangeSlider.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | BDBEB3881E06606100FE2D6F /* NHRangeSlider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NHRangeSlider.h; sourceTree = ""; }; 30 | BDBEB3891E06606100FE2D6F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 31 | BDBEB38E1E06606100FE2D6F /* NHRangeSliderTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NHRangeSliderTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | BDBEB3931E06606100FE2D6F /* NHRangeSliderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NHRangeSliderTests.swift; sourceTree = ""; }; 33 | BDBEB3951E06606100FE2D6F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 34 | BDBEB39F1E06608900FE2D6F /* NHRangeSliderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NHRangeSliderView.swift; sourceTree = ""; }; 35 | BDBEB3A01E06608900FE2D6F /* NHRangeSlider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NHRangeSlider.swift; sourceTree = ""; }; 36 | /* End PBXFileReference section */ 37 | 38 | /* Begin PBXFrameworksBuildPhase section */ 39 | BDBEB3811E06606100FE2D6F /* Frameworks */ = { 40 | isa = PBXFrameworksBuildPhase; 41 | buildActionMask = 2147483647; 42 | files = ( 43 | ); 44 | runOnlyForDeploymentPostprocessing = 0; 45 | }; 46 | BDBEB38B1E06606100FE2D6F /* Frameworks */ = { 47 | isa = PBXFrameworksBuildPhase; 48 | buildActionMask = 2147483647; 49 | files = ( 50 | BDBEB38F1E06606100FE2D6F /* NHRangeSlider.framework in Frameworks */, 51 | ); 52 | runOnlyForDeploymentPostprocessing = 0; 53 | }; 54 | /* End PBXFrameworksBuildPhase section */ 55 | 56 | /* Begin PBXGroup section */ 57 | BDBEB37B1E06606100FE2D6F = { 58 | isa = PBXGroup; 59 | children = ( 60 | BDBEB3871E06606100FE2D6F /* NHRangeSlider */, 61 | BDBEB3921E06606100FE2D6F /* NHRangeSliderTests */, 62 | BDBEB3861E06606100FE2D6F /* Products */, 63 | ); 64 | sourceTree = ""; 65 | }; 66 | BDBEB3861E06606100FE2D6F /* Products */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | BDBEB3851E06606100FE2D6F /* NHRangeSlider.framework */, 70 | BDBEB38E1E06606100FE2D6F /* NHRangeSliderTests.xctest */, 71 | ); 72 | name = Products; 73 | sourceTree = ""; 74 | }; 75 | BDBEB3871E06606100FE2D6F /* NHRangeSlider */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | BDBEB39F1E06608900FE2D6F /* NHRangeSliderView.swift */, 79 | BDBEB3A01E06608900FE2D6F /* NHRangeSlider.swift */, 80 | BDBEB3881E06606100FE2D6F /* NHRangeSlider.h */, 81 | BDBEB3891E06606100FE2D6F /* Info.plist */, 82 | ); 83 | path = NHRangeSlider; 84 | sourceTree = ""; 85 | }; 86 | BDBEB3921E06606100FE2D6F /* NHRangeSliderTests */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | BDBEB3931E06606100FE2D6F /* NHRangeSliderTests.swift */, 90 | BDBEB3951E06606100FE2D6F /* Info.plist */, 91 | ); 92 | path = NHRangeSliderTests; 93 | sourceTree = ""; 94 | }; 95 | /* End PBXGroup section */ 96 | 97 | /* Begin PBXHeadersBuildPhase section */ 98 | BDBEB3821E06606100FE2D6F /* Headers */ = { 99 | isa = PBXHeadersBuildPhase; 100 | buildActionMask = 2147483647; 101 | files = ( 102 | BDBEB3961E06606100FE2D6F /* NHRangeSlider.h in Headers */, 103 | ); 104 | runOnlyForDeploymentPostprocessing = 0; 105 | }; 106 | /* End PBXHeadersBuildPhase section */ 107 | 108 | /* Begin PBXNativeTarget section */ 109 | BDBEB3841E06606100FE2D6F /* NHRangeSlider */ = { 110 | isa = PBXNativeTarget; 111 | buildConfigurationList = BDBEB3991E06606100FE2D6F /* Build configuration list for PBXNativeTarget "NHRangeSlider" */; 112 | buildPhases = ( 113 | BDBEB3801E06606100FE2D6F /* Sources */, 114 | BDBEB3811E06606100FE2D6F /* Frameworks */, 115 | BDBEB3821E06606100FE2D6F /* Headers */, 116 | BDBEB3831E06606100FE2D6F /* Resources */, 117 | ); 118 | buildRules = ( 119 | ); 120 | dependencies = ( 121 | ); 122 | name = NHRangeSlider; 123 | productName = NHRangeSlider; 124 | productReference = BDBEB3851E06606100FE2D6F /* NHRangeSlider.framework */; 125 | productType = "com.apple.product-type.framework"; 126 | }; 127 | BDBEB38D1E06606100FE2D6F /* NHRangeSliderTests */ = { 128 | isa = PBXNativeTarget; 129 | buildConfigurationList = BDBEB39C1E06606100FE2D6F /* Build configuration list for PBXNativeTarget "NHRangeSliderTests" */; 130 | buildPhases = ( 131 | BDBEB38A1E06606100FE2D6F /* Sources */, 132 | BDBEB38B1E06606100FE2D6F /* Frameworks */, 133 | BDBEB38C1E06606100FE2D6F /* Resources */, 134 | ); 135 | buildRules = ( 136 | ); 137 | dependencies = ( 138 | BDBEB3911E06606100FE2D6F /* PBXTargetDependency */, 139 | ); 140 | name = NHRangeSliderTests; 141 | productName = NHRangeSliderTests; 142 | productReference = BDBEB38E1E06606100FE2D6F /* NHRangeSliderTests.xctest */; 143 | productType = "com.apple.product-type.bundle.unit-test"; 144 | }; 145 | /* End PBXNativeTarget section */ 146 | 147 | /* Begin PBXProject section */ 148 | BDBEB37C1E06606100FE2D6F /* Project object */ = { 149 | isa = PBXProject; 150 | attributes = { 151 | LastSwiftUpdateCheck = 0820; 152 | LastUpgradeCheck = 0820; 153 | ORGANIZATIONNAME = Hung; 154 | TargetAttributes = { 155 | BDBEB3841E06606100FE2D6F = { 156 | CreatedOnToolsVersion = 8.2; 157 | DevelopmentTeam = NKN6QECX9M; 158 | LastSwiftMigration = 0820; 159 | ProvisioningStyle = Automatic; 160 | }; 161 | BDBEB38D1E06606100FE2D6F = { 162 | CreatedOnToolsVersion = 8.2; 163 | DevelopmentTeam = NKN6QECX9M; 164 | ProvisioningStyle = Automatic; 165 | }; 166 | }; 167 | }; 168 | buildConfigurationList = BDBEB37F1E06606100FE2D6F /* Build configuration list for PBXProject "NHRangeSlider" */; 169 | compatibilityVersion = "Xcode 3.2"; 170 | developmentRegion = English; 171 | hasScannedForEncodings = 0; 172 | knownRegions = ( 173 | en, 174 | ); 175 | mainGroup = BDBEB37B1E06606100FE2D6F; 176 | productRefGroup = BDBEB3861E06606100FE2D6F /* Products */; 177 | projectDirPath = ""; 178 | projectRoot = ""; 179 | targets = ( 180 | BDBEB3841E06606100FE2D6F /* NHRangeSlider */, 181 | BDBEB38D1E06606100FE2D6F /* NHRangeSliderTests */, 182 | ); 183 | }; 184 | /* End PBXProject section */ 185 | 186 | /* Begin PBXResourcesBuildPhase section */ 187 | BDBEB3831E06606100FE2D6F /* Resources */ = { 188 | isa = PBXResourcesBuildPhase; 189 | buildActionMask = 2147483647; 190 | files = ( 191 | ); 192 | runOnlyForDeploymentPostprocessing = 0; 193 | }; 194 | BDBEB38C1E06606100FE2D6F /* Resources */ = { 195 | isa = PBXResourcesBuildPhase; 196 | buildActionMask = 2147483647; 197 | files = ( 198 | ); 199 | runOnlyForDeploymentPostprocessing = 0; 200 | }; 201 | /* End PBXResourcesBuildPhase section */ 202 | 203 | /* Begin PBXSourcesBuildPhase section */ 204 | BDBEB3801E06606100FE2D6F /* Sources */ = { 205 | isa = PBXSourcesBuildPhase; 206 | buildActionMask = 2147483647; 207 | files = ( 208 | BDBEB3A21E06608900FE2D6F /* NHRangeSlider.swift in Sources */, 209 | BDBEB3A11E06608900FE2D6F /* NHRangeSliderView.swift in Sources */, 210 | ); 211 | runOnlyForDeploymentPostprocessing = 0; 212 | }; 213 | BDBEB38A1E06606100FE2D6F /* Sources */ = { 214 | isa = PBXSourcesBuildPhase; 215 | buildActionMask = 2147483647; 216 | files = ( 217 | BDBEB3941E06606100FE2D6F /* NHRangeSliderTests.swift in Sources */, 218 | ); 219 | runOnlyForDeploymentPostprocessing = 0; 220 | }; 221 | /* End PBXSourcesBuildPhase section */ 222 | 223 | /* Begin PBXTargetDependency section */ 224 | BDBEB3911E06606100FE2D6F /* PBXTargetDependency */ = { 225 | isa = PBXTargetDependency; 226 | target = BDBEB3841E06606100FE2D6F /* NHRangeSlider */; 227 | targetProxy = BDBEB3901E06606100FE2D6F /* PBXContainerItemProxy */; 228 | }; 229 | /* End PBXTargetDependency section */ 230 | 231 | /* Begin XCBuildConfiguration section */ 232 | BDBEB3971E06606100FE2D6F /* Debug */ = { 233 | isa = XCBuildConfiguration; 234 | buildSettings = { 235 | ALWAYS_SEARCH_USER_PATHS = NO; 236 | CLANG_ANALYZER_NONNULL = YES; 237 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 238 | CLANG_CXX_LIBRARY = "libc++"; 239 | CLANG_ENABLE_MODULES = YES; 240 | CLANG_ENABLE_OBJC_ARC = YES; 241 | CLANG_WARN_BOOL_CONVERSION = YES; 242 | CLANG_WARN_CONSTANT_CONVERSION = YES; 243 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 244 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 245 | CLANG_WARN_EMPTY_BODY = YES; 246 | CLANG_WARN_ENUM_CONVERSION = YES; 247 | CLANG_WARN_INFINITE_RECURSION = YES; 248 | CLANG_WARN_INT_CONVERSION = YES; 249 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 250 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 251 | CLANG_WARN_UNREACHABLE_CODE = YES; 252 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 253 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 254 | COPY_PHASE_STRIP = NO; 255 | CURRENT_PROJECT_VERSION = 1; 256 | DEBUG_INFORMATION_FORMAT = dwarf; 257 | ENABLE_STRICT_OBJC_MSGSEND = YES; 258 | ENABLE_TESTABILITY = YES; 259 | GCC_C_LANGUAGE_STANDARD = gnu99; 260 | GCC_DYNAMIC_NO_PIC = NO; 261 | GCC_NO_COMMON_BLOCKS = YES; 262 | GCC_OPTIMIZATION_LEVEL = 0; 263 | GCC_PREPROCESSOR_DEFINITIONS = ( 264 | "DEBUG=1", 265 | "$(inherited)", 266 | ); 267 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 268 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 269 | GCC_WARN_UNDECLARED_SELECTOR = YES; 270 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 271 | GCC_WARN_UNUSED_FUNCTION = YES; 272 | GCC_WARN_UNUSED_VARIABLE = YES; 273 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 274 | MTL_ENABLE_DEBUG_INFO = YES; 275 | ONLY_ACTIVE_ARCH = YES; 276 | SDKROOT = iphoneos; 277 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 278 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 279 | TARGETED_DEVICE_FAMILY = "1,2"; 280 | VERSIONING_SYSTEM = "apple-generic"; 281 | VERSION_INFO_PREFIX = ""; 282 | }; 283 | name = Debug; 284 | }; 285 | BDBEB3981E06606100FE2D6F /* Release */ = { 286 | isa = XCBuildConfiguration; 287 | buildSettings = { 288 | ALWAYS_SEARCH_USER_PATHS = NO; 289 | CLANG_ANALYZER_NONNULL = YES; 290 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 291 | CLANG_CXX_LIBRARY = "libc++"; 292 | CLANG_ENABLE_MODULES = YES; 293 | CLANG_ENABLE_OBJC_ARC = YES; 294 | CLANG_WARN_BOOL_CONVERSION = YES; 295 | CLANG_WARN_CONSTANT_CONVERSION = YES; 296 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 297 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 298 | CLANG_WARN_EMPTY_BODY = YES; 299 | CLANG_WARN_ENUM_CONVERSION = YES; 300 | CLANG_WARN_INFINITE_RECURSION = YES; 301 | CLANG_WARN_INT_CONVERSION = YES; 302 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 303 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 304 | CLANG_WARN_UNREACHABLE_CODE = YES; 305 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 306 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 307 | COPY_PHASE_STRIP = NO; 308 | CURRENT_PROJECT_VERSION = 1; 309 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 310 | ENABLE_NS_ASSERTIONS = NO; 311 | ENABLE_STRICT_OBJC_MSGSEND = YES; 312 | GCC_C_LANGUAGE_STANDARD = gnu99; 313 | GCC_NO_COMMON_BLOCKS = YES; 314 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 315 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 316 | GCC_WARN_UNDECLARED_SELECTOR = YES; 317 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 318 | GCC_WARN_UNUSED_FUNCTION = YES; 319 | GCC_WARN_UNUSED_VARIABLE = YES; 320 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 321 | MTL_ENABLE_DEBUG_INFO = NO; 322 | SDKROOT = iphoneos; 323 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 324 | TARGETED_DEVICE_FAMILY = "1,2"; 325 | VALIDATE_PRODUCT = YES; 326 | VERSIONING_SYSTEM = "apple-generic"; 327 | VERSION_INFO_PREFIX = ""; 328 | }; 329 | name = Release; 330 | }; 331 | BDBEB39A1E06606100FE2D6F /* Debug */ = { 332 | isa = XCBuildConfiguration; 333 | buildSettings = { 334 | CLANG_ENABLE_MODULES = YES; 335 | CODE_SIGN_IDENTITY = ""; 336 | DEFINES_MODULE = YES; 337 | DEVELOPMENT_TEAM = NKN6QECX9M; 338 | DYLIB_COMPATIBILITY_VERSION = 1; 339 | DYLIB_CURRENT_VERSION = 1; 340 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 341 | INFOPLIST_FILE = NHRangeSlider/Info.plist; 342 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 343 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 344 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 345 | PRODUCT_BUNDLE_IDENTIFIER = com.ngohung.NHRangeSlider; 346 | PRODUCT_NAME = "$(TARGET_NAME)"; 347 | SKIP_INSTALL = YES; 348 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 349 | SWIFT_VERSION = 3.0; 350 | }; 351 | name = Debug; 352 | }; 353 | BDBEB39B1E06606100FE2D6F /* Release */ = { 354 | isa = XCBuildConfiguration; 355 | buildSettings = { 356 | CLANG_ENABLE_MODULES = YES; 357 | CODE_SIGN_IDENTITY = ""; 358 | DEFINES_MODULE = YES; 359 | DEVELOPMENT_TEAM = NKN6QECX9M; 360 | DYLIB_COMPATIBILITY_VERSION = 1; 361 | DYLIB_CURRENT_VERSION = 1; 362 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 363 | INFOPLIST_FILE = NHRangeSlider/Info.plist; 364 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 365 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 366 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 367 | PRODUCT_BUNDLE_IDENTIFIER = com.ngohung.NHRangeSlider; 368 | PRODUCT_NAME = "$(TARGET_NAME)"; 369 | SKIP_INSTALL = YES; 370 | SWIFT_VERSION = 3.0; 371 | }; 372 | name = Release; 373 | }; 374 | BDBEB39D1E06606100FE2D6F /* Debug */ = { 375 | isa = XCBuildConfiguration; 376 | buildSettings = { 377 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 378 | DEVELOPMENT_TEAM = NKN6QECX9M; 379 | INFOPLIST_FILE = NHRangeSliderTests/Info.plist; 380 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 381 | PRODUCT_BUNDLE_IDENTIFIER = com.ngohung.NHRangeSliderTests; 382 | PRODUCT_NAME = "$(TARGET_NAME)"; 383 | SWIFT_VERSION = 3.0; 384 | }; 385 | name = Debug; 386 | }; 387 | BDBEB39E1E06606100FE2D6F /* Release */ = { 388 | isa = XCBuildConfiguration; 389 | buildSettings = { 390 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 391 | DEVELOPMENT_TEAM = NKN6QECX9M; 392 | INFOPLIST_FILE = NHRangeSliderTests/Info.plist; 393 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 394 | PRODUCT_BUNDLE_IDENTIFIER = com.ngohung.NHRangeSliderTests; 395 | PRODUCT_NAME = "$(TARGET_NAME)"; 396 | SWIFT_VERSION = 3.0; 397 | }; 398 | name = Release; 399 | }; 400 | /* End XCBuildConfiguration section */ 401 | 402 | /* Begin XCConfigurationList section */ 403 | BDBEB37F1E06606100FE2D6F /* Build configuration list for PBXProject "NHRangeSlider" */ = { 404 | isa = XCConfigurationList; 405 | buildConfigurations = ( 406 | BDBEB3971E06606100FE2D6F /* Debug */, 407 | BDBEB3981E06606100FE2D6F /* Release */, 408 | ); 409 | defaultConfigurationIsVisible = 0; 410 | defaultConfigurationName = Release; 411 | }; 412 | BDBEB3991E06606100FE2D6F /* Build configuration list for PBXNativeTarget "NHRangeSlider" */ = { 413 | isa = XCConfigurationList; 414 | buildConfigurations = ( 415 | BDBEB39A1E06606100FE2D6F /* Debug */, 416 | BDBEB39B1E06606100FE2D6F /* Release */, 417 | ); 418 | defaultConfigurationIsVisible = 0; 419 | defaultConfigurationName = Release; 420 | }; 421 | BDBEB39C1E06606100FE2D6F /* Build configuration list for PBXNativeTarget "NHRangeSliderTests" */ = { 422 | isa = XCConfigurationList; 423 | buildConfigurations = ( 424 | BDBEB39D1E06606100FE2D6F /* Debug */, 425 | BDBEB39E1E06606100FE2D6F /* Release */, 426 | ); 427 | defaultConfigurationIsVisible = 0; 428 | defaultConfigurationName = Release; 429 | }; 430 | /* End XCConfigurationList section */ 431 | }; 432 | rootObject = BDBEB37C1E06606100FE2D6F /* Project object */; 433 | } 434 | --------------------------------------------------------------------------------