diff --git a/BWCircularSlider.xcodeproj/project.pbxproj b/BWCircularSlider.xcodeproj/project.pbxproj old mode 100644 new mode 100755 index 9058bd6..6ba642d --- a/BWCircularSlider.xcodeproj/project.pbxproj +++ b/BWCircularSlider.xcodeproj/project.pbxproj @@ -137,6 +137,7 @@ TargetAttributes = { DAEB2FAD1A0827EE002EE5EF = { CreatedOnToolsVersion = 6.0.1; + LastSwiftMigration = 0820; }; }; }; @@ -289,6 +290,7 @@ INFOPLIST_FILE = TB_CustomControlsSwift/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = BWCircularSlider; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -299,6 +301,7 @@ INFOPLIST_FILE = TB_CustomControlsSwift/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_NAME = BWCircularSlider; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/BWCircularSlider.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/BWCircularSlider.xcodeproj/project.xcworkspace/contents.xcworkspacedata old mode 100644 new mode 100755 diff --git a/BWCircularSlider.xcodeproj/project.xcworkspace/xcshareddata/BWCircularSlider.xccheckout b/BWCircularSlider.xcodeproj/project.xcworkspace/xcshareddata/BWCircularSlider.xccheckout old mode 100644 new mode 100755 diff --git a/BWCircularSlider.xcodeproj/project.xcworkspace/xcuserdata/bitwaker.xcuserdatad/UserInterfaceState.xcuserstate b/BWCircularSlider.xcodeproj/project.xcworkspace/xcuserdata/bitwaker.xcuserdatad/UserInterfaceState.xcuserstate old mode 100644 new mode 100755 diff --git a/BWCircularSlider.xcodeproj/project.xcworkspace/xcuserdata/bitwaker.xcuserdatad/WorkspaceSettings.xcsettings b/BWCircularSlider.xcodeproj/project.xcworkspace/xcuserdata/bitwaker.xcuserdatad/WorkspaceSettings.xcsettings old mode 100644 new mode 100755 diff --git a/BWCircularSlider.xcodeproj/xcuserdata/bitwaker.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/BWCircularSlider.xcodeproj/xcuserdata/bitwaker.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist old mode 100644 new mode 100755 diff --git a/BWCircularSlider.xcodeproj/xcuserdata/bitwaker.xcuserdatad/xcschemes/TB_CustomControlsSwift.xcscheme b/BWCircularSlider.xcodeproj/xcuserdata/bitwaker.xcuserdatad/xcschemes/TB_CustomControlsSwift.xcscheme old mode 100644 new mode 100755 diff --git a/BWCircularSlider.xcodeproj/xcuserdata/bitwaker.xcuserdatad/xcschemes/xcschememanagement.plist b/BWCircularSlider.xcodeproj/xcuserdata/bitwaker.xcuserdatad/xcschemes/xcschememanagement.plist old mode 100644 new mode 100755 diff --git a/TB_CustomControlsSwift/AppDelegate.swift b/TB_CustomControlsSwift/AppDelegate.swift old mode 100644 new mode 100755 index eb78c32..ba8e326 --- a/TB_CustomControlsSwift/AppDelegate.swift +++ b/TB_CustomControlsSwift/AppDelegate.swift @@ -14,30 +14,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true } - func applicationWillResignActive(application: UIApplication) { + func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } - func applicationDidEnterBackground(application: UIApplication) { + func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - func applicationWillEnterForeground(application: UIApplication) { + func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - func applicationDidBecomeActive(application: UIApplication) { + func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - func applicationWillTerminate(application: UIApplication) { + func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } diff --git a/TB_CustomControlsSwift/BWCircularSlider.swift b/TB_CustomControlsSwift/BWCircularSlider.swift old mode 100644 new mode 100755 index c1945a4..8404cc4 --- a/TB_CustomControlsSwift/BWCircularSlider.swift +++ b/TB_CustomControlsSwift/BWCircularSlider.swift @@ -9,26 +9,23 @@ import UIKit struct Config { - - static let TB_SLIDER_SIZE:CGFloat = UIScreen.mainScreen().bounds.size.width + static let TB_SLIDER_SIZE:CGFloat = UIScreen.main.bounds.size.width static let TB_SAFEAREA_PADDING:CGFloat = 60.0 static let TB_LINE_WIDTH:CGFloat = 40.0 static let TB_FONTSIZE:CGFloat = 40.0 - } - // MARK: Math Helpers -func DegreesToRadians (value:Double) -> Double { +func DegreesToRadians (_ value:Double) -> Double { return value * M_PI / 180.0 } -func RadiansToDegrees (value:Double) -> Double { +func RadiansToDegrees (_ value:Double) -> Double { return value * 180.0 / M_PI } -func Square (value:CGFloat) -> CGFloat { +func Square (_ value:CGFloat) -> CGFloat { return value * value } @@ -36,12 +33,11 @@ func Square (value:CGFloat) -> CGFloat { // MARK: Circular Slider class BWCircularSlider: UIControl { - var textField:UITextField? var radius:CGFloat = 0 var angle:Int = 360 - var startColor = UIColor.blueColor() - var endColor = UIColor.purpleColor() + var startColor = UIColor.blue + var endColor = UIColor.purple // Custom initializer convenience init(startColor:UIColor, endColor:UIColor, frame:CGRect){ @@ -55,8 +51,8 @@ class BWCircularSlider: UIControl { override init(frame: CGRect) { super.init(frame: frame) - self.backgroundColor = UIColor.clearColor() - self.opaque = true + self.backgroundColor = UIColor.clear + self.isOpaque = true //Define the circle radius taking into account the safe area radius = self.frame.size.width/2 - Config.TB_SAFEAREA_PADDING @@ -65,18 +61,18 @@ class BWCircularSlider: UIControl { let font = UIFont(name: "Avenir", size: Config.TB_FONTSIZE) //Calculate font size needed to display 3 numbers let str = "000" as NSString - let fontSize:CGSize = str.sizeWithAttributes([NSFontAttributeName:font!]) + let fontSize:CGSize = str.size(attributes: [NSFontAttributeName:font!]) //Using a TextField area we can easily modify the control to get user input from this field - let textFieldRect = CGRectMake( - (frame.size.width - fontSize.width) / 2.0, - (frame.size.height - fontSize.height) / 2.0, - fontSize.width, fontSize.height); + let textFieldRect = CGRect( + x: (frame.size.width - fontSize.width) / 2.0, + y: (frame.size.height - fontSize.height) / 2.0, + width: fontSize.width, height: fontSize.height) textField = UITextField(frame: textFieldRect) - textField?.backgroundColor = UIColor.clearColor() + textField?.backgroundColor = UIColor.clear textField?.textColor = UIColor(white: 1.0, alpha: 0.8) - textField?.textAlignment = .Center + textField?.textAlignment = .center textField?.font = font textField?.text = "\(self.angle)" @@ -88,80 +84,86 @@ class BWCircularSlider: UIControl { } - override func beginTrackingWithTouch(touch: UITouch, withEvent event: UIEvent) -> Bool { - super.beginTrackingWithTouch(touch, withEvent: event) + override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { + super.beginTracking(touch, with: event) return true } - override func continueTrackingWithTouch(touch: UITouch, withEvent event: UIEvent) -> Bool { - super.continueTrackingWithTouch(touch, withEvent: event) + override func continueTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { + super.continueTracking(touch, with: event) - let lastPoint = touch.locationInView(self) + let lastPoint = touch.location(in: self) self.moveHandle(lastPoint) - self.sendActionsForControlEvents(UIControlEvents.ValueChanged) + self.sendActions(for: UIControlEvents.valueChanged) return true } - override func endTrackingWithTouch(touch: UITouch, withEvent event: UIEvent) { - super.endTrackingWithTouch(touch, withEvent: event) + override func endTracking(_ touch: UITouch?, with event: UIEvent?) { + super.endTracking(touch, with: event) } //Use the draw rect to draw the Background, the Circle and the Handle - override func drawRect(rect: CGRect){ - super.drawRect(rect) + override func draw(_ rect: CGRect){ + super.draw(rect) let ctx = UIGraphicsGetCurrentContext() /** Draw the Background **/ - CGContextAddArc(ctx, CGFloat(self.frame.size.width / 2.0), CGFloat(self.frame.size.height / 2.0), radius, 0, CGFloat(M_PI * 2), 0) + let point = CGPoint(x: CGFloat(self.frame.size.width / 2.0), y: CGFloat(self.frame.size.height / 2.0)) + + ctx?.addArc(center: point, radius: radius, startAngle: 0, endAngle: CGFloat(M_PI * 2), clockwise: false) + UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0).set() - CGContextSetLineWidth(ctx, 72) - CGContextSetLineCap(ctx, kCGLineCapButt) + ctx?.setLineWidth(72) + ctx?.setLineCap(.butt) - CGContextDrawPath(ctx, kCGPathStroke) + ctx?.drawPath(using: .stroke) /** Draw the circle **/ /** Create THE MASK Image **/ - UIGraphicsBeginImageContext(CGSizeMake(self.bounds.size.width,self.bounds.size.height)); + UIGraphicsBeginImageContext(CGSize(width: self.bounds.size.width,height: self.bounds.size.height)) let imageCtx = UIGraphicsGetCurrentContext() - CGContextAddArc(imageCtx, CGFloat(self.frame.size.width/2) , CGFloat(self.frame.size.height/2), radius, 0, CGFloat(DegreesToRadians(Double(angle))) , 0); - UIColor.redColor().set() + imageCtx?.addArc(center: point, radius: radius, startAngle: 0, endAngle: CGFloat(DegreesToRadians(Double(angle))), clockwise: false) + + UIColor.red.set() //Use shadow to create the Blur effect - CGContextSetShadowWithColor(imageCtx, CGSizeMake(0, 0), CGFloat(self.angle/15), UIColor.blackColor().CGColor); + imageCtx?.setShadow(offset: CGSize(width: 0, height: 0), blur: CGFloat(self.angle/15), color: UIColor.black.cgColor) //define the path - CGContextSetLineWidth(imageCtx, Config.TB_LINE_WIDTH) - CGContextDrawPath(imageCtx, kCGPathStroke) + imageCtx?.setLineWidth(Config.TB_LINE_WIDTH) + + imageCtx?.drawPath(using: .stroke) //save the context content into the image mask - var mask:CGImageRef = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext()); - UIGraphicsEndImageContext(); + let mask:CGImage = UIGraphicsGetCurrentContext()!.makeImage()! + UIGraphicsEndImageContext() /** Clip Context to the mask **/ - CGContextSaveGState(ctx) + ctx?.saveGState() - CGContextClipToMask(ctx, self.bounds, mask) + ctx?.clip(to: self.bounds, mask: mask) /** The Gradient **/ // Split colors in components (rgba) - let startColorComps:UnsafePointer = CGColorGetComponents(startColor.CGColor); - let endColorComps:UnsafePointer = CGColorGetComponents(endColor.CGColor); + + let startColorComps = startColor.cgColor.components! + let endColorComps = endColor.cgColor.components! let components : [CGFloat] = [ startColorComps[0], startColorComps[1], startColorComps[2], 1.0, // Start color @@ -170,18 +172,19 @@ class BWCircularSlider: UIControl { // Setup the gradient let baseSpace = CGColorSpaceCreateDeviceRGB() - let gradient = CGGradientCreateWithColorComponents(baseSpace, components, nil, 2) + let gradient = CGGradient(colorSpace: baseSpace, colorComponents: components, locations: nil, count: 2) // Gradient direction - let startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect)) - let endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect)) + let startPoint = CGPoint(x: rect.midX, y: rect.minY) + let endPoint = CGPoint(x: rect.midX, y: rect.maxY) // Draw the gradient - CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint, 0); - CGContextRestoreGState(ctx); + + ctx?.drawLinearGradient(gradient!, start: startPoint, end: endPoint, options: CGGradientDrawingOptions(rawValue: 0)) + ctx?.restoreGState() /* Draw the handle */ - drawTheHandle(ctx) + drawTheHandle(ctx!) } @@ -189,33 +192,31 @@ class BWCircularSlider: UIControl { /** Draw a white knob over the circle **/ - func drawTheHandle(ctx:CGContextRef){ + func drawTheHandle(_ ctx:CGContext){ - CGContextSaveGState(ctx); + ctx.saveGState() //I Love shadows - CGContextSetShadowWithColor(ctx, CGSizeMake(0, 0), 3, UIColor.blackColor().CGColor); + ctx.setShadow(offset: CGSize(width: 0, height: 0), blur: 3, color: UIColor.black.cgColor) //Get the handle position - var handleCenter = pointFromAngle(angle) + let handleCenter = pointFromAngle(angle) //Draw It! - UIColor(white:1.0, alpha:0.7).set(); - CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x, handleCenter.y, Config.TB_LINE_WIDTH, Config.TB_LINE_WIDTH)); + UIColor(white:1.0, alpha:0.7).set() + ctx.fillEllipse(in: CGRect(x: handleCenter.x, y: handleCenter.y, width: Config.TB_LINE_WIDTH, height: Config.TB_LINE_WIDTH)) - CGContextRestoreGState(ctx); + ctx.restoreGState() } - - /** Move the Handle **/ - func moveHandle(lastPoint:CGPoint){ + func moveHandle(_ lastPoint:CGPoint){ //Get the center - let centerPoint:CGPoint = CGPointMake(self.frame.size.width/2, self.frame.size.height/2); + let centerPoint:CGPoint = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height/2) //Calculate the direction from a center point and a arbitrary position. - let currentAngle:Double = AngleFromNorth(centerPoint, p2: lastPoint, flipped: false); + let currentAngle:Double = AngleFromNorth(centerPoint, p2: lastPoint, flipped: false) let angleInt = Int(floor(currentAngle)) //Store the new angle @@ -229,33 +230,33 @@ class BWCircularSlider: UIControl { } /** Given the angle, get the point position on circumference **/ - func pointFromAngle(angleInt:Int)->CGPoint{ + func pointFromAngle(_ angleInt:Int)->CGPoint{ //Circle center - let centerPoint = CGPointMake(self.frame.size.width/2.0 - Config.TB_LINE_WIDTH/2.0, self.frame.size.height/2.0 - Config.TB_LINE_WIDTH/2.0); + let centerPoint = CGPoint(x: self.frame.size.width/2.0 - Config.TB_LINE_WIDTH/2.0, y: self.frame.size.height/2.0 - Config.TB_LINE_WIDTH/2.0) //The point position on the circumference - var result:CGPoint = CGPointZero + var result:CGPoint = CGPoint.zero let y = round(Double(radius) * sin(DegreesToRadians(Double(-angleInt)))) + Double(centerPoint.y) let x = round(Double(radius) * cos(DegreesToRadians(Double(-angleInt)))) + Double(centerPoint.x) result.y = CGFloat(y) result.x = CGFloat(x) - return result; + return result } //Sourcecode from Apple example clockControl //Calculate the direction in degrees from a center point to an arbitrary position. - func AngleFromNorth(p1:CGPoint , p2:CGPoint , flipped:Bool) -> Double { - var v:CGPoint = CGPointMake(p2.x - p1.x, p2.y - p1.y) + func AngleFromNorth(_ p1:CGPoint , p2:CGPoint , flipped:Bool) -> Double { + var v:CGPoint = CGPoint(x: p2.x - p1.x, y: p2.y - p1.y) let vmag:CGFloat = Square(Square(v.x) + Square(v.y)) var result:Double = 0.0 - v.x /= vmag; - v.y /= vmag; + v.x /= vmag + v.y /= vmag let radians = Double(atan2(v.y,v.x)) result = RadiansToDegrees(radians) - return (result >= 0 ? result : result + 360.0); + return (result >= 0 ? result : result + 360.0) } } diff --git a/TB_CustomControlsSwift/BWCircularSliderView.swift b/TB_CustomControlsSwift/BWCircularSliderView.swift old mode 100644 new mode 100755 index ccfcf53..6a2876e --- a/TB_CustomControlsSwift/BWCircularSliderView.swift +++ b/TB_CustomControlsSwift/BWCircularSliderView.swift @@ -10,8 +10,8 @@ import UIKit @IBDesignable class BWCircularSliderView: UIView { - @IBInspectable var startColor:UIColor = UIColor.redColor() - @IBInspectable var endColor:UIColor = UIColor.blueColor() + @IBInspectable var startColor:UIColor = UIColor.red + @IBInspectable var endColor:UIColor = UIColor.blue #if TARGET_INTERFACE_BUILDER override func willMoveToSuperview(newSuperview: UIView?) { @@ -30,7 +30,7 @@ import UIKit let slider:BWCircularSlider = BWCircularSlider(startColor:self.startColor, endColor:self.endColor, frame: self.bounds) // Attach an Action and a Target to the slider - slider.addTarget(self, action: "valueChanged:", forControlEvents: UIControlEvents.ValueChanged) + slider.addTarget(self, action: #selector(BWCircularSliderView.valueChanged(_:)), for: UIControlEvents.valueChanged) // Add the slider as subview of this view self.addSubview(slider) @@ -38,8 +38,8 @@ import UIKit } #endif - func valueChanged(slider:BWCircularSlider){ + func valueChanged(_ slider:BWCircularSlider){ // Do something with the value... - println("Value changed \(slider.angle)") + print("Value changed \(slider.angle)") } } diff --git a/TB_CustomControlsSwift/Base.lproj/LaunchScreen.xib b/TB_CustomControlsSwift/Base.lproj/LaunchScreen.xib old mode 100644 new mode 100755 diff --git a/TB_CustomControlsSwift/Base.lproj/Main.storyboard b/TB_CustomControlsSwift/Base.lproj/Main.storyboard old mode 100644 new mode 100755 diff --git a/TB_CustomControlsSwift/Images.xcassets/AppIcon.appiconset/Contents.json b/TB_CustomControlsSwift/Images.xcassets/AppIcon.appiconset/Contents.json old mode 100644 new mode 100755 diff --git a/TB_CustomControlsSwift/Images.xcassets/AppIcon.appiconset/icon.png b/TB_CustomControlsSwift/Images.xcassets/AppIcon.appiconset/icon.png old mode 100644 new mode 100755 diff --git a/TB_CustomControlsSwift/Info.plist b/TB_CustomControlsSwift/Info.plist old mode 100644 new mode 100755 diff --git a/TB_CustomControlsSwift/ViewController.swift b/TB_CustomControlsSwift/ViewController.swift old mode 100644 new mode 100755 diff --git a/TB_CustomControlsSwiftTests/Info.plist b/TB_CustomControlsSwiftTests/Info.plist old mode 100644 new mode 100755 diff --git a/TB_CustomControlsSwiftTests/TB_CustomControlsSwiftTests.swift b/TB_CustomControlsSwiftTests/TB_CustomControlsSwiftTests.swift old mode 100644 new mode 100755