diff --git a/README.md b/README.md index 0ee8288..40ddd64 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ var color = UIColor(hex:"#A8DBA8") ``` The MIT License (MIT) -Copyright (c) 2015 Robin Oster (http://prine.ch) +Copyright (c) 2016 Robin Oster (http://prine.ch) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/ROStorageBar.podspec b/ROStorageBar.podspec index 28d657a..8743ad6 100644 --- a/ROStorageBar.podspec +++ b/ROStorageBar.podspec @@ -7,30 +7,15 @@ # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html # -Pod::Spec.new do |s| -s.name = "ROStorageBar" -s.version = "2.0.0" -s.summary = "Dynamic Storage Bar (a là iTunes Usage Bar) written in Swift" -s.description = <<-DESC -ROStorageBar is a library which provides an easy way to create an UIView which looks -similar like the iTunes Usage Bar. -DESC -s.homepage = "https://github.com/prine/ROStorageBar" -s.screenshots = "https://camo.githubusercontent.com/54ac217836c172791733d1464e805a7401db3dea/687474703a2f2f7072696e652e63682f2f524f53746f726167654261722e706e67", "https://camo.githubusercontent.com/62c5d8ec8583b876d890236c4c6784e1ef54422b/687474703a2f2f7072696e652e63682f2f524f53746f726167654261725f63617074696f6e2e706e67" -s.license = 'MIT' -s.author = { "Robin Oster" => "robin.oster@rascor.com" } -s.source = { :git => "https://github.com/prine/ROStorageBar.git", :tag => s.version.to_s } -s.social_media_url = 'https://twitter.com/prinedev' - -s.platform = :ios, '8.0' -s.requires_arc = true - -s.source_files = 'Source/**/*' -s.resource_bundles = { -'ROStorageBar' => ['Pod/Assets/*.png'] -} - -# s.public_header_files = 'Pod/Classes/**/*.h' -# s.frameworks = 'UIKit', 'MapKit' -# s.dependency 'AFNetworking', '~> 2.3' +Pod::Spec.new do |spec| + spec.name = 'ROStorageBar' + spec.version = '2.1.0' + spec.license = { :type => 'MIT' } + spec.homepage = 'https://github.com/prine/ROStorageBar' + spec.authors = { 'Robin Oster' => 'robin.oster@rascor.com' } + spec.summary = 'Dynamic Storage Bar (a là iTunes Usage Bar) written in Swift' + spec.source = { :git => 'https://github.com/prine/ROStorageBar.git', :tag => '2.1.0' } + spec.source_files = 'Source/**/*' + spec.framework = 'SystemConfiguration' + spec.ios.deployment_target = '9.3' end diff --git a/ROStorageBar.xcodeproj/project.pbxproj b/ROStorageBar.xcodeproj/project.pbxproj index 38dfd10..11d8dde 100644 --- a/ROStorageBar.xcodeproj/project.pbxproj +++ b/ROStorageBar.xcodeproj/project.pbxproj @@ -174,9 +174,12 @@ TargetAttributes = { CB0D1A941A812C3500FC80A8 = { CreatedOnToolsVersion = 6.1.1; + DevelopmentTeam = 39J9X3JBYC; + LastSwiftMigration = 0800; }; CB0D1AA91A812C3500FC80A8 = { CreatedOnToolsVersion = 6.1.1; + LastSwiftMigration = 0800; TestTargetID = CB0D1A941A812C3500FC80A8; }; }; @@ -355,10 +358,12 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = 39J9X3JBYC; INFOPLIST_FILE = ROStorageBar/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "ch.prine.ios.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -366,10 +371,12 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = 39J9X3JBYC; INFOPLIST_FILE = ROStorageBar/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "ch.prine.ios.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -377,10 +384,7 @@ isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", @@ -389,6 +393,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "ch.prine.ios.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ROStorageBar.app/ROStorageBar"; }; name = Debug; @@ -397,14 +402,12 @@ isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", - "$(inherited)", - ); + FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = ROStorageBarTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "ch.prine.ios.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ROStorageBar.app/ROStorageBar"; }; name = Release; diff --git a/ROStorageBar/AppDelegate.swift b/ROStorageBar/AppDelegate.swift index 17fe7dd..219b5e5 100644 --- a/ROStorageBar/AppDelegate.swift +++ b/ROStorageBar/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/ROStorageBar/Base.lproj/Main.storyboard b/ROStorageBar/Base.lproj/Main.storyboard index 575a699..5bddf03 100644 --- a/ROStorageBar/Base.lproj/Main.storyboard +++ b/ROStorageBar/Base.lproj/Main.storyboard @@ -1,7 +1,8 @@ - + - + + @@ -16,11 +17,13 @@ - + + + diff --git a/ROStorageBar/Info.plist b/ROStorageBar/Info.plist index 32bdcaa..a4a90bb 100644 --- a/ROStorageBar/Info.plist +++ b/ROStorageBar/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 2.0.0 + 2.1.0 CFBundleSignature ???? CFBundleVersion - 15265 + 16264 LSRequiresIPhoneOS UILaunchStoryboardName diff --git a/ROStorageBar/ViewController.swift b/ROStorageBar/ViewController.swift index 8d9b023..b013c6c 100644 --- a/ROStorageBar/ViewController.swift +++ b/ROStorageBar/ViewController.swift @@ -15,13 +15,13 @@ class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - storageBar.add(0.2, title: "Apps", color: UIColor.blackColor()) - storageBar.add(0.15, title: "Documents", color: UIColor.orangeColor()) - storageBar.add(0.21, title: "Photos", color: UIColor.purpleColor()) - storageBar.add(0.3, title: "Movies", color: UIColor.redColor()) + storageBar.add(0.2, title: "Apps", color: UIColor.black) + storageBar.add(0.15, title: "Documents", color: UIColor.orange) + storageBar.add(0.21, title: "Photos", color: UIColor.purple) + storageBar.add(0.3, title: "Movies", color: UIColor.red) // Or if you want to use directly the struct to add an item - storageBar.addStorageBarValue(ROStorageBarValue(value: 0.6, title: "Backups", color: UIColor.greenColor())) + storageBar.addStorageBarValue(ROStorageBarValue(value: 0.6, title: "Backups", color: UIColor.green)) storageBar.unit = "GB" storageBar.displayTitle = false @@ -30,14 +30,14 @@ class ViewController: UIViewController { storageBar.titleFontSize = 10.0 storageBar.valueFontSize = 10.0 - let numberFormatter = NSNumberFormatter() + let numberFormatter = NumberFormatter() numberFormatter.maximumFractionDigits = 2 numberFormatter.minimumIntegerDigits = 1 storageBar.numberFormatter = numberFormatter } - override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) { + override func didRotate(from fromInterfaceOrientation: UIInterfaceOrientation) { // Force the redraw. Otherwise the string is not correctly displayed storageBar.setNeedsDisplay() } diff --git a/ROStorageBarTests/ROStorageBarTests.swift b/ROStorageBarTests/ROStorageBarTests.swift index 451a96c..6a94c86 100644 --- a/ROStorageBarTests/ROStorageBarTests.swift +++ b/ROStorageBarTests/ROStorageBarTests.swift @@ -28,7 +28,7 @@ class ROStorageBarTests: XCTestCase { func testPerformanceExample() { // This is an example of a performance test case. - self.measureBlock() { + self.measure() { // Put the code you want to measure the time of here. } } diff --git a/Source/ROStorageBar.swift b/Source/ROStorageBar.swift index 3f6ecf1..a84546f 100644 --- a/Source/ROStorageBar.swift +++ b/Source/ROStorageBar.swift @@ -24,6 +24,17 @@ // import UIKit +fileprivate func < (lhs: T?, rhs: T?) -> Bool { + switch (lhs, rhs) { + case let (l?, r?): + return l < r + case (nil, _?): + return true + default: + return false + } +} + public struct ROStorageBarValue { public var value:Float @@ -37,42 +48,42 @@ public struct ROStorageBarValue { } } -public class ROStorageBar : UIView { +open class ROStorageBar : UIView { - private var storageBarValues = [ROStorageBarValue]() - private var totalSum:Float = 0.0 - private var height:CGFloat! + fileprivate var storageBarValues = [ROStorageBarValue]() + fileprivate var totalSum:Float = 0.0 + fileprivate var height:CGFloat! - public var borderWidth:Float = 1.0 - public var borderColor:UIColor = UIColor.darkGrayColor() - public var titleFontSize = 10.0 - public var valueFontSize = 10.0 - public var displayTitle:Bool = true - public var displayValue:Bool = true - public var displayCaption:Bool = false - public var numberFormatter:NSNumberFormatter - public var unit:String? + open var borderWidth:Float = 1.0 + open var borderColor:UIColor = UIColor.darkGray + open var titleFontSize = 10.0 + open var valueFontSize = 10.0 + open var displayTitle:Bool = true + open var displayValue:Bool = true + open var displayCaption:Bool = false + open var numberFormatter:NumberFormatter + open var unit:String? public init() { // Initilaize the default number formatter - numberFormatter = NSNumberFormatter() + numberFormatter = NumberFormatter() numberFormatter.minimumIntegerDigits = 1 numberFormatter.maximumFractionDigits = 1 // TODO: Check if this is a correct solution - super.init(frame: CGRectZero) + super.init(frame: CGRect.zero) } required public init?(coder aDecoder: NSCoder) { // Initilaize the default number formatter - numberFormatter = NSNumberFormatter() + numberFormatter = NumberFormatter() numberFormatter.minimumIntegerDigits = 1 numberFormatter.maximumFractionDigits = 1 super.init(coder:aDecoder) } - override public func drawRect(rect: CGRect) { + override open func draw(_ rect: CGRect) { let context = UIGraphicsGetCurrentContext() // Depending if the captions should be drawn or not set a different height @@ -85,24 +96,24 @@ public class ROStorageBar : UIView { } } - func drawStorageRects(context:CGContext) { + func drawStorageRects(_ context:CGContext) { - CGContextSetLineWidth(context, CGFloat(borderWidth)) + context.setLineWidth(CGFloat(borderWidth)) var currentX:Float = borderWidth let scale = (Float(self.frame.width) - 2 * borderWidth) / totalSum for storageBarValue in storageBarValues { - let color = storageBarValue.color.CGColor + let color = storageBarValue.color.cgColor let height:CGFloat = self.height - 2 * CGFloat(borderWidth) - let rectangle = CGRectMake(CGFloat(currentX), CGFloat(borderWidth), CGFloat(storageBarValue.value * scale),height) + let rectangle = CGRect(x: CGFloat(currentX), y: CGFloat(borderWidth), width: CGFloat(storageBarValue.value * scale),height: height) - CGContextSetStrokeColorWithColor(context, borderColor.CGColor) - CGContextAddRect(context, rectangle) - CGContextStrokePath(context) - CGContextSetFillColorWithColor(context, color) - CGContextFillRect(context, rectangle) + context.setStrokeColor(borderColor.cgColor) + context.addRect(rectangle) + context.strokePath() + context.setFillColor(color) + context.fill(rectangle) currentX += (storageBarValue.value * scale) @@ -110,14 +121,14 @@ public class ROStorageBar : UIView { } } - func drawString(storageBarValue:ROStorageBarValue, rect:CGRect) { + func drawString(_ storageBarValue:ROStorageBarValue, rect:CGRect) { let fontTitle = UIFont(name: "Helvetica Bold", size: CGFloat(self.titleFontSize)) let fontValue = UIFont(name: "Helvetica Light", size: CGFloat(self.valueFontSize)) - let textStyle = NSMutableParagraphStyle.defaultParagraphStyle().mutableCopy() as! NSMutableParagraphStyle - textStyle.alignment = NSTextAlignment.Center - let textColor = UIColor.blackColor() + let textStyle = NSMutableParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle + textStyle.alignment = NSTextAlignment.center + let textColor = UIColor.black var amountOfLineBreaks:Int? @@ -130,7 +141,7 @@ public class ROStorageBar : UIView { ] let titleStringToDraw:NSString = NSString(string: storageBarValue.title) - let positionedTitleRect = CGRectMake(rect.origin.x, rect.origin.y + (self.height/2 - CGFloat(titleFontSize)), rect.width, rect.height) + let positionedTitleRect = CGRect(x: rect.origin.x, y: rect.origin.y + (self.height/2 - CGFloat(titleFontSize)), width: rect.width, height: rect.height) let titleWidth = storageBarValue.title.characters.count * (Int(titleFontSize/2)+1) @@ -138,7 +149,7 @@ public class ROStorageBar : UIView { // Only display the title if there are less than 4 line breaks if amountOfLineBreaks < 4 { - titleStringToDraw.drawInRect(positionedTitleRect, withAttributes: textFontAttributes) + titleStringToDraw.draw(in: positionedTitleRect, withAttributes: textFontAttributes) } } } @@ -160,17 +171,17 @@ public class ROStorageBar : UIView { // Display the unit if its given let unitOfValue = self.unit ?? "" - let valueStringToDraw:NSString = NSString(string: "\(numberFormatter.stringFromNumber(NSNumber(float:storageBarValue.value))!) \(unitOfValue)") - let positionedValueRect = CGRectMake(rect.origin.x, rect.origin.y + calculatedOffsetY, rect.width, rect.height) + let valueStringToDraw:NSString = NSString(string: "\(numberFormatter.string(from: NSNumber(value: storageBarValue.value as Float))!) \(unitOfValue)") + let positionedValueRect = CGRect(x: rect.origin.x, y: rect.origin.y + calculatedOffsetY, width: rect.width, height: rect.height) if lineBreaks < 4 { - valueStringToDraw.drawInRect(positionedValueRect, withAttributes: textFontAttributes) + valueStringToDraw.draw(in: positionedValueRect, withAttributes: textFontAttributes) } } } } - func drawCaption(context:CGContext) { + func drawCaption(_ context:CGContext) { let offsetToBar:CGFloat = 10.0 let offsetToRectangle:CGFloat = 5.0 @@ -187,16 +198,16 @@ public class ROStorageBar : UIView { let fontTitle = UIFont(name: "Helvetica Bold", size: CGFloat(self.titleFontSize)) let fontValue = UIFont(name: "Helvetica Light", size: CGFloat(self.valueFontSize)) - let textStyle = NSMutableParagraphStyle.defaultParagraphStyle().mutableCopy() as! NSMutableParagraphStyle - textStyle.alignment = NSTextAlignment.Left - let textColor = UIColor.blackColor() + let textStyle = NSMutableParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle + textStyle.alignment = NSTextAlignment.left + let textColor = UIColor.black for storageBarValue in storageBarValues { - let rectangle = CGRectMake(posX, posY, sizeRect, sizeRect) + let rectangle = CGRect(x: posX, y: posY, width: sizeRect, height: sizeRect) - CGContextAddRect(context, rectangle) - CGContextSetFillColorWithColor(context, storageBarValue.color.CGColor) - CGContextFillRect(context, rectangle) + context.addRect(rectangle) + context.setFillColor(storageBarValue.color.cgColor) + context.fill(rectangle) // Title drawing if let actualFont = fontTitle { @@ -206,9 +217,9 @@ public class ROStorageBar : UIView { NSParagraphStyleAttributeName: textStyle ] - let titleRect = CGRectMake(posX + sizeRect + offsetToRectangle, posY, widthText, heightText) + let titleRect = CGRect(x: posX + sizeRect + offsetToRectangle, y: posY, width: widthText, height: heightText) let titleStringToDraw:NSString = NSString(string: storageBarValue.title) - titleStringToDraw.drawInRect(titleRect, withAttributes: textFontAttributes) + titleStringToDraw.draw(in: titleRect, withAttributes: textFontAttributes) } // Value drawing @@ -219,31 +230,31 @@ public class ROStorageBar : UIView { NSParagraphStyleAttributeName: textStyle ] - let valueRect = CGRectMake(posX + sizeRect + offsetToRectangle, posY + offsetToTitle, widthText, heightText) + let valueRect = CGRect(x: posX + sizeRect + offsetToRectangle, y: posY + offsetToTitle, width: widthText, height: heightText) let unitOfValue = self.unit ?? "" - let valueStringToDraw:NSString = NSString(string: "\(numberFormatter.stringFromNumber(NSNumber(float:storageBarValue.value))!) \(unitOfValue)") + let valueStringToDraw:NSString = NSString(string: "\(numberFormatter.string(from: NSNumber(value: storageBarValue.value as Float))!) \(unitOfValue)") - valueStringToDraw.drawInRect(valueRect, withAttributes: textFontAttributes) + valueStringToDraw.draw(in: valueRect, withAttributes: textFontAttributes) } posX += offsetWidth } } - public func add(value:Float, title:String, color:UIColor) { + open func add(_ value:Float, title:String, color:UIColor) { storageBarValues.append(ROStorageBarValue(value: value, title: title, color: color)) self.totalSum += value self.setNeedsDisplay() } - public func addStorageBarValue(storageBarValue:ROStorageBarValue) { + open func addStorageBarValue(_ storageBarValue:ROStorageBarValue) { storageBarValues.append(storageBarValue) self.totalSum += storageBarValue.value self.setNeedsDisplay() } - public func emptyStorageBar() { - self.storageBarValues.removeAll(keepCapacity: false) + open func emptyStorageBar() { + self.storageBarValues.removeAll(keepingCapacity: false) totalSum = 0 } -} \ No newline at end of file +}