├── .gitignore ├── .travis.yml ├── LICENSE ├── OKKLineSwift-iOS-Demo ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── OKKLineViewController.swift └── ViewController.swift ├── OKKLineSwift-iOS-DemoTests ├── Info.plist └── OKKLineSwift_iOS_DemoTests.swift ├── OKKLineSwift-macOS-Demo ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ └── Main.storyboard ├── Info.plist └── ViewController.swift ├── OKKLineSwift-macOS-DemoTests ├── Info.plist └── OKKLineSwift_macOS_DemoTests.swift ├── OKKLineSwift.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── OKKLineSwift-iOS-Demo.xcscheme │ ├── OKKLineSwift-macOS-Demo.xcscheme │ └── OKKLineSwift-tvOS-Demo.xcscheme ├── OKKLineSwift ├── Configuration │ ├── OKConfiguration.swift │ └── OKPlatform.swift ├── Models │ ├── Indicators │ │ ├── OKBOLLModel.swift │ │ ├── OKEMAModel.swift │ │ ├── OKEMAVOLUMEModel.swift │ │ ├── OKKDJModel.swift │ │ ├── OKMACDModel.swift │ │ ├── OKMAModel.swift │ │ └── OKMAVOLUMEModel.swift │ └── OKKLineModel.swift ├── Tools │ ├── OKLineBrush.swift │ └── OKMALineBrush.swift └── Views │ ├── AccessoryView │ └── OKKLineAccessoryView.swift │ ├── MainView │ └── OKKLineMainView.swift │ ├── OKKLineDrawView.swift │ ├── OKKLineView.swift │ ├── OKValueView.swift │ ├── SegmentView │ └── OKSegmentView.swift │ └── VolumeView │ └── OKKLineVolumeView.swift ├── README.md ├── README_CN.md ├── Screenshot ├── OKKLineSwift-iOS.gif └── OKKLineSwift-macOS.gif └── Vendors ├── Just └── Just.swift └── SnapKit ├── Constraint.swift ├── ConstraintAttributes.swift ├── ConstraintConfig.swift ├── ConstraintConstantTarget.swift ├── ConstraintDSL.swift ├── ConstraintDescription.swift ├── ConstraintInsetTarget.swift ├── ConstraintInsets.swift ├── ConstraintItem.swift ├── ConstraintLayoutGuide+Extensions.swift ├── ConstraintLayoutGuide.swift ├── ConstraintLayoutGuideDSL.swift ├── ConstraintLayoutSupport.swift ├── ConstraintLayoutSupportDSL.swift ├── ConstraintMaker.swift ├── ConstraintMakerEditable.swift ├── ConstraintMakerExtendable.swift ├── ConstraintMakerFinalizable.swift ├── ConstraintMakerPriortizable.swift ├── ConstraintMakerRelatable.swift ├── ConstraintMultiplierTarget.swift ├── ConstraintOffsetTarget.swift ├── ConstraintPriorityTarget.swift ├── ConstraintRelatableTarget.swift ├── ConstraintRelation.swift ├── ConstraintView+Extensions.swift ├── ConstraintView.swift ├── ConstraintViewDSL.swift ├── Debugging.swift ├── LayoutConstraint.swift ├── LayoutConstraintItem.swift ├── SnapKit.h └── UILayoutSupport+Extensions.swift /.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 | ## Playgrounds 31 | timeline.xctimeline 32 | playground.xcworkspace 33 | 34 | # Swift Package Manager 35 | # 36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 37 | # Packages/ 38 | .build/ 39 | 40 | # CocoaPods 41 | # 42 | # We recommend against adding the Pods directory to your .gitignore. However 43 | # you should judge for yourself, the pros and cons are mentioned at: 44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 45 | # 46 | # Pods/ 47 | 48 | # Carthage 49 | # 50 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 51 | # Carthage/Checkouts 52 | 53 | Carthage/Build 54 | 55 | # fastlane 56 | # 57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 58 | # screenshots whenever they are needed. 59 | # For more information about the recommended setup visit: 60 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 61 | 62 | fastlane/report.xml 63 | fastlane/Preview.html 64 | fastlane/screenshots 65 | fastlane/test_output 66 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode8 3 | xcode_project: OKKLineSwift.xcodeproj 4 | xcode_scheme: OKKLineSwift-iOS-Demo 5 | xcode_sdk: iphonesimulator10.2 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Herb 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 | -------------------------------------------------------------------------------- /OKKLineSwift-iOS-Demo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // OKKLineSwift-iOS-Demo 4 | // 5 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 6 | // 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 | -------------------------------------------------------------------------------- /OKKLineSwift-iOS-Demo/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 | } -------------------------------------------------------------------------------- /OKKLineSwift-iOS-Demo/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 | -------------------------------------------------------------------------------- /OKKLineSwift-iOS-Demo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /OKKLineSwift-iOS-Demo/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 | -------------------------------------------------------------------------------- /OKKLineSwift-iOS-Demo/OKKLineViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OKKLineViewController.swift 3 | // OKKLineSwift 4 | // 5 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 6 | // 7 | 8 | import UIKit 9 | 10 | class OKKLineViewController: UIViewController { 11 | 12 | var klineView: OKKLineView! 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | klineView = OKKLineView() 17 | klineView.doubleTapHandle = { () -> Void in 18 | self.dismiss(animated: true, completion: nil) 19 | } 20 | view.addSubview(self.klineView) 21 | klineView.snp.makeConstraints { (make) in 22 | make.edges.equalTo(OKEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)) 23 | } 24 | // let timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(fetchData), userInfo: nil, repeats: true) 25 | 26 | fetchData() 27 | 28 | // timer.fire() 29 | 30 | //let unitValue = (limitValue.maxValue - limitValue.minValue) / Double(drawHeight) 31 | //let drawValue = Double(drawMaxY - drawY) * unitValue + limitValue.minValue 32 | //let drawY: CGFloat = abs(self.drawMaxY - CGFloat((drawValue - limitValue.minValue) / unitValue)) 33 | 34 | } 35 | 36 | override func viewWillAppear(_ animated: Bool) { 37 | super.viewWillAppear(animated) 38 | UIApplication.shared.isStatusBarHidden = true 39 | } 40 | 41 | override func viewWillDisappear(_ animated: Bool) { 42 | super.viewWillDisappear(animated) 43 | UIApplication.shared.isStatusBarHidden = false 44 | } 45 | 46 | override var supportedInterfaceOrientations: UIInterfaceOrientationMask { 47 | return .landscape 48 | } 49 | 50 | @objc 51 | func fetchData() { 52 | let param = ["type" : "5min", 53 | "symbol" : "okcoincnbtccny", 54 | "size" : "300"] 55 | Just.post("https://www.btc123.com/kline/klineapi", params: param, asyncCompletionHandler: { (result) -> Void in 56 | 57 | print(result) 58 | DispatchQueue.main.async(execute: { 59 | 60 | if result.ok { 61 | let resultData = result.json as! [String : Any] 62 | let datas = resultData["datas"] as! [[Double]] 63 | 64 | var dataArray = [OKKLineModel]() 65 | for data in datas { 66 | 67 | let model = OKKLineModel(date: data[0], open: data[1], close: data[4], high: data[2], low: data[3], volume: data[5]) 68 | dataArray.append(model) 69 | } 70 | 71 | // for model in OKConfiguration.shared.klineModels { 72 | // print(model.propertyDescription()) 73 | // } 74 | self.klineView.drawKLineView(klineModels: dataArray) 75 | } 76 | 77 | 78 | }) 79 | 80 | }) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /OKKLineSwift-iOS-Demo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // OKKLineSwift-iOS-Demo 4 | // 5 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 6 | // 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | } 17 | 18 | @IBAction func showKLine() { 19 | 20 | let klineVC = OKKLineViewController() 21 | klineVC.modalTransitionStyle = .crossDissolve 22 | present(klineVC, animated: true, completion: nil) 23 | 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /OKKLineSwift-iOS-DemoTests/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 | -------------------------------------------------------------------------------- /OKKLineSwift-iOS-DemoTests/OKKLineSwift_iOS_DemoTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OKKLineSwift_iOS_DemoTests.swift 3 | // OKKLineSwift-iOS-DemoTests 4 | // 5 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 6 | // 7 | // 8 | 9 | import XCTest 10 | @testable import OKKLineSwift_iOS_Demo 11 | 12 | class OKKLineSwift_iOS_DemoTests: 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 | -------------------------------------------------------------------------------- /OKKLineSwift-macOS-Demo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // OKKLineSwift-macOS-Demo 4 | // 5 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 6 | // 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | 15 | 16 | func applicationDidFinishLaunching(_ aNotification: Notification) { 17 | // Insert code here to initialize your application 18 | } 19 | 20 | func applicationWillTerminate(_ aNotification: Notification) { 21 | // Insert code here to tear down your application 22 | } 23 | 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /OKKLineSwift-macOS-Demo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /OKKLineSwift-macOS-Demo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /OKKLineSwift-macOS-Demo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSMainStoryboardFile 26 | Main 27 | NSPrincipalClass 28 | NSApplication 29 | 30 | 31 | -------------------------------------------------------------------------------- /OKKLineSwift-macOS-Demo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // OKKLineSwift-macOS-Demo 4 | // 5 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 6 | // 7 | // 8 | import Cocoa 9 | 10 | class ViewController: NSViewController { 11 | 12 | var klineView: OKKLineView! 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | klineView = OKKLineView() 17 | view.addSubview(klineView) 18 | klineView.snp.makeConstraints { (make) in 19 | make.edges.equalToSuperview() 20 | } 21 | 22 | fetchData() 23 | } 24 | 25 | @objc 26 | func fetchData() { 27 | let param = ["type" : "5min", 28 | "symbol" : "okcoincnbtccny", 29 | "size" : "1000"] 30 | Just.post("https://www.btc123.com/kline/klineapi", params: param, asyncCompletionHandler: { (result) -> Void in 31 | 32 | print(result) 33 | DispatchQueue.main.async(execute: { 34 | 35 | if result.ok { 36 | let resultData = result.json as! [String : Any] 37 | let datas = resultData["datas"] as! [[Double]] 38 | 39 | var dataArray = [OKKLineModel]() 40 | for data in datas { 41 | 42 | let model = OKKLineModel(date: data[0], open: data[1], close: data[4], high: data[2], low: data[3], volume: data[5]) 43 | dataArray.append(model) 44 | } 45 | 46 | // for model in OKConfiguration.shared.klineModels { 47 | // print(model.propertyDescription()) 48 | // } 49 | self.klineView.drawKLineView(klineModels: dataArray) 50 | } 51 | 52 | 53 | }) 54 | 55 | }) 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /OKKLineSwift-macOS-DemoTests/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 | -------------------------------------------------------------------------------- /OKKLineSwift-macOS-DemoTests/OKKLineSwift_macOS_DemoTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OKKLineSwift_macOS_DemoTests.swift 3 | // OKKLineSwift-macOS-DemoTests 4 | // 5 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 6 | // 7 | // 8 | 9 | import XCTest 10 | @testable import OKKLineSwift_macOS_Demo 11 | 12 | class OKKLineSwift_macOS_DemoTests: 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 | -------------------------------------------------------------------------------- /OKKLineSwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /OKKLineSwift.xcodeproj/xcshareddata/xcschemes/OKKLineSwift-iOS-Demo.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 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /OKKLineSwift.xcodeproj/xcshareddata/xcschemes/OKKLineSwift-macOS-Demo.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 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /OKKLineSwift.xcodeproj/xcshareddata/xcschemes/OKKLineSwift-tvOS-Demo.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 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /OKKLineSwift/Configuration/OKConfiguration.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OKKLineSwift 3 | // 4 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import Cocoa 28 | #endif 29 | 30 | /// K线类型 31 | enum OKKLineType: Int { 32 | case KLine // K线 33 | case timeLine // 分时图 34 | case other // 其他 35 | } 36 | 37 | /// 指标种类 38 | enum OKIndicatorType { 39 | case NONE 40 | case MA([Int]) 41 | case MA_VOLUME([Int]) 42 | case EMA([Int]) 43 | case EMA_VOLUME([Int]) 44 | case DIF, DEA, MACD 45 | case KDJ, KDJ_K, KDJ_D, KDJ_J 46 | case BOLL(Int), BOLL_MB, BOLL_UP, BOLL_DN 47 | case RSI 48 | case VOL 49 | case DMI 50 | } 51 | 52 | /// 时间线分隔 53 | enum OKTimeLineType: Int { 54 | case realTime = 1 // 分时 55 | case oneMinute = 60 // 1分 56 | case fiveMinute = 300 // 5分 57 | case fifteenMinute = 900 // 15分 58 | case thirtyMinute = 1800 // 30分 59 | case oneHour = 3600 // 60分 60 | case oneDay = 86400 // 日 61 | case oneWeek = 604800 // 周 62 | } 63 | 64 | public final class OKConfiguration { 65 | 66 | private init() { 67 | dateFormatter = DateFormatter() 68 | dateFormatter.dateFormat = "HH:mm" 69 | } 70 | 71 | static let sharedConfiguration = OKConfiguration() 72 | 73 | // MARK: - Common 74 | var dateFormatter: DateFormatter 75 | 76 | let dataSource: OKDataSource = OKDataSource() 77 | 78 | /// 全局主题 79 | let theme: OKTheme = OKTheme() 80 | 81 | /// 主图Configuration(main) 82 | let main: OKMainConfiguration = OKMainConfiguration() 83 | 84 | /// 成交量图Configuration(volume) 85 | let volume: OKVolumeConfiguration = OKVolumeConfiguration() 86 | 87 | /// 指标图Configuration(accessory) 88 | let accessory: OKAccessoryConfiguration = OKAccessoryConfiguration() 89 | 90 | /// 价格视图Configuration(value) 91 | let value: OKValueConfiguration = OKValueConfiguration() 92 | 93 | } 94 | 95 | public class OKDataSource { 96 | 97 | var drawRange: NSRange? 98 | var klineModels = [OKKLineModel]() 99 | var drawKLineModels = [OKKLineModel]() 100 | } 101 | 102 | // MARK: - 皮肤主题 103 | public class OKTheme { 104 | 105 | // MARK: K线主题 106 | 107 | /// 涨的颜色 108 | var increaseColor: OKColor = OKColor(hexRGB: 0xFF5353) 109 | 110 | /// 跌的颜色 111 | var decreaseColor: OKColor = OKColor(hexRGB: 0x00B07C) 112 | 113 | /// k线的间隔 114 | var klineSpace: CGFloat = 1.0 115 | 116 | /// k线图主体宽度 117 | var klineWidth: CGFloat = 5.0 118 | 119 | /// 上下影线宽度 120 | var klineShadowLineWidth: CGFloat = 1.0 121 | 122 | /// k线最大宽度 123 | var klineMaxWidth: CGFloat = 20.0 124 | 125 | /// k线最小宽度 126 | var klineMinWidth: CGFloat = 2.0 127 | 128 | /// k线缩放界限 129 | var klineScale: CGFloat = 0.03 130 | 131 | /// k线缩放因子 132 | var klineScaleFactor: CGFloat = 0.03 133 | 134 | /// 指标线宽度 135 | var indicatorLineWidth: CGFloat = 0.8 136 | 137 | /// 十字线颜色 138 | var longPressLineColor: OKColor = OKColor(hexRGB: 0xE1E2E6) 139 | 140 | /// 十字线宽度 141 | var longPressLineWidth: CGFloat = 0.5 142 | 143 | // MARK: 指标颜色 144 | 145 | var DIFColor: OKColor = OKColor(hexRGB: 0xFF8D1D) 146 | var DEAColor: OKColor = OKColor(hexRGB: 0x0DAEE6) 147 | var MACDColor: OKColor = OKColor(hexRGB: 0xFFC90E) 148 | 149 | var KDJ_KColor: OKColor = OKColor(hexRGB: 0xFF8D1D) 150 | var KDJ_DColor: OKColor = OKColor(hexRGB: 0x0DAEE6) 151 | var KDJ_JColor: OKColor = OKColor(hexRGB: 0xE970DC) 152 | 153 | var BOLL_MBColor: OKColor = OKColor(hexRGB: 0xFFAEBF) 154 | var BOLL_UPColor: OKColor = OKColor(hexRGB: 0xFFC90E) 155 | var BOLL_DNColor: OKColor = OKColor(hexRGB: 0x0DAEE6) 156 | 157 | public func MAColor(day: Int) -> OKColor { 158 | return OKColor(hexRGB: 0x4498EA + day) 159 | } 160 | 161 | public func EMAColor(day: Int) -> OKColor { 162 | return OKColor(hexRGB: 0x4498EA + day) 163 | } 164 | } 165 | 166 | // MARK: - 主图Configuration(main) 167 | 168 | public class OKMainConfiguration { 169 | 170 | /// 主图图表的背景色 171 | var backgroundColor: OKColor = OKColor(hexRGB: 0x181C20) 172 | 173 | /// 主图比例 174 | var scale: CGFloat = 0.50 175 | 176 | /// 主图顶部提示信息高度 177 | var topAssistViewHeight: CGFloat = 30.0 178 | 179 | /// 主图底部时间线信息高度 180 | var bottomAssistViewHeight: CGFloat = 15.0 181 | 182 | /// 时间线 183 | var timeLineType: OKTimeLineType = .realTime 184 | 185 | /// 主图K线类型 186 | var klineType: OKKLineType = .KLine 187 | 188 | /// 主图分时线宽度 189 | var realtimeLineWidth: CGFloat = 1.0 190 | 191 | /// 分时线颜色 192 | var realtimeLineColor: OKColor = OKColor(hexRGB: 0xFFFFFF) 193 | 194 | /// 主图指标类型 195 | var indicatorType: OKIndicatorType = .MA([12, 26]) 196 | 197 | /// 辅助视图背景色(e.g. 日期的背景色) 198 | var assistViewBgColor: OKColor = OKColor(hexRGB: 0x1D2227) 199 | 200 | /// 辅助视图字体颜色(e.g. 日期的字体颜色) 201 | var assistTextColor: OKColor = OKColor(hexRGB: 0x565A64) 202 | 203 | /// 辅助视图字体大小(e.g. 日期的字体大小) 204 | var assistTextFont: OKFont = OKFont.systemFont(ofSize: 11) 205 | } 206 | 207 | // MARK: - 成交量图Configuration(volume) 208 | 209 | public class OKVolumeConfiguration { 210 | 211 | /// 是否显示成交量视图 212 | var show: Bool = true 213 | 214 | /// 成交量视图背景色 215 | var backgroundColor: OKColor = OKColor(hexRGB: 0x181C20) 216 | 217 | /// 成交量比例 218 | var scale: CGFloat = 0.25 219 | 220 | /// 顶部提示信息高度 221 | var topViewHeight: CGFloat = 20.0 222 | 223 | /// 成交量图分时线宽度 224 | var lineWidth: CGFloat = 0.5 225 | 226 | /// 成交量指标类型 227 | var indicatorType: OKIndicatorType = .EMA_VOLUME([12, 26]) 228 | } 229 | 230 | // MARK: - 指标图Configuration(accessory) 231 | 232 | public class OKAccessoryConfiguration { 233 | 234 | /// 是否显示指标图 235 | var show: Bool = true 236 | 237 | /// 指标视图背景色 238 | var backgroundColor: OKColor = OKColor(hexRGB: 0x181C20) 239 | 240 | /// 指标图比例 241 | var scale: CGFloat = 0.25 242 | 243 | /// 顶部提示信息高度 244 | var topViewHeight: CGFloat = 20.0 245 | 246 | /// 指标图分时线宽度 247 | var lineWidth: CGFloat = 0.5 248 | 249 | /// 辅助图指标类型 250 | var indicatorType: OKIndicatorType = .MACD 251 | } 252 | 253 | // MARK: - 价格视图Configuration(value) 254 | 255 | public class OKValueConfiguration { 256 | 257 | var backgroundColor: OKColor = OKColor(hexRGB: 0x181C20) 258 | var textFont: OKFont = OKFont.systemFont(ofSize: 11) 259 | var textColor: OKColor = OKColor(hexRGB: 0xDCDADC) 260 | } 261 | -------------------------------------------------------------------------------- /OKKLineSwift/Configuration/OKPlatform.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OKKLineSwift 3 | // 4 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | 26 | import UIKit 27 | public typealias OKFont = UIFont 28 | public typealias OKColor = UIColor 29 | public typealias OKEdgeInsets = UIEdgeInsets 30 | 31 | func OKGraphicsGetCurrentContext() -> CGContext? { 32 | return UIGraphicsGetCurrentContext() 33 | } 34 | 35 | #else 36 | 37 | import Cocoa 38 | public typealias OKFont = NSFont 39 | public typealias OKColor = NSColor 40 | public typealias OKEdgeInsets = EdgeInsets 41 | 42 | func OKGraphicsGetCurrentContext() -> CGContext? { 43 | return NSGraphicsContext.current()?.cgContext 44 | } 45 | 46 | #endif 47 | 48 | extension OKFont { 49 | 50 | public class func systemFont(size: CGFloat) -> OKFont { 51 | return systemFont(ofSize: size) 52 | } 53 | 54 | public class func boldSystemFont(size: CGFloat) -> OKFont { 55 | return boldSystemFont(ofSize: size) 56 | } 57 | 58 | #if os(OSX) 59 | public var lineHeight: CGFloat { 60 | // Not sure if this is right, but it looks okay 61 | return self.boundingRectForFont.size.height 62 | } 63 | #endif 64 | } 65 | 66 | extension OKColor { 67 | 68 | //MARK: - Hex 69 | 70 | public convenience init(hexRGB: Int, alpha: CGFloat = 1.0) { 71 | 72 | self.init(red:CGFloat((hexRGB >> 16) & 0xff) / 255.0, 73 | green:CGFloat((hexRGB >> 8) & 0xff) / 255.0, 74 | blue:CGFloat(hexRGB & 0xff) / 255.0, 75 | alpha: alpha) 76 | } 77 | 78 | public class func randomColor() -> OKColor { 79 | 80 | return OKColor(red: CGFloat(arc4random_uniform(255)) / 255.0, 81 | green: CGFloat(arc4random_uniform(255)) / 255.0, 82 | blue: CGFloat(arc4random_uniform(255)) / 255.0, 83 | alpha: 1.0) 84 | 85 | } 86 | } 87 | 88 | 89 | #if os(iOS) || os(tvOS) 90 | 91 | class OKView: UIView { 92 | 93 | public var okBackgroundColor: OKColor? { 94 | didSet { 95 | backgroundColor = okBackgroundColor 96 | } 97 | } 98 | 99 | public func okSetNeedsDisplay() { 100 | setNeedsDisplay() 101 | } 102 | 103 | public func okSetNeedsDisplay(_ rect: CGRect) { 104 | setNeedsDisplay(rect) 105 | } 106 | 107 | override init(frame: CGRect) { 108 | super.init(frame: frame) 109 | } 110 | 111 | required init?(coder aDecoder: NSCoder) { 112 | fatalError("init(coder:) has not been implemented") 113 | } 114 | 115 | override func draw(_ rect: CGRect) { 116 | super.draw(rect) 117 | } 118 | } 119 | 120 | class OKScrollView: UIScrollView { 121 | 122 | } 123 | 124 | class OKButton: UIButton { 125 | 126 | } 127 | 128 | #else 129 | 130 | class OKView: NSView { 131 | 132 | public var okBackgroundColor: OKColor? { 133 | didSet { 134 | wantsLayer = true 135 | layer?.backgroundColor = okBackgroundColor?.cgColor 136 | } 137 | } 138 | 139 | public func okSetNeedsDisplay() { 140 | setNeedsDisplay(bounds) 141 | } 142 | 143 | public func okSetNeedsDisplay(_ rect: CGRect) { 144 | setNeedsDisplay(rect) 145 | } 146 | 147 | public override var isFlipped: Bool { 148 | get { 149 | return true 150 | } 151 | } 152 | 153 | override init(frame frameRect: NSRect) { 154 | super.init(frame: frameRect) 155 | } 156 | 157 | public required init?(coder: NSCoder) { 158 | fatalError("init(coder:) has not been implemented") 159 | } 160 | 161 | public override func draw(_ dirtyRect: NSRect) { 162 | super.draw(dirtyRect) 163 | 164 | // Drawing code here. 165 | } 166 | } 167 | 168 | class OKScrollView: NSScrollView { 169 | 170 | public override var isFlipped: Bool { 171 | get { 172 | return true 173 | } 174 | } 175 | 176 | public var showsVerticalScrollIndicator: Bool = true { 177 | didSet { 178 | hasVerticalScroller = showsVerticalScrollIndicator 179 | } 180 | } 181 | 182 | public var showsHorizontalScrollIndicator: Bool = true { 183 | didSet { 184 | hasHorizontalRuler = showsHorizontalScrollIndicator 185 | } 186 | } 187 | } 188 | 189 | class OKButton: NSButton { 190 | 191 | public var okBackgroundColor: OKColor? { 192 | didSet { 193 | if let buttonCell = cell as? NSButtonCell { 194 | buttonCell.isBordered = false 195 | buttonCell.backgroundColor = okBackgroundColor 196 | } 197 | } 198 | } 199 | 200 | } 201 | 202 | #endif 203 | 204 | public func OKPrint(_ object: @autoclosure() -> Any?, 205 | _ file: String = #file, 206 | _ function: String = #function, 207 | _ line: Int = #line) { 208 | #if DEBUG 209 | guard let value = object() else { 210 | return 211 | } 212 | var stringRepresentation: String? 213 | 214 | if let value = value as? CustomDebugStringConvertible { 215 | stringRepresentation = value.debugDescription 216 | } 217 | else if let value = value as? CustomStringConvertible { 218 | stringRepresentation = value.description 219 | } 220 | 221 | let formatter = DateFormatter() 222 | formatter.dateFormat = "HH:mm:ss:SSS" 223 | let timestamp = formatter.string(from: Date()) 224 | let queue = Thread.isMainThread ? "UI" : "BG" 225 | let fileURL = NSURL(string: file)?.lastPathComponent ?? "Unknown file" 226 | 227 | if let string = stringRepresentation { 228 | print("✅ \(timestamp) {\(queue)} \(fileURL) > \(function)[\(line)]: \(string)") 229 | } else { 230 | print("✅ \(timestamp) {\(queue)} \(fileURL) > \(function)[\(line)]: \(value)") 231 | } 232 | #endif 233 | } 234 | 235 | protocol OKDescriptable { 236 | func propertyDescription() -> String 237 | } 238 | 239 | extension OKDescriptable { 240 | func propertyDescription() -> String { 241 | let strings = Mirror(reflecting: self).children.flatMap { "\($0.label!): \($0.value)" } 242 | var string = "" 243 | for str in strings { 244 | string += str + "\n" 245 | } 246 | return string 247 | } 248 | } 249 | 250 | 251 | -------------------------------------------------------------------------------- /OKKLineSwift/Models/Indicators/OKBOLLModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OKKLineSwift 3 | // 4 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import Foundation 25 | 26 | struct OKBOLLModel { 27 | 28 | let indicatorType: OKIndicatorType 29 | let klineModels: [OKKLineModel] 30 | 31 | init(indicatorType: OKIndicatorType, klineModels: [OKKLineModel]) { 32 | self.indicatorType = indicatorType 33 | self.klineModels = klineModels 34 | } 35 | 36 | public func fetchDrawBOLLData(drawRange: NSRange? = nil) -> [OKKLineModel] { 37 | var datas = [OKKLineModel]() 38 | 39 | guard klineModels.count > 0 else { 40 | return datas 41 | } 42 | 43 | for (index, model) in klineModels.enumerated() { 44 | 45 | model.sumClose = model.close + (index > 0 ? klineModels[index - 1].sumClose! : 0) 46 | 47 | switch indicatorType { 48 | case .BOLL(let day): 49 | let MA = handleMA(day: day, model: model, index: index, models: klineModels) 50 | let MD = handleMD(day: day, model: model, MAValue: MA) 51 | model.BOLL_MB = MA 52 | model.BOLL_UP = handleUP(MB: model.BOLL_MB, MD: MD) 53 | model.BOLL_DN = handleDN(MB: model.BOLL_MB, MD: MD) 54 | 55 | default: 56 | break 57 | } 58 | 59 | datas.append(model) 60 | } 61 | 62 | if let range = drawRange { 63 | return Array(datas[range.location.. Double? { 70 | if let MA = MAValue { 71 | return sqrt(pow((model.close - MA), 2) / Double(day)) 72 | } 73 | return nil 74 | } 75 | 76 | private func handleMA(day: Int, model: OKKLineModel, index: Int, models: [OKKLineModel]) -> Double? { 77 | if day <= 0 || index < (day - 1) { 78 | return nil 79 | } 80 | else if index == (day - 1) { 81 | return model.sumClose! / Double(day) 82 | } 83 | else { 84 | return (model.sumClose! - models[index - day].sumClose!) / Double(day) 85 | } 86 | } 87 | 88 | private func handleUP(MB: Double?, MD: Double?) -> Double? { 89 | if let MB = MB, 90 | let MD = MD { 91 | return MB + 2 * MD 92 | } 93 | return nil 94 | } 95 | 96 | private func handleDN(MB: Double?, MD: Double?) -> Double? { 97 | if let MB = MB, 98 | let MD = MD { 99 | return MB - 2 * MD 100 | } 101 | return nil 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /OKKLineSwift/Models/Indicators/OKEMAModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OKKLineSwift 3 | // 4 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import Foundation 25 | 26 | struct OKEMAModel { 27 | 28 | let indicatorType: OKIndicatorType 29 | let klineModels: [OKKLineModel] 30 | 31 | init(indicatorType: OKIndicatorType, klineModels: [OKKLineModel]) { 32 | self.indicatorType = indicatorType 33 | self.klineModels = klineModels 34 | } 35 | 36 | public func fetchDrawEMAData(drawRange: NSRange? = nil) -> [OKKLineModel] { 37 | 38 | var datas = [OKKLineModel]() 39 | 40 | guard klineModels.count > 0 else { 41 | return datas 42 | } 43 | 44 | for (index, model) in klineModels.enumerated() { 45 | 46 | switch indicatorType { 47 | case .EMA(let days): 48 | 49 | var values = [Double?]() 50 | 51 | for (idx, day) in days.enumerated() { 52 | 53 | let previousEMA: Double? = index > 0 ? datas[index - 1].EMAs?[idx] : nil 54 | values.append(handleEMA(day: day, model: model, index: index, previousEMA: previousEMA)) 55 | } 56 | model.EMAs = values 57 | default: 58 | break 59 | } 60 | datas.append(model) 61 | } 62 | 63 | if let range = drawRange { 64 | return Array(datas[range.location.. Double? { 71 | if day <= 0 || index < (day - 1) { 72 | return nil 73 | } else { 74 | if previousEMA != nil { 75 | return Double(day - 1) / Double(day + 1) * previousEMA! + 2 / Double(day + 1) * model.close 76 | } else { 77 | return 2 / Double(day + 1) * model.close 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /OKKLineSwift/Models/Indicators/OKEMAVOLUMEModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OKKLineSwift 3 | // 4 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import Foundation 25 | 26 | struct OKEMAVOLUMEModel { 27 | 28 | let indicatorType: OKIndicatorType 29 | let klineModels: [OKKLineModel] 30 | 31 | init(indicatorType: OKIndicatorType, klineModels: [OKKLineModel]) { 32 | self.indicatorType = indicatorType 33 | self.klineModels = klineModels 34 | } 35 | 36 | public func fetchDrawEMAVOLUMEData(drawRange: NSRange?) -> [OKKLineModel] { 37 | 38 | var datas = [OKKLineModel]() 39 | 40 | guard klineModels.count > 0 else { 41 | return datas 42 | } 43 | 44 | for (index, model) in klineModels.enumerated() { 45 | 46 | switch indicatorType { 47 | case .EMA_VOLUME(let days): 48 | 49 | var values = [Double?]() 50 | 51 | for (idx, day) in days.enumerated() { 52 | 53 | let previousEMA_VOLUME: Double? = index > 0 ? datas[index - 1].EMA_VOLUMEs?[idx] : nil 54 | values.append(handleEMA_VOLUME(day: day, model: model, index: index, previousEMA_VOLUME: previousEMA_VOLUME)) 55 | } 56 | model.EMA_VOLUMEs = values 57 | default: 58 | break 59 | } 60 | datas.append(model) 61 | } 62 | 63 | if let range = drawRange { 64 | return Array(datas[range.location.. Double? { 71 | if day <= 0 || index < (day - 1) { 72 | return nil 73 | } else { 74 | if previousEMA_VOLUME != nil { 75 | return Double(day - 1) / Double(day + 1) * previousEMA_VOLUME! + 2 / Double(day + 1) * model.volume 76 | } else { 77 | return 2 / Double(day + 1) * model.volume 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /OKKLineSwift/Models/Indicators/OKKDJModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OKKLineSwift 3 | // 4 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import Foundation 25 | 26 | struct OKKDJModel { 27 | 28 | let klineModels: [OKKLineModel] 29 | 30 | init(klineModels: [OKKLineModel]) { 31 | self.klineModels = klineModels 32 | } 33 | 34 | public func fetchDrawKDJData(drawRange: NSRange? = nil) -> [OKKLineModel] { 35 | var datas = [OKKLineModel]() 36 | 37 | guard klineModels.count > 0 else { 38 | return datas 39 | } 40 | 41 | for (index, model) in klineModels.enumerated() { 42 | let previousModel: OKKLineModel? = index > 0 ? klineModels[index - 1] : nil 43 | model.minPriceOfNineClock = handleMinPriceOfNineClock(index: index, models: klineModels) 44 | model.maxPriceOfNineClock = handleMaxPriceOfNineClock(index: index, models: klineModels) 45 | model.RSV9 = handleRSV9(model: model) 46 | model.KDJ_K = handleKDJ_K(model: model, previousModel: previousModel) 47 | model.KDJ_D = handleKDJ_D(model: model, previousModel: previousModel) 48 | model.KDJ_J = handleKDJ_J(model: model) 49 | datas.append(model) 50 | } 51 | 52 | if let range = drawRange { 53 | return Array(datas[range.location.. Double { 60 | var minValue = models[index].low 61 | let startIndex = index < 9 ? 0 : (index - (9 - 1)) 62 | 63 | for i in startIndex.. Double { 72 | var maxValue = models[index].high 73 | let startIndex = index < 9 ? 0 : (index - (9 - 1)) 74 | 75 | for i in startIndex.. Double { 84 | 85 | guard let minPrice = model.minPriceOfNineClock, 86 | let maxPrice = model.maxPriceOfNineClock else { 87 | return 100.0 88 | } 89 | 90 | if minPrice == maxPrice { 91 | return 100.0 92 | } else { 93 | return (model.close - minPrice) / (maxPrice - minPrice) 94 | } 95 | } 96 | 97 | private func handleKDJ_K(model: OKKLineModel, previousModel: OKKLineModel?) -> Double { 98 | 99 | if previousModel == nil { // 第一个数据 100 | return (model.RSV9! + 2 * 50) / 3 101 | } else { 102 | return (model.RSV9! + 2 * previousModel!.KDJ_K!) / 3 103 | } 104 | } 105 | 106 | private func handleKDJ_D(model: OKKLineModel, previousModel: OKKLineModel?) -> Double { 107 | 108 | if previousModel == nil { // 第一个数据 109 | return (model.KDJ_K! + 2 * 50) / 3 110 | } else { 111 | return (model.KDJ_K! + 2 * previousModel!.KDJ_D!) / 3 112 | } 113 | } 114 | 115 | private func handleKDJ_J(model: OKKLineModel) -> Double { 116 | return model.KDJ_K! * 3 - model.KDJ_D! * 2 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /OKKLineSwift/Models/Indicators/OKMACDModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OKKLineSwift 3 | // 4 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import Foundation 25 | 26 | struct OKMACDModel { 27 | 28 | let klineModels: [OKKLineModel] 29 | 30 | init(klineModels: [OKKLineModel]) { 31 | self.klineModels = klineModels 32 | } 33 | 34 | public func fetchDrawMACDData(drawRange: NSRange? = nil) -> [OKKLineModel] { 35 | 36 | var datas = [OKKLineModel]() 37 | guard klineModels.count > 0 else { 38 | return datas 39 | } 40 | var lastEMA12: Double? 41 | var lastEMA26: Double? 42 | 43 | for (index, model) in klineModels.enumerated() { 44 | let previousModel: OKKLineModel? = index > 0 ? klineModels[index - 1] : nil 45 | 46 | let ema12 = handleEMA(day: 12, model: model, index: index, previousEMA: lastEMA12) 47 | let ema26 = handleEMA(day: 26, model: model, index: index, previousEMA: lastEMA26) 48 | lastEMA12 = ema12 49 | lastEMA26 = ema26 50 | model.DIF = handleDIF(EMA12: ema12, EMA26: ema26) 51 | model.DEA = handleDEA(model: model, previousModel: previousModel) 52 | model.MACD = handleMACD(model: model) 53 | 54 | datas.append(model) 55 | } 56 | 57 | if let range = drawRange { 58 | return Array(datas[range.location.. Double? { 65 | if day <= 0 || index < (day - 1) { 66 | return nil 67 | } else { 68 | if previousEMA != nil { 69 | return Double(day - 1) / Double(day + 1) * previousEMA! + 2 / Double(day + 1) * model.close 70 | } else { 71 | return 2 / Double(day + 1) * model.close 72 | } 73 | } 74 | } 75 | 76 | private func handleDIF(EMA12: Double?, EMA26: Double?) -> Double? { 77 | guard let ema12 = EMA12, 78 | let ema26 = EMA26 else { 79 | return nil 80 | } 81 | return ema12 - ema26 82 | } 83 | 84 | private func handleDEA(model: OKKLineModel, previousModel: OKKLineModel?) -> Double? { 85 | 86 | guard let dif = model.DIF else { 87 | return nil 88 | } 89 | 90 | if let previousDEA = previousModel?.DEA { 91 | return dif * 0.2 + previousDEA * 0.8 92 | } else { 93 | return dif * 0.2 94 | } 95 | } 96 | 97 | private func handleMACD(model: OKKLineModel) -> Double? { 98 | guard let dif = model.DIF, 99 | let dea = model.DEA else { 100 | return nil 101 | } 102 | return (dif - dea) * 2 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /OKKLineSwift/Models/Indicators/OKMAModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OKKLineSwift 3 | // 4 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import Foundation 25 | 26 | struct OKMAModel { 27 | 28 | let indicatorType: OKIndicatorType 29 | let klineModels: [OKKLineModel] 30 | 31 | init(indicatorType: OKIndicatorType, klineModels: [OKKLineModel]) { 32 | self.indicatorType = indicatorType 33 | self.klineModels = klineModels 34 | } 35 | 36 | public func fetchDrawMAData(drawRange: NSRange?) -> [OKKLineModel] { 37 | 38 | var datas = [OKKLineModel]() 39 | 40 | guard klineModels.count > 0 else { 41 | return datas 42 | } 43 | 44 | for (index, model) in klineModels.enumerated() { 45 | 46 | model.sumClose = model.close + (index > 0 ? klineModels[index - 1].sumClose! : 0) 47 | 48 | switch indicatorType { 49 | case .MA(let days): 50 | var values = [Double?]() 51 | for day in days { 52 | 53 | values.append(handleMA(day: day, model: model, index: index, models: klineModels)) 54 | } 55 | model.MAs = values 56 | default: 57 | break 58 | } 59 | 60 | datas.append(model) 61 | } 62 | 63 | if let range = drawRange { 64 | return Array(datas[range.location.. Double? { 71 | if day <= 0 || index < (day - 1) { 72 | return nil 73 | } 74 | else if index == (day - 1) { 75 | return model.sumClose! / Double(day) 76 | } 77 | else { 78 | return (model.sumClose! - models[index - day].sumClose!) / Double(day) 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /OKKLineSwift/Models/Indicators/OKMAVOLUMEModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OKKLineSwift 3 | // 4 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import Foundation 25 | 26 | struct OKMAVOLUMEModel { 27 | 28 | let indicatorType: OKIndicatorType 29 | let klineModels: [OKKLineModel] 30 | 31 | init(indicatorType: OKIndicatorType, klineModels: [OKKLineModel]) { 32 | self.indicatorType = indicatorType 33 | self.klineModels = klineModels 34 | } 35 | 36 | public func fetchDrawMAVOLUMEData(drawRange: NSRange?) -> [OKKLineModel] { 37 | 38 | var datas = [OKKLineModel]() 39 | 40 | guard klineModels.count > 0 else { 41 | return datas 42 | } 43 | 44 | for (index, model) in klineModels.enumerated() { 45 | 46 | model.sumVolume = model.volume + (index > 0 ? klineModels[index - 1].sumVolume! : 0) 47 | 48 | switch indicatorType { 49 | case .MA_VOLUME(let days): 50 | var values = [Double?]() 51 | for day in days { 52 | 53 | values.append(handleMA_VOLUME(day: day, model: model, index: index, models: klineModels)) 54 | } 55 | model.MA_VOLUMEs = values 56 | default: 57 | break 58 | } 59 | 60 | datas.append(model) 61 | } 62 | 63 | if let range = drawRange { 64 | return Array(datas[range.location.. Double? { 70 | if day <= 0 || index < (day - 1) { 71 | return nil 72 | } 73 | else if index == (day - 1) { 74 | return model.sumVolume! / Double(day) 75 | } 76 | else { 77 | return (model.sumVolume! - models[index - day].sumVolume!) / Double(day) 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /OKKLineSwift/Models/OKKLineModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OKKLineSwift 3 | // 4 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | import Foundation 25 | 26 | /// k线类型 27 | enum OKKLineDataType: Int { 28 | case BTC 29 | case LTC 30 | case ETH 31 | case other 32 | } 33 | 34 | class OKKLineModel: OKDescriptable { 35 | 36 | var klineDataType: OKKLineDataType 37 | // 日期 38 | var date: Double 39 | // 开盘价 40 | var open: Double 41 | // 收盘价 42 | var close: Double 43 | // 最高价 44 | var high: Double 45 | // 最低价 46 | var low: Double 47 | // 成交量 48 | var volume: Double 49 | 50 | // MARK: 指标 51 | // 该model以及之前所有开盘价之和 52 | var sumOpen: Double? 53 | 54 | // 该model以及之前所有收盘价之和 55 | var sumClose: Double? 56 | 57 | // 该model以及之前所有最高价之和 58 | var sumHigh: Double? 59 | 60 | // 该model以及之前所有最低价之和 61 | var sumLow: Double? 62 | 63 | // 该model以及之前所有成交量之和 64 | var sumVolume: Double? 65 | 66 | // MARK: MA - MA(N) = (C1+C2+……CN) / N, C:收盘价 67 | var MAs: [Double?]? 68 | var MA_VOLUMEs: [Double?]? 69 | 70 | // MARK: EMA - EMA(N) = 2 / (N+1) * (C-昨日EMA) + 昨日EMA, C:收盘价 71 | var EMAs: [Double?]? 72 | var EMA_VOLUMEs: [Double?]? 73 | 74 | // MARK: MACD 75 | 76 | // DIF = EMA(12) - EMA(26) 77 | var DIF: Double? 78 | // DEA = (前一日DEA X 8/10 + 今日DIF X 2/10) 79 | var DEA: Double? 80 | // MACD(12,26,9) = (DIF - DEA) * 2 81 | var MACD: Double? 82 | 83 | // MARK: KDJ(9,3,3) 代表指标分析周期为9天,K值D值为3天 84 | // 九个交易日内最低价 85 | var minPriceOfNineClock: Double? 86 | // 九个交易日最高价 87 | var maxPriceOfNineClock: Double? 88 | // RSV(9) =(今日收盘价-9日内最低价)/(9日内最高价-9日内最低价)* 100 89 | var RSV9: Double? 90 | // K(3) =(当日RSV值+2*前一日K值)/ 3 91 | var KDJ_K: Double? 92 | // D(3) =(当日K值 + 2*前一日D值)/ 3 93 | var KDJ_D: Double? 94 | // J = 3K - 2D 95 | var KDJ_J: Double? 96 | 97 | // MARK: BOLL 98 | // 中轨线 99 | var BOLL_MB: Double? 100 | // 上轨线 101 | var BOLL_UP: Double? 102 | // 下轨线 103 | var BOLL_DN: Double? 104 | 105 | init(klineDataType: OKKLineDataType = .BTC, 106 | date: Double, 107 | open: Double, 108 | close: Double, 109 | high: Double, 110 | low: Double, 111 | volume: Double) { 112 | 113 | self.klineDataType = klineDataType 114 | self.date = date 115 | self.open = open 116 | self.close = close 117 | self.high = high 118 | self.low = low 119 | self.volume = volume 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /OKKLineSwift/Tools/OKLineBrush.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OKKLineSwift 3 | // 4 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import Cocoa 28 | #endif 29 | import CoreGraphics 30 | 31 | class OKLineBrush { 32 | 33 | public var indicatorType: OKIndicatorType 34 | private var context: CGContext 35 | private var firstValueIndex: Int? 36 | private let configuration = OKConfiguration.sharedConfiguration 37 | 38 | public var calFormula: ((Int, OKKLineModel) -> CGPoint?)? 39 | 40 | init(indicatorType: OKIndicatorType, context: CGContext) { 41 | self.indicatorType = indicatorType 42 | self.context = context 43 | 44 | context.setLineWidth(configuration.theme.indicatorLineWidth) 45 | context.setLineCap(.round) 46 | context.setLineJoin(.round) 47 | 48 | switch indicatorType { 49 | case .DIF: 50 | context.setStrokeColor(configuration.theme.DIFColor.cgColor) 51 | case .DEA: 52 | context.setStrokeColor(configuration.theme.DEAColor.cgColor) 53 | case .KDJ_K: 54 | context.setStrokeColor(configuration.theme.KDJ_KColor.cgColor) 55 | case .KDJ_D: 56 | context.setStrokeColor(configuration.theme.KDJ_DColor.cgColor) 57 | case .KDJ_J: 58 | context.setStrokeColor(configuration.theme.KDJ_JColor.cgColor) 59 | case .BOLL_MB: 60 | context.setStrokeColor(configuration.theme.BOLL_MBColor.cgColor) 61 | case .BOLL_UP: 62 | context.setStrokeColor(configuration.theme.BOLL_UPColor.cgColor) 63 | case .BOLL_DN: 64 | context.setStrokeColor(configuration.theme.BOLL_DNColor.cgColor) 65 | default: break 66 | } 67 | } 68 | 69 | public func draw(drawModels: [OKKLineModel]) { 70 | 71 | for (index, model) in drawModels.enumerated() { 72 | 73 | if let point = calFormula?(index, model) { 74 | 75 | if firstValueIndex == nil { 76 | firstValueIndex = index 77 | } 78 | 79 | if firstValueIndex == index { 80 | context.move(to: point) 81 | } else { 82 | context.addLine(to: point) 83 | } 84 | } 85 | } 86 | context.strokePath() 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /OKKLineSwift/Tools/OKMALineBrush.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OKKLineSwift 3 | // 4 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import Cocoa 28 | #endif 29 | import CoreGraphics 30 | 31 | enum OKBrushType { 32 | case MA(Int) 33 | case EMA(Int) 34 | case MA_VOLUME(Int) 35 | case EMA_VOLUME(Int) 36 | } 37 | 38 | class OKMALineBrush { 39 | 40 | public var calFormula: ((Int, OKKLineModel) -> CGPoint?)? 41 | public var brushType: OKBrushType 42 | private var context: CGContext 43 | private var firstValueIndex: Int? 44 | private let configuration = OKConfiguration.sharedConfiguration 45 | 46 | 47 | init(brushType: OKBrushType, context: CGContext) { 48 | self.brushType = brushType 49 | self.context = context 50 | 51 | context.setLineWidth(configuration.theme.indicatorLineWidth) 52 | context.setLineCap(.round) 53 | context.setLineJoin(.round) 54 | 55 | switch brushType { 56 | case .MA(let day): 57 | context.setStrokeColor(configuration.theme.MAColor(day: day).cgColor) 58 | case .EMA(let day): 59 | context.setStrokeColor(configuration.theme.EMAColor(day: day).cgColor) 60 | case .MA_VOLUME(let day): 61 | context.setStrokeColor(configuration.theme.MAColor(day: day).cgColor) 62 | case .EMA_VOLUME(let day): 63 | context.setStrokeColor(configuration.theme.EMAColor(day: day).cgColor) 64 | } 65 | } 66 | 67 | public func draw(drawModels: [OKKLineModel]) { 68 | 69 | for (index, model) in drawModels.enumerated() { 70 | 71 | if let point = calFormula?(index, model) { 72 | 73 | if firstValueIndex == nil { 74 | firstValueIndex = index 75 | } 76 | 77 | if firstValueIndex == index { 78 | context.move(to: point) 79 | } else { 80 | context.addLine(to: point) 81 | } 82 | } 83 | } 84 | context.strokePath() 85 | } 86 | } 87 | 88 | -------------------------------------------------------------------------------- /OKKLineSwift/Views/OKKLineView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OKKLineSwift 3 | // 4 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import Cocoa 28 | #endif 29 | 30 | class OKKLineView: OKView { 31 | 32 | public var doubleTapHandle: (() -> Void)? 33 | private var klineDrawView: OKKLineDrawView! 34 | private var timeSegmentView: OKSegmentView! 35 | private var mainViewIndicatorSegmentView: OKSegmentView! 36 | private var volumeViewIndicatorSegmentView: OKSegmentView! 37 | private var accessoryViewIndicatorSegmentView: OKSegmentView! 38 | private let configuration = OKConfiguration.sharedConfiguration 39 | 40 | override init(frame: CGRect) { 41 | super.init(frame: frame) 42 | 43 | klineDrawView = OKKLineDrawView() 44 | klineDrawView.doubleTapHandle = { 45 | self.doubleTapHandle?() 46 | } 47 | addSubview(klineDrawView) 48 | klineDrawView.snp.makeConstraints { (make) in 49 | make.edges.equalTo(OKEdgeInsets(top: 0, left: 0, bottom: 44, right: 50)) 50 | } 51 | 52 | setupTimeSegment() 53 | setupMainViewSegment() 54 | setupVolumeViewSegment() 55 | setupAccessoryViewSegment() 56 | 57 | } 58 | 59 | required init?(coder aDecoder: NSCoder) { 60 | fatalError("init(coder:) has not been implemented") 61 | } 62 | 63 | public func drawKLineView(klineModels: [OKKLineModel]) { 64 | configuration.dataSource.klineModels = klineModels 65 | klineDrawView.drawKLineView(true) 66 | } 67 | 68 | /// 设置时间分割视图 69 | private func setupTimeSegment() { 70 | 71 | let timeTitles = ["分时", "1分", "5分", "15分", "30分", "60分", "日K", "周K", "月K", "季K", "年K"] 72 | timeSegmentView = OKSegmentView(direction: .horizontal, titles: timeTitles) 73 | timeSegmentView.didSelectedSegment = { [weak self] (segmentView, result) -> Void in 74 | if result.index == 0 { 75 | self?.configuration.main.klineType = .timeLine 76 | } else { 77 | self?.configuration.main.klineType = .KLine 78 | } 79 | 80 | self?.klineDrawView.drawKLineView(true) 81 | } 82 | addSubview(timeSegmentView) 83 | timeSegmentView.snp.makeConstraints { (make) in 84 | make.top.equalTo(klineDrawView.snp.bottom) 85 | make.leading.trailing.bottom.equalToSuperview() 86 | } 87 | } 88 | 89 | 90 | /// 设置主图指标分割视图 91 | private func setupMainViewSegment() { 92 | 93 | let mainViewIndicatorTitles = ["MA", "EMA", "BOLL"] 94 | mainViewIndicatorSegmentView = OKSegmentView(direction: .vertical, 95 | titles: mainViewIndicatorTitles) 96 | 97 | mainViewIndicatorSegmentView.didSelectedSegment = { [weak self] (segmentView, result) -> Void in 98 | if result.index == 0 { 99 | self?.configuration.main.indicatorType = .MA([12, 26]) 100 | } else if result.index == 1 { 101 | self?.configuration.main.indicatorType = .EMA([12, 26]) 102 | } else if result.index == 2 { 103 | self?.configuration.main.indicatorType = .BOLL(20) 104 | } 105 | self?.klineDrawView.drawKLineView(false) 106 | } 107 | 108 | addSubview(mainViewIndicatorSegmentView) 109 | mainViewIndicatorSegmentView.snp.makeConstraints { (make) in 110 | make.top.equalTo(klineDrawView.snp.top) 111 | make.leading.equalTo(klineDrawView.snp.trailing) 112 | make.trailing.equalToSuperview() 113 | make.height.equalTo(klineDrawView.snp.height).multipliedBy(configuration.main.scale) 114 | } 115 | } 116 | 117 | 118 | /// 设置成交量指标的分割视图 119 | private func setupVolumeViewSegment() { 120 | let volumeViewIndicatorTitles = ["MA", "EMA"] 121 | volumeViewIndicatorSegmentView = OKSegmentView(direction: .vertical, 122 | titles: volumeViewIndicatorTitles) 123 | 124 | volumeViewIndicatorSegmentView.didSelectedSegment = { [weak self] (segmentView, result) -> Void in 125 | if result.index == 0 { 126 | self?.configuration.volume.indicatorType = .MA_VOLUME([12, 26]) 127 | } else if result.index == 1 { 128 | self?.configuration.volume.indicatorType = .EMA_VOLUME([12, 26]) 129 | } 130 | self?.klineDrawView.drawKLineView(false) 131 | } 132 | 133 | addSubview(volumeViewIndicatorSegmentView) 134 | volumeViewIndicatorSegmentView.snp.makeConstraints { (make) in 135 | make.top.equalTo(mainViewIndicatorSegmentView.snp.bottom) 136 | make.leading.equalTo(klineDrawView.snp.trailing) 137 | make.trailing.equalToSuperview() 138 | make.height.equalTo(klineDrawView.snp.height).multipliedBy(configuration.volume.scale) 139 | } 140 | } 141 | 142 | 143 | /// 设置指标分割视图 144 | private func setupAccessoryViewSegment() { 145 | 146 | let accessoryViewIndicatorTitles = ["MACD", "KDJ"] 147 | accessoryViewIndicatorSegmentView = OKSegmentView(direction: .vertical, 148 | titles: accessoryViewIndicatorTitles) 149 | 150 | accessoryViewIndicatorSegmentView.didSelectedSegment = { [weak self] (segmentView, result) -> Void in 151 | if result.index == 0 { 152 | self?.configuration.accessory.indicatorType = .MACD 153 | } else if result.index == 1 { 154 | self?.configuration.accessory.indicatorType = .KDJ 155 | } else if result.index == 2 { 156 | self?.configuration.accessory.indicatorType = .BOLL(20) 157 | } 158 | self?.klineDrawView.drawKLineView(false) 159 | } 160 | 161 | addSubview(accessoryViewIndicatorSegmentView) 162 | accessoryViewIndicatorSegmentView.snp.makeConstraints { (make) in 163 | make.top.equalTo(volumeViewIndicatorSegmentView.snp.bottom) 164 | make.leading.equalTo(klineDrawView.snp.trailing) 165 | make.trailing.equalToSuperview() 166 | make.height.equalTo(klineDrawView.snp.height).multipliedBy(configuration.accessory.scale) 167 | } 168 | } 169 | 170 | } 171 | -------------------------------------------------------------------------------- /OKKLineSwift/Views/OKValueView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OKKLineSwift 3 | // 4 | // Copyright © 2016年 Herb - https://github.com/Herb-Sun/OKKLineSwift 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import Cocoa 28 | #endif 29 | 30 | class OKValueView: OKView { 31 | 32 | public var limitValue: (minValue: Double, maxValue: Double)? { 33 | didSet { 34 | okSetNeedsDisplay() 35 | } 36 | } 37 | 38 | public var currentValueDrawPoint: CGPoint? { 39 | didSet { 40 | okSetNeedsDisplay() 41 | } 42 | } 43 | 44 | private let configuration = OKConfiguration.sharedConfiguration 45 | private var drawEdgeInsets: OKEdgeInsets! 46 | private var limitValueAttrs: [String : Any]! 47 | private var currentValueAttrs: [String : Any]! 48 | private let separate: CGFloat = 20.0 49 | 50 | convenience init(drawEdgeInsets: OKEdgeInsets) { 51 | self.init() 52 | self.drawEdgeInsets = drawEdgeInsets 53 | 54 | let textStyle = NSMutableParagraphStyle() 55 | textStyle.alignment = .center 56 | 57 | limitValueAttrs = [ 58 | NSForegroundColorAttributeName : configuration.value.textColor, 59 | NSFontAttributeName : configuration.value.textFont, 60 | NSParagraphStyleAttributeName : textStyle 61 | ] 62 | 63 | currentValueAttrs = [ 64 | NSForegroundColorAttributeName : configuration.value.textColor, 65 | NSFontAttributeName : configuration.value.textFont, 66 | NSParagraphStyleAttributeName : textStyle, 67 | ] 68 | 69 | } 70 | 71 | override init(frame: CGRect) { 72 | super.init(frame: frame) 73 | } 74 | 75 | required init?(coder aDecoder: NSCoder) { 76 | fatalError("init(coder:) has not been implemented") 77 | } 78 | 79 | override func draw(_ rect: CGRect) { 80 | super.draw(rect) 81 | 82 | guard let context = OKGraphicsGetCurrentContext() else { 83 | return 84 | } 85 | // 背景色 86 | context.clear(rect) 87 | context.setFillColor(configuration.value.backgroundColor.cgColor) 88 | context.fill(rect) 89 | 90 | guard let limitValue = limitValue else { 91 | return 92 | } 93 | 94 | let valueHeight: CGFloat = configuration.value.textFont.lineHeight 95 | let drawHeight = rect.height - drawEdgeInsets.top - drawEdgeInsets.bottom 96 | let unitValue = (limitValue.maxValue - limitValue.minValue) / Double(drawHeight) 97 | let drawMaxY = rect.height - drawEdgeInsets.bottom 98 | 99 | // 四舍五入 100 | let separateCount: Int = Int(drawHeight / separate + 0.5) 101 | 102 | for i in 0.. rect.height - valueHeight { 127 | y = rect.height - valueHeight 128 | } 129 | 130 | let drawRect = CGRect(x: 0, y: y, width: rect.width, height: valueHeight) 131 | 132 | // 画指示背景 133 | context.setFillColor(configuration.value.backgroundColor.cgColor) 134 | context.fill(drawRect) 135 | 136 | // 画指示框 137 | context.setStrokeColor(OKColor.white.cgColor) 138 | context.stroke(drawRect) 139 | 140 | currentValueAttrStr.draw(in: drawRect) 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

OKKLineSwift

2 | 3 | ### [中文介绍](README_CN.md) 4 | 5 | :smile: **OKKLineSwift** is written in Swift3 to draw the stock K-line library 6 | 7 | ## Screenshot 8 | 9 | iOS Screenshot 10 | [Support drag gestures, long press gestures (see details), knead gestures (zoom in)] 11 | 12 | ![OKKLineSwift](https://github.com/Herb-Sun/OKKLineSwift/blob/master/Screenshot/OKKLineSwift-iOS.gif) 13 | 14 | macOS Screenshot 15 | [Support drag events, crosshairs follow, mouse scrolling events (zoom in)] 16 | 17 | ![OKKLineSwift](https://github.com/Herb-Sun/OKKLineSwift/blob/master/Screenshot/OKKLineSwift-macOS.gif) 18 | 19 | Support 20 | === 21 | Swift 3.0 22 | 23 | iOS 8+ 24 | 25 | macOS 10.10+ 26 | 27 | Installation 28 | === 29 | #### Manually 30 | 31 | 1. Download the full file. 32 | 2. Drag the OKKLineSwift folder to your project. 33 | 34 | ## Source directory 35 | 36 | |Directory | Description| 37 | | ---------- | -----------| 38 | | Configuration | OKConfiguration.swift - This is a global control class that controls the global theme (e.g. color, font size, etc.) | 39 | | Views | OKKLineView - This class is the parent view of all views
OKKLineDrawView.swift - This class is a parent view of all K-line views that handle gestures and data sources
OKValueView.swift - Responsible for drawing prices
1、MainView:
OKKLineMainView.swift - Responsible for drawing the main graph
2、VolumeView:
OKKLineVolumeView.swift - Responsible for drawing the volume view
3、AccessoryView:
OKKLineAccessoryView.swift - Responsible for drawing the index view
4、SegmentView:
OKSegmentView.swift - Responsible for displaying timeline or indicator type
| 40 | | Models | Data model directory, mainly K-line data and a variety of indicators model | 41 | | Tools | Tool class directory,for example:
OKLineBrush.swift - Responsible for drawing lines
OKMALineBrush.swift - Responsible for drawing the average class| 42 | 43 | ## TODO 44 | - [x] Support macOS system 45 | - [ ] Support for more metric types 46 | 47 | ## Licenses 48 | All the OK at the beginning of the project source code to comply with MIT license. 49 | Copyright (c) 2016 Herb. All rights reserved. 50 | 51 | ## Contributions 52 | Welcome to contribute to your ideas and code! You can pull requests and issues here! :clap: 53 | 54 | 55 | -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 |

OKKLineSwift

2 | 3 | ### [English Introduction](README.md) 4 | 5 | :smile: **OKKLineSwift** 是本人用Swift3编写的绘制股票K线库 6 | 7 | ## 样例展示 8 | 9 | iOS Screenshot 10 | [支持拖动手势, 长按手势(查看详情), 捏合手势(放大缩小)] 11 | 12 | ![OKKLineSwift](https://github.com/Herb-Sun/OKKLineSwift/blob/master/Screenshot/OKKLineSwift-iOS.gif) 13 | 14 | macOS Screenshot 15 | [支持拖动事件,十字线跟随,鼠标滚动事件(放大缩小)] 16 | 17 | ![OKKLineSwift](https://github.com/Herb-Sun/OKKLineSwift/blob/master/Screenshot/OKKLineSwift-macOS.gif) 18 | 19 | 支持环境 20 | === 21 | Swift 3.0 22 | 23 | iOS 8+ 24 | 25 | macOS 10.10+ 26 | 27 | 集成方法 28 | === 29 | #### 手动安装 30 | 31 | 1. 下载所有文件. 32 | 2. 将OKKLineSwift文件夹拖拽到你的工程中. 33 | 34 | ## 源码目录(所有源码均放在Source文件夹下) 35 | 36 | |目录 | 说明| 37 | | ---------- | -----------| 38 | | Configuration | OKConfiguration.swift - 这是一个全局控制类,控制全局主题(e.g. 颜色,字号等 | 39 | | Views | OKKLineView - 此类是所有视图的父视图
OKKLineDrawView.swift - 此类是所有涉及K线视图的父视图,负责处理手势和数据源
OKValueView.swift - 负责绘制价格
1、MainView:
OKKLineMainView.swift - 负责主图的绘制
2、VolumeView:
OKKLineVolumeView.swift - 负责成交量视图的绘制
3、AccessoryView:
OKKLineAccessoryView.swift - 负责指标视图的绘制
4、SegmentView:
OKSegmentView.swift - 负责显示时间线或者指标类型
| 40 | | Models | 数据模型目录,主要是K线数据以及各种指标模型 | 41 | | Tools | 工具类目录,例如:
OKLineBrush.swift - 负责画线的类
OKMALineBrush.swift - 负责画均线的类| 42 | 43 | ## TODO 44 | - [x] 支持 macOS 系统 45 | - [ ] 支持更多指标类型 46 | 47 | ## Licenses 48 | 本项目所有OK开头的源码遵守MIT license. 49 | Copyright (c) 2016 Herb. All rights reserved. 50 | 51 | ## Contributions 52 | 欢迎各位贡献你们的思路和代码! 您可以在这里pull requests和issues我! :clap: 53 | 54 | 55 | -------------------------------------------------------------------------------- /Screenshot/OKKLineSwift-iOS.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/herbsun/OKKLineSwift/ff5e60c6c3dac94ea3b0ce10169da0ac7f61eab5/Screenshot/OKKLineSwift-iOS.gif -------------------------------------------------------------------------------- /Screenshot/OKKLineSwift-macOS.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/herbsun/OKKLineSwift/ff5e60c6c3dac94ea3b0ce10169da0ac7f61eab5/Screenshot/OKKLineSwift-macOS.gif -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | public typealias ConstraintInterfaceLayoutDirection = UIUserInterfaceLayoutDirection 27 | #else 28 | import AppKit 29 | public typealias ConstraintInterfaceLayoutDirection = NSUserInterfaceLayoutDirection 30 | #endif 31 | 32 | 33 | public struct ConstraintConfig { 34 | 35 | public static var interfaceLayoutDirection: ConstraintInterfaceLayoutDirection = .leftToRight 36 | 37 | } 38 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintConstantTarget.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public protocol ConstraintConstantTarget { 32 | } 33 | 34 | extension CGPoint: ConstraintConstantTarget { 35 | } 36 | 37 | extension CGSize: ConstraintConstantTarget { 38 | } 39 | 40 | extension ConstraintInsets: ConstraintConstantTarget { 41 | } 42 | 43 | extension ConstraintConstantTarget { 44 | 45 | internal func constraintConstantTargetValueFor(layoutAttribute: NSLayoutAttribute) -> CGFloat { 46 | if let value = self as? CGFloat { 47 | return value 48 | } 49 | 50 | if let value = self as? Float { 51 | return CGFloat(value) 52 | } 53 | 54 | if let value = self as? Double { 55 | return CGFloat(value) 56 | } 57 | 58 | if let value = self as? Int { 59 | return CGFloat(value) 60 | } 61 | 62 | if let value = self as? UInt { 63 | return CGFloat(value) 64 | } 65 | 66 | if let value = self as? CGSize { 67 | if layoutAttribute == .width { 68 | return value.width 69 | } else if layoutAttribute == .height { 70 | return value.height 71 | } else { 72 | return 0.0 73 | } 74 | } 75 | 76 | if let value = self as? CGPoint { 77 | #if os(iOS) || os(tvOS) 78 | switch layoutAttribute { 79 | case .left, .right, .leading, .trailing, .centerX, .leftMargin, .rightMargin, .leadingMargin, .trailingMargin, .centerXWithinMargins: 80 | return value.x 81 | case .top, .bottom, .centerY, .topMargin, .bottomMargin, .centerYWithinMargins, .lastBaseline, .firstBaseline: 82 | return value.y 83 | case .width, .height, .notAnAttribute: 84 | return 0.0 85 | } 86 | #else 87 | switch layoutAttribute { 88 | case .left, .right, .leading, .trailing, .centerX: 89 | return value.x 90 | case .top, .bottom, .centerY, .lastBaseline, .firstBaseline: 91 | return value.y 92 | case .width, .height, .notAnAttribute: 93 | return 0.0 94 | } 95 | #endif 96 | } 97 | 98 | if let value = self as? ConstraintInsets { 99 | #if os(iOS) || os(tvOS) 100 | switch layoutAttribute { 101 | case .left, .leftMargin, .centerX, .centerXWithinMargins: 102 | return value.left 103 | case .top, .topMargin, .centerY, .centerYWithinMargins, .lastBaseline, .firstBaseline: 104 | return value.top 105 | case .right, .rightMargin: 106 | return -value.right 107 | case .bottom, .bottomMargin: 108 | return -value.bottom 109 | case .leading, .leadingMargin: 110 | return (ConstraintConfig.interfaceLayoutDirection == .leftToRight) ? value.left : value.right 111 | case .trailing, .trailingMargin: 112 | return (ConstraintConfig.interfaceLayoutDirection == .leftToRight) ? -value.right : -value.left 113 | case .width: 114 | return -(value.left + value.right) 115 | case .height: 116 | return -(value.top + value.bottom) 117 | case .notAnAttribute: 118 | return 0.0 119 | } 120 | #else 121 | switch layoutAttribute { 122 | case .left, .centerX: 123 | return value.left 124 | case .top, .centerY, .lastBaseline, .firstBaseline: 125 | return value.top 126 | case .right: 127 | return -value.right 128 | case .bottom: 129 | return -value.bottom 130 | case .leading: 131 | return (ConstraintConfig.interfaceLayoutDirection == .leftToRight) ? value.left : value.right 132 | case .trailing: 133 | return (ConstraintConfig.interfaceLayoutDirection == .leftToRight) ? -value.right : -value.left 134 | case .width: 135 | return -(value.left + value.right) 136 | case .height: 137 | return -(value.top + value.bottom) 138 | case .notAnAttribute: 139 | return 0.0 140 | } 141 | #endif 142 | } 143 | 144 | return 0.0 145 | } 146 | 147 | } 148 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintDSL.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public protocol ConstraintDSL { 32 | 33 | var target: AnyObject? { get } 34 | 35 | func setLabel(_ value: String?) 36 | func label() -> String? 37 | 38 | } 39 | extension ConstraintDSL { 40 | 41 | public func setLabel(_ value: String?) { 42 | objc_setAssociatedObject(self.target, &labelKey, value, .OBJC_ASSOCIATION_COPY_NONATOMIC) 43 | } 44 | public func label() -> String? { 45 | return objc_getAssociatedObject(self.target, &labelKey) as? String 46 | } 47 | 48 | } 49 | private var labelKey: UInt8 = 0 50 | 51 | 52 | public protocol ConstraintBasicAttributesDSL : ConstraintDSL { 53 | } 54 | extension ConstraintBasicAttributesDSL { 55 | 56 | // MARK: Basics 57 | 58 | public var left: ConstraintItem { 59 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.left) 60 | } 61 | 62 | public var top: ConstraintItem { 63 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.top) 64 | } 65 | 66 | public var right: ConstraintItem { 67 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.right) 68 | } 69 | 70 | public var bottom: ConstraintItem { 71 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.bottom) 72 | } 73 | 74 | public var leading: ConstraintItem { 75 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.leading) 76 | } 77 | 78 | public var trailing: ConstraintItem { 79 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.trailing) 80 | } 81 | 82 | public var width: ConstraintItem { 83 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.width) 84 | } 85 | 86 | public var height: ConstraintItem { 87 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.height) 88 | } 89 | 90 | public var centerX: ConstraintItem { 91 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.centerX) 92 | } 93 | 94 | public var centerY: ConstraintItem { 95 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.centerY) 96 | } 97 | 98 | public var edges: ConstraintItem { 99 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.edges) 100 | } 101 | 102 | public var size: ConstraintItem { 103 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.size) 104 | } 105 | 106 | public var center: ConstraintItem { 107 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.center) 108 | } 109 | 110 | } 111 | 112 | public protocol ConstraintAttributesDSL : ConstraintBasicAttributesDSL { 113 | } 114 | extension ConstraintAttributesDSL { 115 | 116 | // MARK: Baselines 117 | 118 | @available(*, deprecated:3.0, message:"Use .lastBaseline instead") 119 | public var baseline: ConstraintItem { 120 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.lastBaseline) 121 | } 122 | 123 | @available(iOS 8.0, OSX 10.11, *) 124 | public var lastBaseline: ConstraintItem { 125 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.lastBaseline) 126 | } 127 | 128 | @available(iOS 8.0, OSX 10.11, *) 129 | public var firstBaseline: ConstraintItem { 130 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.firstBaseline) 131 | } 132 | 133 | // MARK: Margins 134 | 135 | @available(iOS 8.0, *) 136 | public var leftMargin: ConstraintItem { 137 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.leftMargin) 138 | } 139 | 140 | @available(iOS 8.0, *) 141 | public var topMargin: ConstraintItem { 142 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.topMargin) 143 | } 144 | 145 | @available(iOS 8.0, *) 146 | public var rightMargin: ConstraintItem { 147 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.rightMargin) 148 | } 149 | 150 | @available(iOS 8.0, *) 151 | public var bottomMargin: ConstraintItem { 152 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.bottomMargin) 153 | } 154 | 155 | @available(iOS 8.0, *) 156 | public var leadingMargin: ConstraintItem { 157 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.leadingMargin) 158 | } 159 | 160 | @available(iOS 8.0, *) 161 | public var trailingMargin: ConstraintItem { 162 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.trailingMargin) 163 | } 164 | 165 | @available(iOS 8.0, *) 166 | public var centerXWithinMargins: ConstraintItem { 167 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.centerXWithinMargins) 168 | } 169 | 170 | @available(iOS 8.0, *) 171 | public var centerYWithinMargins: ConstraintItem { 172 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.centerYWithinMargins) 173 | } 174 | 175 | @available(iOS 8.0, *) 176 | public var margins: ConstraintItem { 177 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.margins) 178 | } 179 | 180 | @available(iOS 8.0, *) 181 | public var centerWithinMargins: ConstraintItem { 182 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.centerWithinMargins) 183 | } 184 | 185 | } 186 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintDescription.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public class ConstraintDescription { 32 | 33 | internal let item: LayoutConstraintItem 34 | internal var attributes: ConstraintAttributes 35 | internal var relation: ConstraintRelation? = nil 36 | internal var sourceLocation: (String, UInt)? = nil 37 | internal var label: String? = nil 38 | internal var related: ConstraintItem? = nil 39 | internal var multiplier: ConstraintMultiplierTarget = 1.0 40 | internal var constant: ConstraintConstantTarget = 0.0 41 | internal var priority: ConstraintPriorityTarget = 1000.0 42 | internal lazy var constraint: Constraint? = { 43 | guard let relation = self.relation, 44 | let related = self.related, 45 | let sourceLocation = self.sourceLocation else { 46 | return nil 47 | } 48 | let from = ConstraintItem(target: self.item as AnyObject, attributes: self.attributes) 49 | 50 | return Constraint( 51 | from: from, 52 | to: related, 53 | relation: relation, 54 | sourceLocation: sourceLocation, 55 | label: self.label, 56 | multiplier: self.multiplier, 57 | constant: self.constant, 58 | priority: self.priority 59 | ) 60 | }() 61 | 62 | // MARK: Initialization 63 | 64 | internal init(item: LayoutConstraintItem, attributes: ConstraintAttributes) { 65 | self.item = item 66 | self.attributes = attributes 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintInsetTarget.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public protocol ConstraintInsetTarget: ConstraintConstantTarget { 32 | } 33 | 34 | extension Int: ConstraintInsetTarget { 35 | } 36 | 37 | extension UInt: ConstraintInsetTarget { 38 | } 39 | 40 | extension Float: ConstraintInsetTarget { 41 | } 42 | 43 | extension Double: ConstraintInsetTarget { 44 | } 45 | 46 | extension CGFloat: ConstraintInsetTarget { 47 | } 48 | 49 | extension ConstraintInsets: ConstraintInsetTarget { 50 | } 51 | 52 | extension ConstraintInsetTarget { 53 | 54 | internal var constraintInsetTargetValue: ConstraintInsets { 55 | if let amount = self as? ConstraintInsets { 56 | return amount 57 | } else if let amount = self as? Float { 58 | return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount)) 59 | } else if let amount = self as? Double { 60 | return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount)) 61 | } else if let amount = self as? CGFloat { 62 | return ConstraintInsets(top: amount, left: amount, bottom: amount, right: amount) 63 | } else if let amount = self as? Int { 64 | return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount)) 65 | } else if let amount = self as? UInt { 66 | return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount)) 67 | } else { 68 | return ConstraintInsets(top: 0, left: 0, bottom: 0, right: 0) 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintInsets.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | #if os(iOS) || os(tvOS) 32 | public typealias ConstraintInsets = UIEdgeInsets 33 | #else 34 | public typealias ConstraintInsets = EdgeInsets 35 | #endif 36 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public class ConstraintItem : Equatable { 32 | 33 | internal weak var target: AnyObject? 34 | internal let attributes: ConstraintAttributes 35 | 36 | internal init(target: AnyObject?, attributes: ConstraintAttributes) { 37 | self.target = target 38 | self.attributes = attributes 39 | } 40 | 41 | internal var layoutConstraintItem: LayoutConstraintItem? { 42 | return self.target as? LayoutConstraintItem 43 | } 44 | 45 | } 46 | 47 | public func ==(lhs: ConstraintItem, rhs: ConstraintItem) -> Bool { 48 | // pointer equality 49 | guard lhs !== rhs else { 50 | return true 51 | } 52 | 53 | // must both have valid targets and identical attributes 54 | guard let target1 = lhs.target, 55 | let target2 = rhs.target, 56 | target1 === target2 && lhs.attributes == rhs.attributes else { 57 | return false 58 | } 59 | 60 | return true 61 | } 62 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintLayoutGuide+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #endif 27 | 28 | 29 | @available(iOS 9.0, OSX 10.11, *) 30 | public extension ConstraintLayoutGuide { 31 | 32 | public var snp: ConstraintLayoutGuideDSL { 33 | return ConstraintLayoutGuideDSL(guide: self) 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintLayoutGuide.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | #if os(iOS) || os(tvOS) 32 | @available(iOS 9.0, *) 33 | public typealias ConstraintLayoutGuide = UILayoutGuide 34 | #else 35 | @available(OSX 10.11, *) 36 | public typealias ConstraintLayoutGuide = NSLayoutGuide 37 | #endif 38 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintLayoutGuideDSL.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | @available(iOS 9.0, OSX 10.11, *) 32 | public struct ConstraintLayoutGuideDSL: ConstraintAttributesDSL { 33 | 34 | @discardableResult 35 | public func prepareConstraints(_ closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] { 36 | return ConstraintMaker.prepareConstraints(item: self.guide, closure: closure) 37 | } 38 | 39 | public func makeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) { 40 | ConstraintMaker.makeConstraints(item: self.guide, closure: closure) 41 | } 42 | 43 | public func remakeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) { 44 | ConstraintMaker.remakeConstraints(item: self.guide, closure: closure) 45 | } 46 | 47 | public func updateConstraints(_ closure: (_ make: ConstraintMaker) -> Void) { 48 | ConstraintMaker.updateConstraints(item: self.guide, closure: closure) 49 | } 50 | 51 | public func removeConstraints() { 52 | ConstraintMaker.removeConstraints(item: self.guide) 53 | } 54 | 55 | public var target: AnyObject? { 56 | return self.guide 57 | } 58 | 59 | internal let guide: ConstraintLayoutGuide 60 | 61 | internal init(guide: ConstraintLayoutGuide) { 62 | self.guide = guide 63 | 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintLayoutSupport.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | #if os(iOS) || os(tvOS) 32 | @available(iOS 8.0, *) 33 | public typealias ConstraintLayoutSupport = UILayoutSupport 34 | #else 35 | public class ConstraintLayoutSupport {} 36 | #endif 37 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintLayoutSupportDSL.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | @available(iOS 8.0, *) 32 | public struct ConstraintLayoutSupportDSL: ConstraintDSL { 33 | 34 | public var target: AnyObject? { 35 | return self.support 36 | } 37 | 38 | internal let support: ConstraintLayoutSupport 39 | 40 | internal init(support: ConstraintLayoutSupport) { 41 | self.support = support 42 | 43 | } 44 | 45 | public var top: ConstraintItem { 46 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.top) 47 | } 48 | 49 | public var bottom: ConstraintItem { 50 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.bottom) 51 | } 52 | 53 | public var height: ConstraintItem { 54 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.height) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintMaker.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | public class ConstraintMaker { 31 | 32 | public var left: ConstraintMakerExtendable { 33 | return self.makeExtendableWithAttributes(.left) 34 | } 35 | 36 | public var top: ConstraintMakerExtendable { 37 | return self.makeExtendableWithAttributes(.top) 38 | } 39 | 40 | public var bottom: ConstraintMakerExtendable { 41 | return self.makeExtendableWithAttributes(.bottom) 42 | } 43 | 44 | public var right: ConstraintMakerExtendable { 45 | return self.makeExtendableWithAttributes(.right) 46 | } 47 | 48 | public var leading: ConstraintMakerExtendable { 49 | return self.makeExtendableWithAttributes(.leading) 50 | } 51 | 52 | public var trailing: ConstraintMakerExtendable { 53 | return self.makeExtendableWithAttributes(.trailing) 54 | } 55 | 56 | public var width: ConstraintMakerExtendable { 57 | return self.makeExtendableWithAttributes(.width) 58 | } 59 | 60 | public var height: ConstraintMakerExtendable { 61 | return self.makeExtendableWithAttributes(.height) 62 | } 63 | 64 | public var centerX: ConstraintMakerExtendable { 65 | return self.makeExtendableWithAttributes(.centerX) 66 | } 67 | 68 | public var centerY: ConstraintMakerExtendable { 69 | return self.makeExtendableWithAttributes(.centerY) 70 | } 71 | 72 | @available(*, deprecated:3.0, message:"Use lastBaseline instead") 73 | public var baseline: ConstraintMakerExtendable { 74 | return self.makeExtendableWithAttributes(.lastBaseline) 75 | } 76 | 77 | public var lastBaseline: ConstraintMakerExtendable { 78 | return self.makeExtendableWithAttributes(.lastBaseline) 79 | } 80 | 81 | @available(iOS 8.0, OSX 10.11, *) 82 | public var firstBaseline: ConstraintMakerExtendable { 83 | return self.makeExtendableWithAttributes(.firstBaseline) 84 | } 85 | 86 | @available(iOS 8.0, *) 87 | public var leftMargin: ConstraintMakerExtendable { 88 | return self.makeExtendableWithAttributes(.leftMargin) 89 | } 90 | 91 | @available(iOS 8.0, *) 92 | public var rightMargin: ConstraintMakerExtendable { 93 | return self.makeExtendableWithAttributes(.rightMargin) 94 | } 95 | 96 | @available(iOS 8.0, *) 97 | public var topMargin: ConstraintMakerExtendable { 98 | return self.makeExtendableWithAttributes(.topMargin) 99 | } 100 | 101 | @available(iOS 8.0, *) 102 | public var bottomMargin: ConstraintMakerExtendable { 103 | return self.makeExtendableWithAttributes(.bottomMargin) 104 | } 105 | 106 | @available(iOS 8.0, *) 107 | public var leadingMargin: ConstraintMakerExtendable { 108 | return self.makeExtendableWithAttributes(.leadingMargin) 109 | } 110 | 111 | @available(iOS 8.0, *) 112 | public var trailingMargin: ConstraintMakerExtendable { 113 | return self.makeExtendableWithAttributes(.trailingMargin) 114 | } 115 | 116 | @available(iOS 8.0, *) 117 | public var centerXWithinMargins: ConstraintMakerExtendable { 118 | return self.makeExtendableWithAttributes(.centerXWithinMargins) 119 | } 120 | 121 | @available(iOS 8.0, *) 122 | public var centerYWithinMargins: ConstraintMakerExtendable { 123 | return self.makeExtendableWithAttributes(.centerYWithinMargins) 124 | } 125 | 126 | public var edges: ConstraintMakerExtendable { 127 | return self.makeExtendableWithAttributes(.edges) 128 | } 129 | public var size: ConstraintMakerExtendable { 130 | return self.makeExtendableWithAttributes(.size) 131 | } 132 | public var center: ConstraintMakerExtendable { 133 | return self.makeExtendableWithAttributes(.center) 134 | } 135 | 136 | @available(iOS 8.0, *) 137 | public var margins: ConstraintMakerExtendable { 138 | return self.makeExtendableWithAttributes(.margins) 139 | } 140 | 141 | @available(iOS 8.0, *) 142 | public var centerWithinMargins: ConstraintMakerExtendable { 143 | return self.makeExtendableWithAttributes(.centerWithinMargins) 144 | } 145 | 146 | private let item: LayoutConstraintItem 147 | private var descriptions = [ConstraintDescription]() 148 | 149 | internal init(item: LayoutConstraintItem) { 150 | self.item = item 151 | self.item.prepare() 152 | } 153 | 154 | internal func makeExtendableWithAttributes(_ attributes: ConstraintAttributes) -> ConstraintMakerExtendable { 155 | let description = ConstraintDescription(item: self.item, attributes: attributes) 156 | self.descriptions.append(description) 157 | return ConstraintMakerExtendable(description) 158 | } 159 | 160 | internal static func prepareConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] { 161 | let maker = ConstraintMaker(item: item) 162 | closure(maker) 163 | let constraints = maker.descriptions 164 | .map { $0.constraint } 165 | .filter { $0 != nil } 166 | .map { $0! } 167 | return constraints 168 | } 169 | 170 | internal static func makeConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) { 171 | let maker = ConstraintMaker(item: item) 172 | closure(maker) 173 | let constraints = maker.descriptions 174 | .map { $0.constraint } 175 | .filter { $0 != nil } 176 | .map { $0! } 177 | for constraint in constraints { 178 | constraint.activateIfNeeded(updatingExisting: false) 179 | } 180 | } 181 | 182 | internal static func remakeConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) { 183 | self.removeConstraints(item: item) 184 | self.makeConstraints(item: item, closure: closure) 185 | } 186 | 187 | internal static func updateConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) { 188 | guard item.constraints.count > 0 else { 189 | self.makeConstraints(item: item, closure: closure) 190 | return 191 | } 192 | 193 | let maker = ConstraintMaker(item: item) 194 | closure(maker) 195 | let constraints = maker.descriptions 196 | .map { $0.constraint } 197 | .filter { $0 != nil } 198 | .map { $0! } 199 | for constraint in constraints { 200 | constraint.activateIfNeeded(updatingExisting: true) 201 | } 202 | } 203 | 204 | internal static func removeConstraints(item: LayoutConstraintItem) { 205 | let constraints = item.constraints 206 | for constraint in constraints { 207 | constraint.deactivateIfNeeded() 208 | } 209 | } 210 | 211 | } 212 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintMakerEditable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public class ConstraintMakerEditable: ConstraintMakerPriortizable { 32 | 33 | @discardableResult 34 | public func multipliedBy(_ amount: ConstraintMultiplierTarget) -> ConstraintMakerEditable { 35 | self.description.multiplier = amount 36 | return self 37 | } 38 | 39 | @discardableResult 40 | public func dividedBy(_ amount: ConstraintMultiplierTarget) -> ConstraintMakerEditable { 41 | return self.multipliedBy(1.0 / amount.constraintMultiplierTargetValue) 42 | } 43 | 44 | @discardableResult 45 | public func offset(_ amount: ConstraintOffsetTarget) -> ConstraintMakerEditable { 46 | self.description.constant = amount.constraintOffsetTargetValue 47 | return self 48 | } 49 | 50 | @discardableResult 51 | public func inset(_ amount: ConstraintInsetTarget) -> ConstraintMakerEditable { 52 | self.description.constant = amount.constraintInsetTargetValue 53 | return self 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintMakerExtendable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public class ConstraintMakerExtendable: ConstraintMakerRelatable { 32 | 33 | public var left: ConstraintMakerExtendable { 34 | self.description.attributes += .left 35 | return self 36 | } 37 | 38 | public var top: ConstraintMakerExtendable { 39 | self.description.attributes += .top 40 | return self 41 | } 42 | 43 | public var bottom: ConstraintMakerExtendable { 44 | self.description.attributes += .bottom 45 | return self 46 | } 47 | 48 | public var right: ConstraintMakerExtendable { 49 | self.description.attributes += .right 50 | return self 51 | } 52 | 53 | public var leading: ConstraintMakerExtendable { 54 | self.description.attributes += .leading 55 | return self 56 | } 57 | 58 | public var trailing: ConstraintMakerExtendable { 59 | self.description.attributes += .trailing 60 | return self 61 | } 62 | 63 | public var width: ConstraintMakerExtendable { 64 | self.description.attributes += .width 65 | return self 66 | } 67 | 68 | public var height: ConstraintMakerExtendable { 69 | self.description.attributes += .height 70 | return self 71 | } 72 | 73 | public var centerX: ConstraintMakerExtendable { 74 | self.description.attributes += .centerX 75 | return self 76 | } 77 | 78 | public var centerY: ConstraintMakerExtendable { 79 | self.description.attributes += .centerY 80 | return self 81 | } 82 | 83 | @available(*, deprecated:3.0, message:"Use lastBaseline instead") 84 | public var baseline: ConstraintMakerExtendable { 85 | self.description.attributes += .lastBaseline 86 | return self 87 | } 88 | 89 | public var lastBaseline: ConstraintMakerExtendable { 90 | self.description.attributes += .lastBaseline 91 | return self 92 | } 93 | 94 | @available(iOS 8.0, OSX 10.11, *) 95 | public var firstBaseline: ConstraintMakerExtendable { 96 | self.description.attributes += .firstBaseline 97 | return self 98 | } 99 | 100 | @available(iOS 8.0, *) 101 | public var leftMargin: ConstraintMakerExtendable { 102 | self.description.attributes += .leftMargin 103 | return self 104 | } 105 | 106 | @available(iOS 8.0, *) 107 | public var rightMargin: ConstraintMakerExtendable { 108 | self.description.attributes += .rightMargin 109 | return self 110 | } 111 | 112 | @available(iOS 8.0, *) 113 | public var bottomMargin: ConstraintMakerExtendable { 114 | self.description.attributes += .bottomMargin 115 | return self 116 | } 117 | 118 | @available(iOS 8.0, *) 119 | public var leadingMargin: ConstraintMakerExtendable { 120 | self.description.attributes += .leadingMargin 121 | return self 122 | } 123 | 124 | @available(iOS 8.0, *) 125 | public var trailingMargin: ConstraintMakerExtendable { 126 | self.description.attributes += .trailingMargin 127 | return self 128 | } 129 | 130 | @available(iOS 8.0, *) 131 | public var centerXWithinMargins: ConstraintMakerExtendable { 132 | self.description.attributes += .centerXWithinMargins 133 | return self 134 | } 135 | 136 | @available(iOS 8.0, *) 137 | public var centerYWithinMargins: ConstraintMakerExtendable { 138 | self.description.attributes += .centerYWithinMargins 139 | return self 140 | } 141 | 142 | public var edges: ConstraintMakerExtendable { 143 | self.description.attributes += .edges 144 | return self 145 | } 146 | public var size: ConstraintMakerExtendable { 147 | self.description.attributes += .size 148 | return self 149 | } 150 | 151 | @available(iOS 8.0, *) 152 | public var margins: ConstraintMakerExtendable { 153 | self.description.attributes += .margins 154 | return self 155 | } 156 | 157 | @available(iOS 8.0, *) 158 | public var centerWithinMargins: ConstraintMakerExtendable { 159 | self.description.attributes += .centerWithinMargins 160 | return self 161 | } 162 | 163 | } 164 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintMakerFinalizable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public class ConstraintMakerFinalizable { 32 | 33 | internal let description: ConstraintDescription 34 | 35 | internal init(_ description: ConstraintDescription) { 36 | self.description = description 37 | } 38 | 39 | @discardableResult 40 | public func labeled(_ label: String) -> ConstraintMakerFinalizable { 41 | self.description.label = label 42 | return self 43 | } 44 | 45 | public var constraint: Constraint { 46 | return self.description.constraint! 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintMakerPriortizable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public class ConstraintMakerPriortizable: ConstraintMakerFinalizable { 32 | 33 | @discardableResult 34 | public func priority(_ amount: ConstraintPriorityTarget) -> ConstraintMakerFinalizable { 35 | self.description.priority = amount 36 | return self 37 | } 38 | 39 | @available(*, deprecated:3.0, message:"Use priority(_ amount: ConstraintPriorityTarget) instead.") 40 | @discardableResult 41 | public func priorityRequired() -> ConstraintMakerFinalizable { 42 | return self.priority(1000) 43 | } 44 | 45 | @available(*, deprecated:3.0, message:"Use priority(_ amount: ConstraintPriorityTarget) instead.") 46 | @discardableResult 47 | public func priorityHigh() -> ConstraintMakerFinalizable { 48 | return self.priority(750) 49 | } 50 | 51 | @available(*, deprecated:3.0, message:"Use priority(_ amount: ConstraintPriorityTarget) instead.") 52 | @discardableResult 53 | public func priorityMedium() -> ConstraintMakerFinalizable { 54 | #if os(iOS) || os(tvOS) 55 | return self.priority(500) 56 | #else 57 | return self.priority(501) 58 | #endif 59 | } 60 | 61 | @available(*, deprecated:3.0, message:"Use priority(_ amount: ConstraintPriorityTarget) instead.") 62 | @discardableResult 63 | public func priorityLow() -> ConstraintMakerFinalizable { 64 | return self.priority(250) 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintMakerRelatable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public class ConstraintMakerRelatable { 32 | 33 | internal let description: ConstraintDescription 34 | 35 | internal init(_ description: ConstraintDescription) { 36 | self.description = description 37 | } 38 | 39 | internal func relatedTo(_ other: ConstraintRelatableTarget, relation: ConstraintRelation, file: String, line: UInt) -> ConstraintMakerEditable { 40 | let related: ConstraintItem 41 | let constant: ConstraintConstantTarget 42 | 43 | if let other = other as? ConstraintItem { 44 | guard other.attributes == ConstraintAttributes.none || 45 | other.attributes.layoutAttributes.count <= 1 || 46 | other.attributes.layoutAttributes == self.description.attributes.layoutAttributes || 47 | other.attributes == .edges && self.description.attributes == .margins || 48 | other.attributes == .margins && self.description.attributes == .edges else { 49 | fatalError("Cannot constraint to multiple non identical attributes. (\(file), \(line))"); 50 | } 51 | 52 | related = other 53 | constant = 0.0 54 | } else if let other = other as? ConstraintView { 55 | related = ConstraintItem(target: other, attributes: ConstraintAttributes.none) 56 | constant = 0.0 57 | } else if let other = other as? ConstraintConstantTarget { 58 | related = ConstraintItem(target: nil, attributes: ConstraintAttributes.none) 59 | constant = other 60 | } else { 61 | fatalError("Invalid constraint. (\(file), \(line))") 62 | } 63 | 64 | let editable = ConstraintMakerEditable(self.description) 65 | editable.description.sourceLocation = (file, line) 66 | editable.description.relation = relation 67 | editable.description.related = related 68 | editable.description.constant = constant 69 | return editable 70 | } 71 | 72 | @discardableResult 73 | public func equalTo(_ other: ConstraintRelatableTarget, _ file: String = #file, _ line: UInt = #line) -> ConstraintMakerEditable { 74 | return self.relatedTo(other, relation: .equal, file: file, line: line) 75 | } 76 | 77 | @discardableResult 78 | public func equalToSuperview(_ file: String = #file, _ line: UInt = #line) -> ConstraintMakerEditable { 79 | guard let other = self.description.item.superview else { 80 | fatalError("Expected superview but found nil when attempting make constraint `equalToSuperview`.") 81 | } 82 | return self.relatedTo(other, relation: .equal, file: file, line: line) 83 | } 84 | 85 | @discardableResult 86 | public func lessThanOrEqualTo(_ other: ConstraintRelatableTarget, _ file: String = #file, _ line: UInt = #line) -> ConstraintMakerEditable { 87 | return self.relatedTo(other, relation: .lessThanOrEqual, file: file, line: line) 88 | } 89 | 90 | @discardableResult 91 | public func lessThanOrEqualToSuperview(_ file: String = #file, _ line: UInt = #line) -> ConstraintMakerEditable { 92 | guard let other = self.description.item.superview else { 93 | fatalError("Expected superview but found nil when attempting make constraint `lessThanOrEqualToSuperview`.") 94 | } 95 | return self.relatedTo(other, relation: .lessThanOrEqual, file: file, line: line) 96 | } 97 | 98 | @discardableResult 99 | public func greaterThanOrEqualTo(_ other: ConstraintRelatableTarget, _ file: String = #file, line: UInt = #line) -> ConstraintMakerEditable { 100 | return self.relatedTo(other, relation: .greaterThanOrEqual, file: file, line: line) 101 | } 102 | 103 | @discardableResult 104 | public func greaterThanOrEqualToSuperview(_ file: String = #file, line: UInt = #line) -> ConstraintMakerEditable { 105 | guard let other = self.description.item.superview else { 106 | fatalError("Expected superview but found nil when attempting make constraint `greaterThanOrEqualToSuperview`.") 107 | } 108 | return self.relatedTo(other, relation: .greaterThanOrEqual, file: file, line: line) 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintMultiplierTarget.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public protocol ConstraintMultiplierTarget { 32 | 33 | var constraintMultiplierTargetValue: CGFloat { get } 34 | 35 | } 36 | 37 | extension Int: ConstraintMultiplierTarget { 38 | 39 | public var constraintMultiplierTargetValue: CGFloat { 40 | return CGFloat(self) 41 | } 42 | 43 | } 44 | 45 | extension UInt: ConstraintMultiplierTarget { 46 | 47 | public var constraintMultiplierTargetValue: CGFloat { 48 | return CGFloat(self) 49 | } 50 | 51 | } 52 | 53 | extension Float: ConstraintMultiplierTarget { 54 | 55 | public var constraintMultiplierTargetValue: CGFloat { 56 | return CGFloat(self) 57 | } 58 | 59 | } 60 | 61 | extension Double: ConstraintMultiplierTarget { 62 | 63 | public var constraintMultiplierTargetValue: CGFloat { 64 | return CGFloat(self) 65 | } 66 | 67 | } 68 | 69 | extension CGFloat: ConstraintMultiplierTarget { 70 | 71 | public var constraintMultiplierTargetValue: CGFloat { 72 | return self 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintOffsetTarget.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public protocol ConstraintOffsetTarget: ConstraintConstantTarget { 32 | } 33 | 34 | extension Int: ConstraintOffsetTarget { 35 | } 36 | 37 | extension UInt: ConstraintOffsetTarget { 38 | } 39 | 40 | extension Float: ConstraintOffsetTarget { 41 | } 42 | 43 | extension Double: ConstraintOffsetTarget { 44 | } 45 | 46 | extension CGFloat: ConstraintOffsetTarget { 47 | } 48 | 49 | extension ConstraintOffsetTarget { 50 | 51 | internal var constraintOffsetTargetValue: CGFloat { 52 | let offset: CGFloat 53 | if let amount = self as? Float { 54 | offset = CGFloat(amount) 55 | } else if let amount = self as? Double { 56 | offset = CGFloat(amount) 57 | } else if let amount = self as? CGFloat { 58 | offset = CGFloat(amount) 59 | } else if let amount = self as? Int { 60 | offset = CGFloat(amount) 61 | } else if let amount = self as? UInt { 62 | offset = CGFloat(amount) 63 | } else { 64 | offset = 0.0 65 | } 66 | return offset 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintPriorityTarget.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public protocol ConstraintPriorityTarget { 32 | 33 | var constraintPriorityTargetValue: Float { get } 34 | 35 | } 36 | 37 | extension Int: ConstraintPriorityTarget { 38 | 39 | public var constraintPriorityTargetValue: Float { 40 | return Float(self) 41 | } 42 | 43 | } 44 | 45 | extension UInt: ConstraintPriorityTarget { 46 | 47 | public var constraintPriorityTargetValue: Float { 48 | return Float(self) 49 | } 50 | 51 | } 52 | 53 | extension Float: ConstraintPriorityTarget { 54 | 55 | public var constraintPriorityTargetValue: Float { 56 | return self 57 | } 58 | 59 | } 60 | 61 | extension Double: ConstraintPriorityTarget { 62 | 63 | public var constraintPriorityTargetValue: Float { 64 | return Float(self) 65 | } 66 | 67 | } 68 | 69 | extension CGFloat: ConstraintPriorityTarget { 70 | 71 | public var constraintPriorityTargetValue: Float { 72 | return Float(self) 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintRelatableTarget.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public protocol ConstraintRelatableTarget { 32 | } 33 | 34 | extension Int: ConstraintRelatableTarget { 35 | } 36 | 37 | extension UInt: ConstraintRelatableTarget { 38 | } 39 | 40 | extension Float: ConstraintRelatableTarget { 41 | } 42 | 43 | extension Double: ConstraintRelatableTarget { 44 | } 45 | 46 | extension CGFloat: ConstraintRelatableTarget { 47 | } 48 | 49 | extension CGSize: ConstraintRelatableTarget { 50 | } 51 | 52 | extension CGPoint: ConstraintRelatableTarget { 53 | } 54 | 55 | extension ConstraintInsets: ConstraintRelatableTarget { 56 | } 57 | 58 | extension ConstraintItem: ConstraintRelatableTarget { 59 | } 60 | 61 | extension ConstraintView: ConstraintRelatableTarget { 62 | } 63 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintRelation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | internal enum ConstraintRelation : Int { 32 | case equal = 1 33 | case lessThanOrEqual 34 | case greaterThanOrEqual 35 | 36 | internal var layoutRelation: NSLayoutRelation { 37 | get { 38 | switch(self) { 39 | case .equal: 40 | return .equal 41 | case .lessThanOrEqual: 42 | return .lessThanOrEqual 43 | case .greaterThanOrEqual: 44 | return .greaterThanOrEqual 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintView+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public extension ConstraintView { 32 | 33 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 34 | public var snp_left: ConstraintItem { return self.snp.left } 35 | 36 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 37 | public var snp_top: ConstraintItem { return self.snp.top } 38 | 39 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 40 | public var snp_right: ConstraintItem { return self.snp.right } 41 | 42 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 43 | public var snp_bottom: ConstraintItem { return self.snp.bottom } 44 | 45 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 46 | public var snp_leading: ConstraintItem { return self.snp.leading } 47 | 48 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 49 | public var snp_trailing: ConstraintItem { return self.snp.trailing } 50 | 51 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 52 | public var snp_width: ConstraintItem { return self.snp.width } 53 | 54 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 55 | public var snp_height: ConstraintItem { return self.snp.height } 56 | 57 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 58 | public var snp_centerX: ConstraintItem { return self.snp.centerX } 59 | 60 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 61 | public var snp_centerY: ConstraintItem { return self.snp.centerY } 62 | 63 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 64 | public var snp_baseline: ConstraintItem { return self.snp.baseline } 65 | 66 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 67 | @available(iOS 8.0, OSX 10.11, *) 68 | public var snp_lastBaseline: ConstraintItem { return self.snp.lastBaseline } 69 | 70 | @available(iOS, deprecated:3.0, message:"Use newer snp.* syntax.") 71 | @available(iOS 8.0, OSX 10.11, *) 72 | public var snp_firstBaseline: ConstraintItem { return self.snp.firstBaseline } 73 | 74 | @available(iOS, deprecated:3.0, message:"Use newer snp.* syntax.") 75 | @available(iOS 8.0, *) 76 | public var snp_leftMargin: ConstraintItem { return self.snp.leftMargin } 77 | 78 | @available(iOS, deprecated:3.0, message:"Use newer snp.* syntax.") 79 | @available(iOS 8.0, *) 80 | public var snp_topMargin: ConstraintItem { return self.snp.topMargin } 81 | 82 | @available(iOS, deprecated:3.0, message:"Use newer snp.* syntax.") 83 | @available(iOS 8.0, *) 84 | public var snp_rightMargin: ConstraintItem { return self.snp.rightMargin } 85 | 86 | @available(iOS, deprecated:3.0, message:"Use newer snp.* syntax.") 87 | @available(iOS 8.0, *) 88 | public var snp_bottomMargin: ConstraintItem { return self.snp.bottomMargin } 89 | 90 | @available(iOS, deprecated:3.0, message:"Use newer snp.* syntax.") 91 | @available(iOS 8.0, *) 92 | public var snp_leadingMargin: ConstraintItem { return self.snp.leadingMargin } 93 | 94 | @available(iOS, deprecated:3.0, message:"Use newer snp.* syntax.") 95 | @available(iOS 8.0, *) 96 | public var snp_trailingMargin: ConstraintItem { return self.snp.trailingMargin } 97 | 98 | @available(iOS, deprecated:3.0, message:"Use newer snp.* syntax.") 99 | @available(iOS 8.0, *) 100 | public var snp_centerXWithinMargins: ConstraintItem { return self.snp.centerXWithinMargins } 101 | 102 | @available(iOS, deprecated:3.0, message:"Use newer snp.* syntax.") 103 | @available(iOS 8.0, *) 104 | public var snp_centerYWithinMargins: ConstraintItem { return self.snp.centerYWithinMargins } 105 | 106 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 107 | public var snp_edges: ConstraintItem { return self.snp.edges } 108 | 109 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 110 | public var snp_size: ConstraintItem { return self.snp.size } 111 | 112 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 113 | public var snp_center: ConstraintItem { return self.snp.center } 114 | 115 | @available(iOS, deprecated:3.0, message:"Use newer snp.* syntax.") 116 | @available(iOS 8.0, *) 117 | public var snp_margins: ConstraintItem { return self.snp.margins } 118 | 119 | @available(iOS, deprecated:3.0, message:"Use newer snp.* syntax.") 120 | @available(iOS 8.0, *) 121 | public var snp_centerWithinMargins: ConstraintItem { return self.snp.centerWithinMargins } 122 | 123 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 124 | public func snp_prepareConstraints(_ closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] { 125 | return self.snp.prepareConstraints(closure) 126 | } 127 | 128 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 129 | public func snp_makeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) { 130 | self.snp.makeConstraints(closure) 131 | } 132 | 133 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 134 | public func snp_remakeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) { 135 | self.snp.remakeConstraints(closure) 136 | } 137 | 138 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 139 | public func snp_updateConstraints(_ closure: (_ make: ConstraintMaker) -> Void) { 140 | self.snp.updateConstraints(closure) 141 | } 142 | 143 | @available(*, deprecated:3.0, message:"Use newer snp.* syntax.") 144 | public func snp_removeConstraints() { 145 | self.snp.removeConstraints() 146 | } 147 | 148 | public var snp: ConstraintViewDSL { 149 | return ConstraintViewDSL(view: self) 150 | } 151 | 152 | } 153 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | #if os(iOS) || os(tvOS) 32 | public typealias ConstraintView = UIView 33 | #else 34 | public typealias ConstraintView = NSView 35 | #endif 36 | -------------------------------------------------------------------------------- /Vendors/SnapKit/ConstraintViewDSL.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public struct ConstraintViewDSL: ConstraintAttributesDSL { 32 | 33 | @discardableResult 34 | public func prepareConstraints(_ closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] { 35 | return ConstraintMaker.prepareConstraints(item: self.view, closure: closure) 36 | } 37 | 38 | public func makeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) { 39 | ConstraintMaker.makeConstraints(item: self.view, closure: closure) 40 | } 41 | 42 | public func remakeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) { 43 | ConstraintMaker.remakeConstraints(item: self.view, closure: closure) 44 | } 45 | 46 | public func updateConstraints(_ closure: (_ make: ConstraintMaker) -> Void) { 47 | ConstraintMaker.updateConstraints(item: self.view, closure: closure) 48 | } 49 | 50 | public func removeConstraints() { 51 | ConstraintMaker.removeConstraints(item: self.view) 52 | } 53 | 54 | public var contentHuggingHorizontalPriority: Float { 55 | get { 56 | return self.view.contentHuggingPriority(for: .horizontal) 57 | } 58 | set { 59 | self.view.setContentHuggingPriority(newValue, for: .horizontal) 60 | } 61 | } 62 | 63 | public var contentHuggingVerticalPriority: Float { 64 | get { 65 | return self.view.contentHuggingPriority(for: .vertical) 66 | } 67 | set { 68 | self.view.setContentHuggingPriority(newValue, for: .vertical) 69 | } 70 | } 71 | 72 | public var contentCompressionResistanceHorizontalPriority: Float { 73 | get { 74 | return self.view.contentCompressionResistancePriority(for: .horizontal) 75 | } 76 | set { 77 | self.view.setContentHuggingPriority(newValue, for: .horizontal) 78 | } 79 | } 80 | 81 | public var contentCompressionResistanceVerticalPriority: Float { 82 | get { 83 | return self.view.contentCompressionResistancePriority(for: .vertical) 84 | } 85 | set { 86 | self.view.setContentCompressionResistancePriority(newValue, for: .vertical) 87 | } 88 | } 89 | 90 | public var target: AnyObject? { 91 | return self.view 92 | } 93 | 94 | internal let view: ConstraintView 95 | 96 | internal init(view: ConstraintView) { 97 | self.view = view 98 | 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /Vendors/SnapKit/Debugging.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | public extension LayoutConstraint { 31 | 32 | override public var description: String { 33 | var description = "<" 34 | 35 | description += descriptionForObject(self) 36 | 37 | if let firstItem = conditionalOptional(from: self.firstItem) { 38 | description += " \(descriptionForObject(firstItem))" 39 | } 40 | 41 | if self.firstAttribute != .notAnAttribute { 42 | description += ".\(descriptionForAttribute(self.firstAttribute))" 43 | } 44 | 45 | description += " \(descriptionForRelation(self.relation))" 46 | 47 | if let secondItem = self.secondItem { 48 | description += " \(descriptionForObject(secondItem))" 49 | } 50 | 51 | if self.secondAttribute != .notAnAttribute { 52 | description += ".\(descriptionForAttribute(self.secondAttribute))" 53 | } 54 | 55 | if self.multiplier != 1.0 { 56 | description += " * \(self.multiplier)" 57 | } 58 | 59 | if self.secondAttribute == .notAnAttribute { 60 | description += " \(self.constant)" 61 | } else { 62 | if self.constant > 0.0 { 63 | description += " + \(self.constant)" 64 | } else if self.constant < 0.0 { 65 | description += " - \(abs(self.constant))" 66 | } 67 | } 68 | 69 | if self.priority != 1000.0 { 70 | description += " ^\(self.priority)" 71 | } 72 | 73 | description += ">" 74 | 75 | return description 76 | } 77 | 78 | } 79 | 80 | private func descriptionForRelation(_ relation: NSLayoutRelation) -> String { 81 | switch relation { 82 | case .equal: return "==" 83 | case .greaterThanOrEqual: return ">=" 84 | case .lessThanOrEqual: return "<=" 85 | } 86 | } 87 | 88 | private func descriptionForAttribute(_ attribute: NSLayoutAttribute) -> String { 89 | #if os(iOS) || os(tvOS) 90 | switch attribute { 91 | case .notAnAttribute: return "notAnAttribute" 92 | case .top: return "top" 93 | case .left: return "left" 94 | case .bottom: return "bottom" 95 | case .right: return "right" 96 | case .leading: return "leading" 97 | case .trailing: return "trailing" 98 | case .width: return "width" 99 | case .height: return "height" 100 | case .centerX: return "centerX" 101 | case .centerY: return "centerY" 102 | case .lastBaseline: return "lastBaseline" 103 | case .firstBaseline: return "firstBaseline" 104 | case .topMargin: return "topMargin" 105 | case .leftMargin: return "leftMargin" 106 | case .bottomMargin: return "bottomMargin" 107 | case .rightMargin: return "rightMargin" 108 | case .leadingMargin: return "leadingMargin" 109 | case .trailingMargin: return "trailingMargin" 110 | case .centerXWithinMargins: return "centerXWithinMargins" 111 | case .centerYWithinMargins: return "centerYWithinMargins" 112 | } 113 | #else 114 | switch attribute { 115 | case .notAnAttribute: return "notAnAttribute" 116 | case .top: return "top" 117 | case .left: return "left" 118 | case .bottom: return "bottom" 119 | case .right: return "right" 120 | case .leading: return "leading" 121 | case .trailing: return "trailing" 122 | case .width: return "width" 123 | case .height: return "height" 124 | case .centerX: return "centerX" 125 | case .centerY: return "centerY" 126 | case .lastBaseline: return "lastBaseline" 127 | case .firstBaseline: return "firstBaseline" 128 | } 129 | #endif 130 | } 131 | 132 | private func conditionalOptional(from object: Optional) -> Optional { 133 | return object 134 | } 135 | 136 | private func conditionalOptional(from object: T) -> Optional { 137 | return Optional.some(object) 138 | } 139 | 140 | private func descriptionForObject(_ object: AnyObject) -> String { 141 | let pointerDescription = String(format: "%p", UInt(bitPattern: ObjectIdentifier(object))) 142 | var desc = "" 143 | 144 | desc += type(of: object).description() 145 | 146 | if let object = object as? ConstraintView { 147 | desc += ":\(object.snp.label() ?? pointerDescription)" 148 | } else if let object = object as? LayoutConstraint { 149 | desc += ":\(object.label ?? pointerDescription)" 150 | } else { 151 | desc += ":\(pointerDescription)" 152 | } 153 | 154 | if let object = object as? LayoutConstraint, let file = object.constraint?.sourceLocation.0, let line = object.constraint?.sourceLocation.1 { 155 | desc += "@\((file as NSString).lastPathComponent)#\(line)" 156 | } 157 | 158 | desc += "" 159 | return desc 160 | } 161 | -------------------------------------------------------------------------------- /Vendors/SnapKit/LayoutConstraint.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public class LayoutConstraint : NSLayoutConstraint { 32 | 33 | public var label: String? { 34 | get { 35 | return self.identifier 36 | } 37 | set { 38 | self.identifier = newValue 39 | } 40 | } 41 | 42 | internal weak var constraint: Constraint? = nil 43 | 44 | } 45 | 46 | internal func ==(lhs: LayoutConstraint, rhs: LayoutConstraint) -> Bool { 47 | guard lhs.firstItem === rhs.firstItem && 48 | lhs.secondItem === rhs.secondItem && 49 | lhs.firstAttribute == rhs.firstAttribute && 50 | lhs.secondAttribute == rhs.secondAttribute && 51 | lhs.relation == rhs.relation && 52 | lhs.priority == rhs.priority && 53 | lhs.multiplier == rhs.multiplier else { 54 | return false 55 | } 56 | return true 57 | } 58 | -------------------------------------------------------------------------------- /Vendors/SnapKit/LayoutConstraintItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #else 27 | import AppKit 28 | #endif 29 | 30 | 31 | public protocol LayoutConstraintItem: class { 32 | } 33 | 34 | @available(iOS 9.0, OSX 10.11, *) 35 | extension ConstraintLayoutGuide : LayoutConstraintItem { 36 | } 37 | 38 | extension ConstraintView : LayoutConstraintItem { 39 | } 40 | 41 | 42 | extension LayoutConstraintItem { 43 | 44 | internal func prepare() { 45 | if let view = self as? ConstraintView { 46 | view.translatesAutoresizingMaskIntoConstraints = false 47 | } 48 | } 49 | 50 | internal var superview: ConstraintView? { 51 | if let view = self as? ConstraintView { 52 | return view.superview 53 | } 54 | 55 | if #available(iOS 9.0, OSX 10.11, *), let guide = self as? ConstraintLayoutGuide { 56 | return guide.owningView 57 | } 58 | 59 | return nil 60 | } 61 | internal var constraints: [Constraint] { 62 | return self.constraintsHashTable.allObjects 63 | } 64 | 65 | internal func add(constraints: [Constraint]) { 66 | let hashTable = self.constraintsHashTable 67 | for constraint in constraints { 68 | hashTable.add(constraint) 69 | } 70 | } 71 | 72 | internal func remove(constraints: [Constraint]) { 73 | let hashTable = self.constraintsHashTable 74 | for constraint in constraints { 75 | hashTable.remove(constraint) 76 | } 77 | } 78 | 79 | private var constraintsHashTable: NSHashTable { 80 | let constraints: NSHashTable 81 | 82 | if let existing = objc_getAssociatedObject(self, &constraintsKey) as? NSHashTable { 83 | constraints = existing 84 | } else { 85 | constraints = NSHashTable() 86 | objc_setAssociatedObject(self, &constraintsKey, constraints, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 87 | } 88 | return constraints 89 | 90 | } 91 | 92 | } 93 | private var constraintsKey: UInt8 = 0 94 | -------------------------------------------------------------------------------- /Vendors/SnapKit/SnapKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #import 25 | 26 | FOUNDATION_EXPORT double SnapKitVersionNumber; 27 | FOUNDATION_EXPORT const unsigned char SnapKitVersionString[]; -------------------------------------------------------------------------------- /Vendors/SnapKit/UILayoutSupport+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SnapKit 3 | // 4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | 24 | #if os(iOS) || os(tvOS) 25 | import UIKit 26 | #endif 27 | 28 | 29 | @available(iOS 8.0, *) 30 | public extension ConstraintLayoutSupport { 31 | 32 | public var snp: ConstraintLayoutSupportDSL { 33 | return ConstraintLayoutSupportDSL(support: self) 34 | } 35 | 36 | } 37 | --------------------------------------------------------------------------------