From 3caa8b39d7cf10ccf305d52442083f8c13915544 Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Wed, 7 Sep 2016 12:46:21 +0300 Subject: [PATCH 01/14] add some useful extensions to UIImage --- LeadKit/LeadKit.xcodeproj/project.pbxproj | 12 +++++++ .../AlamofireRequest+Extensions.swift | 2 +- .../NSString/NSString+SizeCalculation.swift | 6 ++-- .../UIImage/UIImage+CapInsetsUtils.swift | 23 ++---------- .../Extensions/UIImage/UIImage+Creation.swift | 36 +++++++++++++++++++ .../UIImage/UIImage+RenderTemplate.swift | 12 +++---- .../Extensions/UIImage/UIImage+Resize.swift | 31 ++++++++++++++++ .../UIImage/UIImage+Transformations.swift | 35 ++++++++++++++++++ 8 files changed, 124 insertions(+), 33 deletions(-) create mode 100644 LeadKit/LeadKit/Extensions/UIImage/UIImage+Creation.swift create mode 100644 LeadKit/LeadKit/Extensions/UIImage/UIImage+Resize.swift create mode 100644 LeadKit/LeadKit/Extensions/UIImage/UIImage+Transformations.swift diff --git a/LeadKit/LeadKit.xcodeproj/project.pbxproj b/LeadKit/LeadKit.xcodeproj/project.pbxproj index 41eef9e3..e8dc0fd8 100644 --- a/LeadKit/LeadKit.xcodeproj/project.pbxproj +++ b/LeadKit/LeadKit.xcodeproj/project.pbxproj @@ -31,6 +31,9 @@ 78B0FC7D1C6B2BE200358B64 /* LogFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78B0FC7C1C6B2BE200358B64 /* LogFormatter.swift */; }; 78B0FC7F1C6B2C4D00358B64 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78B0FC7E1C6B2C4D00358B64 /* Log.swift */; }; 78B0FC811C6B2CD500358B64 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78B0FC801C6B2CD500358B64 /* App.swift */; }; + 78C36F771D80117D00E7EBEA /* UIImage+Transformations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C36F761D80117D00E7EBEA /* UIImage+Transformations.swift */; }; + 78C36F791D8011FA00E7EBEA /* UIImage+Resize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C36F781D8011FA00E7EBEA /* UIImage+Resize.swift */; }; + 78C36F7B1D8015ED00E7EBEA /* UIImage+Creation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C36F7A1D8015ED00E7EBEA /* UIImage+Creation.swift */; }; 78CFEE2E1C5C456B00F50370 /* LeadKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 78CFEE2D1C5C456B00F50370 /* LeadKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 78CFEE351C5C456B00F50370 /* LeadKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 78CFEE2A1C5C456B00F50370 /* LeadKit.framework */; }; 78CFEE3A1C5C456B00F50370 /* LeadKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78CFEE391C5C456B00F50370 /* LeadKitTests.swift */; }; @@ -83,6 +86,9 @@ 78B0FC7C1C6B2BE200358B64 /* LogFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LogFormatter.swift; sourceTree = ""; }; 78B0FC7E1C6B2C4D00358B64 /* Log.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = ""; }; 78B0FC801C6B2CD500358B64 /* App.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = ""; }; + 78C36F761D80117D00E7EBEA /* UIImage+Transformations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Transformations.swift"; sourceTree = ""; }; + 78C36F781D8011FA00E7EBEA /* UIImage+Resize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Resize.swift"; sourceTree = ""; }; + 78C36F7A1D8015ED00E7EBEA /* UIImage+Creation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Creation.swift"; sourceTree = ""; }; 78CFEE2A1C5C456B00F50370 /* LeadKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LeadKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 78CFEE2D1C5C456B00F50370 /* LeadKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LeadKit.h; sourceTree = ""; }; 78CFEE2F1C5C456B00F50370 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -324,6 +330,9 @@ children = ( 786A17A01CB8D71D007F9661 /* UIImage+CapInsetsUtils.swift */, 7824CA511CFEE6B700D7B132 /* UIImage+RenderTemplate.swift */, + 78C36F761D80117D00E7EBEA /* UIImage+Transformations.swift */, + 78C36F781D8011FA00E7EBEA /* UIImage+Resize.swift */, + 78C36F7A1D8015ED00E7EBEA /* UIImage+Creation.swift */, ); path = UIImage; sourceTree = ""; @@ -512,6 +521,7 @@ 786D78EC1D53C46E006B2CEA /* AlamofireManager+Extensions.swift in Sources */, 78E59B1B1C77470A00C6BFE9 /* ViewsGenerator.swift in Sources */, 78B0FC811C6B2CD500358B64 /* App.swift in Sources */, + 78C36F771D80117D00E7EBEA /* UIImage+Transformations.swift in Sources */, 786D78EA1D53C43E006B2CEA /* ApiError.swift in Sources */, 787A071A1D085750009EC97F /* CellsControllerProtocol.swift in Sources */, 78CFEE551C5C45E500F50370 /* NibNameProtocol.swift in Sources */, @@ -519,11 +529,13 @@ 786D78E81D53C378006B2CEA /* AlamofireRequest+Extensions.swift in Sources */, 78E59B191C773EE600C6BFE9 /* ObjectsGenerator.swift in Sources */, 78CFEE5B1C5C45E500F50370 /* ViewModelProtocol.swift in Sources */, + 78C36F7B1D8015ED00E7EBEA /* UIImage+Creation.swift in Sources */, 7824CA521CFEE6B700D7B132 /* UIImage+RenderTemplate.swift in Sources */, 78CFEE5A1C5C45E500F50370 /* ViewHeightProtocol.swift in Sources */, 787682FA1CAD40C300532AB3 /* StaticEstimatedViewHeightProtocol.swift in Sources */, 78A74EA91C6B373700FE9724 /* UIView+DefaultNibName.swift in Sources */, 786A17A11CB8D71D007F9661 /* UIImage+CapInsetsUtils.swift in Sources */, + 78C36F791D8011FA00E7EBEA /* UIImage+Resize.swift in Sources */, 78CFEE581C5C45E500F50370 /* StaticViewHeightProtocol.swift in Sources */, 787783631CA03CA0001CDC9B /* NSIndexPath+ImmutableIndexPath.swift in Sources */, 78CFEE591C5C45E500F50370 /* StoryboardIdentifierProtocol.swift in Sources */, diff --git a/LeadKit/LeadKit/Extensions/Alamofire/AlamofireRequest+Extensions.swift b/LeadKit/LeadKit/Extensions/Alamofire/AlamofireRequest+Extensions.swift index 5dcc08d6..7ab3ec86 100644 --- a/LeadKit/LeadKit/Extensions/Alamofire/AlamofireRequest+Extensions.swift +++ b/LeadKit/LeadKit/Extensions/Alamofire/AlamofireRequest+Extensions.swift @@ -41,5 +41,5 @@ public extension Alamofire.Request { return rx_responseResult(responseSerializer: mapperSerializer) } - + } diff --git a/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift b/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift index 7321d879..cb6f368b 100644 --- a/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift +++ b/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift @@ -34,7 +34,7 @@ extension NSString { */ public func heightWith(width: CGFloat, attributes: [String: AnyObject]?) -> CGFloat { return self.boundingRectWithSize(CGSize(width: width, height: CGFloat.max), - options: .UsesLineFragmentOrigin, + options: [.UsesLineFragmentOrigin, .UsesFontLeading], attributes: attributes, context: nil).size.height } @@ -52,9 +52,7 @@ extension NSString { preconditionFailure("Value for NSFontAttributeName should be defined in attributes") } - let paragraphStyle = attributes[NSParagraphStyleAttributeName] as? NSParagraphStyle - - let lineHeight = font.lineHeight * (paragraphStyle?.lineHeightMultiple ?? 1.0) + let lineHeight = font.lineHeight let lineHeightRounded = roundDouble(Double(lineHeight), withPersicion: 2) diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+CapInsetsUtils.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+CapInsetsUtils.swift index 4576c30f..80d4d84e 100644 --- a/LeadKit/LeadKit/Extensions/UIImage/UIImage+CapInsetsUtils.swift +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+CapInsetsUtils.swift @@ -8,26 +8,7 @@ import UIKit -extension UIImage { - - /** - method which render current UIImage for specific size and return new UIImage - - - parameter size: size of new rendered image - - - returns: new rendered UIImage - */ - public func renderWithSize(size: CGSize) -> UIImage { - UIGraphicsBeginImageContextWithOptions(size, false, 0.0) - - self.drawInRect(CGRect(origin: CGPoint.zero, size: size)) - - let resizedImage = UIGraphicsGetImageFromCurrentImageContext() - - UIGraphicsEndImageContext() - - return resizedImage - } +public extension UIImage { /** this method tries to find requested image with specific parameters in cache, and if doesn't exists - create it @@ -81,7 +62,7 @@ extension UIImage { right: assetsInsetsForScale.right / scale) - return self.fetchOrCreateImageWithName(name, size: size, capInsets: capInsetsForScale, cache: cache) + return fetchOrCreateImageWithName(name, size: size, capInsets: capInsetsForScale, cache: cache) } return nil diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Creation.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Creation.swift new file mode 100644 index 00000000..7ca919a9 --- /dev/null +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Creation.swift @@ -0,0 +1,36 @@ +// +// UIImage+Creation.swift +// LeadKit +// +// Created by Ivan Smolin on 07/09/16. +// Copyright © 2016 Touch Instinct. All rights reserved. +// + +import UIKit + +public extension UIImage { + + /** + method which creates new UIImage instance filled by given color + + - parameter color: color to fill + - parameter size: size of new image + - parameter opaque: a flag indicating whether the bitmap is opaque (default: False) + - parameter scale: screen scale (default: 0 (pick a device scale)) + + - returns: new instanse of UIImage with given size and color + */ + public static func imageWith(color: UIColor, size: CGSize, opaque: Bool = false, scale: CGFloat = 0) -> UIImage { + UIGraphicsBeginImageContextWithOptions(size, opaque, scale) + + defer { UIGraphicsEndImageContext() } + + let context = UIGraphicsGetCurrentContext() + + CGContextSetFillColorWithColor(context, color.CGColor) + CGContextFillRect(context, CGRect(origin: CGPoint.zero, size: size)) + + return UIGraphicsGetImageFromCurrentImageContext() + } + +} diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+RenderTemplate.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+RenderTemplate.swift index 21cbf669..cd5a85c5 100644 --- a/LeadKit/LeadKit/Extensions/UIImage/UIImage+RenderTemplate.swift +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+RenderTemplate.swift @@ -14,12 +14,14 @@ public extension UIImage { method which render current template UIImage into new image using given color - parameter color: color which used to fill template image - - parameter opaque: a flag indicating whether the bitmap is opaque + - parameter opaque: a flag indicating whether the bitmap is opaque (default: False) - returns: new UIImage rendered with given color */ public func renderTemplateWithColor(color: UIColor, opaque: Bool = false) -> UIImage { - UIGraphicsBeginImageContextWithOptions(size, opaque, 0.0) + UIGraphicsBeginImageContextWithOptions(size, opaque, scale) + + defer { UIGraphicsEndImageContext() } let ctx = UIGraphicsGetCurrentContext() @@ -38,11 +40,7 @@ public extension UIImage { CGContextSetBlendMode(ctx, .Multiply) CGContextDrawImage(ctx, imageRect, CGImage) - let newImage = UIGraphicsGetImageFromCurrentImageContext() - - UIGraphicsEndImageContext() - - return newImage + return UIGraphicsGetImageFromCurrentImageContext() } } diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Resize.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Resize.swift new file mode 100644 index 00000000..4acae7da --- /dev/null +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Resize.swift @@ -0,0 +1,31 @@ +// +// UIImage+Resize.swift +// LeadKit +// +// Created by Ivan Smolin on 07/09/16. +// Copyright © 2016 Touch Instinct. All rights reserved. +// + +import UIKit + +public extension UIImage { + + /** + method which render current UIImage for specific size and return new UIImage + + - parameter size: size of new image + - parameter opaque: a flag indicating whether the bitmap is opaque (default: False) + + - returns: new instance of UIImage rendered with given size + */ + public func renderWithSize(size: CGSize, opaque: Bool = false) -> UIImage { + UIGraphicsBeginImageContextWithOptions(size, opaque, scale) + + defer { UIGraphicsEndImageContext() } + + drawInRect(CGRect(origin: CGPoint.zero, size: size)) + + return UIGraphicsGetImageFromCurrentImageContext() + } + +} diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Transformations.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Transformations.swift new file mode 100644 index 00000000..bad69574 --- /dev/null +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Transformations.swift @@ -0,0 +1,35 @@ +// +// UIImage+Transformations.swift +// LeadKit +// +// Created by Ivan Smolin on 07/09/16. +// Copyright © 2016 Touch Instinct. All rights reserved. +// + +import UIKit + +public extension UIImage { + + /** + method which creates new UIImage from current with rounded corners + + - parameter radius: corners radius + - parameter opaque: a flag indicating whether the bitmap is opaque (default: False) + + - returns: new UIImage instance rendered with given radius + */ + public func roundedImage(withRadius radius: CGFloat, opaque: Bool = false) -> UIImage { + UIGraphicsBeginImageContextWithOptions(size, opaque, scale) + + defer { UIGraphicsEndImageContext() } + + let imageRect = CGRect(origin: CGPoint.zero, size: size) + + UIBezierPath(roundedRect: imageRect, cornerRadius: radius).addClip() + + drawInRect(imageRect) + + return UIGraphicsGetImageFromCurrentImageContext() + } + +} From 6101532165b709d146803fc856d5ba08d386539a Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Wed, 7 Sep 2016 13:11:06 +0300 Subject: [PATCH 02/14] refactoring --- LeadKit/LeadKit.xcodeproj/project.pbxproj | 12 ++++ .../Extensions/Double/Double+Rounding.swift | 27 +++++++ .../NSString/NSString+SizeCalculation.swift | 70 ++++++++----------- 3 files changed, 67 insertions(+), 42 deletions(-) create mode 100644 LeadKit/LeadKit/Extensions/Double/Double+Rounding.swift diff --git a/LeadKit/LeadKit.xcodeproj/project.pbxproj b/LeadKit/LeadKit.xcodeproj/project.pbxproj index e8dc0fd8..554a938c 100644 --- a/LeadKit/LeadKit.xcodeproj/project.pbxproj +++ b/LeadKit/LeadKit.xcodeproj/project.pbxproj @@ -34,6 +34,7 @@ 78C36F771D80117D00E7EBEA /* UIImage+Transformations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C36F761D80117D00E7EBEA /* UIImage+Transformations.swift */; }; 78C36F791D8011FA00E7EBEA /* UIImage+Resize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C36F781D8011FA00E7EBEA /* UIImage+Resize.swift */; }; 78C36F7B1D8015ED00E7EBEA /* UIImage+Creation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C36F7A1D8015ED00E7EBEA /* UIImage+Creation.swift */; }; + 78C36F7E1D801E3E00E7EBEA /* Double+Rounding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C36F7D1D801E3E00E7EBEA /* Double+Rounding.swift */; }; 78CFEE2E1C5C456B00F50370 /* LeadKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 78CFEE2D1C5C456B00F50370 /* LeadKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 78CFEE351C5C456B00F50370 /* LeadKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 78CFEE2A1C5C456B00F50370 /* LeadKit.framework */; }; 78CFEE3A1C5C456B00F50370 /* LeadKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78CFEE391C5C456B00F50370 /* LeadKitTests.swift */; }; @@ -89,6 +90,7 @@ 78C36F761D80117D00E7EBEA /* UIImage+Transformations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Transformations.swift"; sourceTree = ""; }; 78C36F781D8011FA00E7EBEA /* UIImage+Resize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Resize.swift"; sourceTree = ""; }; 78C36F7A1D8015ED00E7EBEA /* UIImage+Creation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Creation.swift"; sourceTree = ""; }; + 78C36F7D1D801E3E00E7EBEA /* Double+Rounding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Double+Rounding.swift"; sourceTree = ""; }; 78CFEE2A1C5C456B00F50370 /* LeadKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LeadKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 78CFEE2D1C5C456B00F50370 /* LeadKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LeadKit.h; sourceTree = ""; }; 78CFEE2F1C5C456B00F50370 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -224,6 +226,14 @@ path = Logging; sourceTree = ""; }; + 78C36F7C1D801E2F00E7EBEA /* Double */ = { + isa = PBXGroup; + children = ( + 78C36F7D1D801E3E00E7EBEA /* Double+Rounding.swift */, + ); + path = Double; + sourceTree = ""; + }; 78CFEE201C5C456B00F50370 = { isa = PBXGroup; children = ( @@ -269,6 +279,7 @@ 78CFEE441C5C45E500F50370 /* Extensions */ = { isa = PBXGroup; children = ( + 78C36F7C1D801E2F00E7EBEA /* Double */, 787783651CA04D14001CDC9B /* NSString */, 787783611CA03C84001CDC9B /* NSIndexPath */, 78E59B2C1C786CD500C6BFE9 /* UIView */, @@ -524,6 +535,7 @@ 78C36F771D80117D00E7EBEA /* UIImage+Transformations.swift in Sources */, 786D78EA1D53C43E006B2CEA /* ApiError.swift in Sources */, 787A071A1D085750009EC97F /* CellsControllerProtocol.swift in Sources */, + 78C36F7E1D801E3E00E7EBEA /* Double+Rounding.swift in Sources */, 78CFEE551C5C45E500F50370 /* NibNameProtocol.swift in Sources */, 78CFEE561C5C45E500F50370 /* ReuseIdentifierProtocol.swift in Sources */, 786D78E81D53C378006B2CEA /* AlamofireRequest+Extensions.swift in Sources */, diff --git a/LeadKit/LeadKit/Extensions/Double/Double+Rounding.swift b/LeadKit/LeadKit/Extensions/Double/Double+Rounding.swift new file mode 100644 index 00000000..eff310e4 --- /dev/null +++ b/LeadKit/LeadKit/Extensions/Double/Double+Rounding.swift @@ -0,0 +1,27 @@ +// +// Double+Rounding.swift +// LeadKit +// +// Created by Ivan Smolin on 07/09/16. +// Copyright © 2016 Touch Instinct. All rights reserved. +// + +import Foundation + +public extension Double { + + /** + rounds double value 1.7800000004 to 1.78 + + - parameter val: value for rounding + - parameter persicion: important number of digits after comma + + - returns: rounded value + */ + public func roundValue(withPersicion persicion: UInt) -> Double { + let divider = pow(10.0, Double(persicion - 1)) + + return round(self * divider) / divider + } + +} diff --git a/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift b/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift index cb6f368b..b7275531 100644 --- a/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift +++ b/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift @@ -6,70 +6,56 @@ // Copyright © 2016 Touch Instinct. All rights reserved. // -import Foundation - -/** - rounds double value 1.7800000004 to 1.78 - - - parameter val: value for rounding - - parameter persicion: important number of digits after comma - - - returns: rounded value - */ -private func roundDouble(val: Double, withPersicion persicion: UInt) -> Double { - let divider = pow(10.0, Double(persicion - 1)) - - return round(val * divider) / divider -} +import UIKit extension NSString { - + /** method which calculates string height based on given width and character attributes - + - parameter width: maximum width of string - parameter attributes: dictionary with string character attributes - + - returns: string height */ public func heightWith(width: CGFloat, attributes: [String: AnyObject]?) -> CGFloat { return self.boundingRectWithSize(CGSize(width: width, height: CGFloat.max), - options: [.UsesLineFragmentOrigin, .UsesFontLeading], - attributes: attributes, - context: nil).size.height + options: [.UsesLineFragmentOrigin, .UsesFontLeading], + attributes: attributes, + context: nil).size.height } - + /** method which calculates required number of lines to fit string with given width and character attributes - + - parameter width: maximum width of string - parameter attributes: dictionary with string character attributes - + - returns: minimum number of lines */ public func numberOfLinesWith(width: CGFloat, attributes: [String: AnyObject]) -> UInt { guard let font = attributes[NSFontAttributeName] as? UIFont else { preconditionFailure("Value for NSFontAttributeName should be defined in attributes") } - + let lineHeight = font.lineHeight - - let lineHeightRounded = roundDouble(Double(lineHeight), withPersicion: 2) - + + let lineHeightRounded = Double(lineHeight).roundValue(withPersicion: 2) + let height = heightWith(width, attributes: attributes) - - let heightRounded = roundDouble(Double(height), withPersicion: 2) - + + let heightRounded = Double(height).roundValue(withPersicion: 2) + let numberOfLines = ceil(heightRounded / lineHeightRounded) - + return UInt(numberOfLines) } - + /** method which calculates string width based on given character attributes - + - parameter attriutes: dictionary with string character attributes - + - returns: string width */ public func widthWith(attriutes: [String: AnyObject]) -> CGFloat { @@ -86,13 +72,13 @@ extension NSString { - returns: text size */ public func sizeWith(maxWidth width: CGFloat = CGFloat.max, - maxHeight height: CGFloat = CGFloat.max, - attributes: [String: AnyObject]?) -> CGSize { + maxHeight height: CGFloat = CGFloat.max, + attributes: [String: AnyObject]?) -> CGSize { - return self.boundingRectWithSize(CGSize(width: width, height: height), - options: .UsesLineFragmentOrigin, - attributes: attributes, - context: nil).size + return boundingRectWithSize(CGSize(width: width, height: height), + options: .UsesLineFragmentOrigin, + attributes: attributes, + context: nil).size } - + } From 888f6c59b815f13cc1af50aef9b26802d603e302 Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Wed, 7 Sep 2016 13:57:45 +0300 Subject: [PATCH 03/14] add UIColor+Hex extension --- LeadKit/LeadKit.xcodeproj/project.pbxproj | 12 +++++ .../Extensions/UIColor/UIColor+Hex.swift | 47 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift diff --git a/LeadKit/LeadKit.xcodeproj/project.pbxproj b/LeadKit/LeadKit.xcodeproj/project.pbxproj index 554a938c..98f47eba 100644 --- a/LeadKit/LeadKit.xcodeproj/project.pbxproj +++ b/LeadKit/LeadKit.xcodeproj/project.pbxproj @@ -35,6 +35,7 @@ 78C36F791D8011FA00E7EBEA /* UIImage+Resize.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C36F781D8011FA00E7EBEA /* UIImage+Resize.swift */; }; 78C36F7B1D8015ED00E7EBEA /* UIImage+Creation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C36F7A1D8015ED00E7EBEA /* UIImage+Creation.swift */; }; 78C36F7E1D801E3E00E7EBEA /* Double+Rounding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C36F7D1D801E3E00E7EBEA /* Double+Rounding.swift */; }; + 78C36F811D8021DD00E7EBEA /* UIColor+Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78C36F801D8021DD00E7EBEA /* UIColor+Hex.swift */; }; 78CFEE2E1C5C456B00F50370 /* LeadKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 78CFEE2D1C5C456B00F50370 /* LeadKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 78CFEE351C5C456B00F50370 /* LeadKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 78CFEE2A1C5C456B00F50370 /* LeadKit.framework */; }; 78CFEE3A1C5C456B00F50370 /* LeadKitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78CFEE391C5C456B00F50370 /* LeadKitTests.swift */; }; @@ -91,6 +92,7 @@ 78C36F781D8011FA00E7EBEA /* UIImage+Resize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Resize.swift"; sourceTree = ""; }; 78C36F7A1D8015ED00E7EBEA /* UIImage+Creation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Creation.swift"; sourceTree = ""; }; 78C36F7D1D801E3E00E7EBEA /* Double+Rounding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Double+Rounding.swift"; sourceTree = ""; }; + 78C36F801D8021DD00E7EBEA /* UIColor+Hex.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Hex.swift"; sourceTree = ""; }; 78CFEE2A1C5C456B00F50370 /* LeadKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LeadKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 78CFEE2D1C5C456B00F50370 /* LeadKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LeadKit.h; sourceTree = ""; }; 78CFEE2F1C5C456B00F50370 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -234,6 +236,14 @@ path = Double; sourceTree = ""; }; + 78C36F7F1D8021D100E7EBEA /* UIColor */ = { + isa = PBXGroup; + children = ( + 78C36F801D8021DD00E7EBEA /* UIColor+Hex.swift */, + ); + path = UIColor; + sourceTree = ""; + }; 78CFEE201C5C456B00F50370 = { isa = PBXGroup; children = ( @@ -279,6 +289,7 @@ 78CFEE441C5C45E500F50370 /* Extensions */ = { isa = PBXGroup; children = ( + 78C36F7F1D8021D100E7EBEA /* UIColor */, 78C36F7C1D801E2F00E7EBEA /* Double */, 787783651CA04D14001CDC9B /* NSString */, 787783611CA03C84001CDC9B /* NSIndexPath */, @@ -539,6 +550,7 @@ 78CFEE551C5C45E500F50370 /* NibNameProtocol.swift in Sources */, 78CFEE561C5C45E500F50370 /* ReuseIdentifierProtocol.swift in Sources */, 786D78E81D53C378006B2CEA /* AlamofireRequest+Extensions.swift in Sources */, + 78C36F811D8021DD00E7EBEA /* UIColor+Hex.swift in Sources */, 78E59B191C773EE600C6BFE9 /* ObjectsGenerator.swift in Sources */, 78CFEE5B1C5C45E500F50370 /* ViewModelProtocol.swift in Sources */, 78C36F7B1D8015ED00E7EBEA /* UIImage+Creation.swift in Sources */, diff --git a/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift b/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift new file mode 100644 index 00000000..bc36b99c --- /dev/null +++ b/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift @@ -0,0 +1,47 @@ +// +// UIColor+Hex.swift +// LeadKit +// +// Created by Ivan Smolin on 07/09/16. +// Copyright © 2016 Touch Instinct. All rights reserved. +// + +import UIKit + +public extension UIColor { + + /** + convenience initializer which creates an instance with given hex color values + + - parameter hex: hex with red, green and blue values + - parameter alpha: alpha component + + - returns: new instance with given hex color + */ + public convenience init(hex: UInt32, alpha: CGFloat = 1) { + let red = CGFloat((hex & 0xFF0000) >> 16) / 0xFF + let green = CGFloat((hex & 0x00FF00) >> 8) / 0xFF + let blue = CGFloat((hex & 0x0000FF) >> 0) / 0xFF + + self.init(red: red, green: green, blue: blue, alpha: alpha) + } + + /** + convenience failable initializer which creates an instance with given hex color values if string has a correct format + + - parameter hexString: hex string with red green and blue values (can have `#` sign) + - parameter alpha: alpha component + + - returns: new instance with given hex color or nil if hexString is incorrect + */ + public convenience init?(hexString: String, alpha: CGFloat = 1) { + let hexStringWithoutHash = hexString.stringByReplacingOccurrencesOfString("#", withString: "", + options: .LiteralSearch, range: nil) + if let hex = UInt32(hexStringWithoutHash, radix: 16) { + self.init(hex: hex, alpha: alpha) + } else { + return nil + } + } + +} From aa0fdae43610dcf13d3ab8716cb0959eb1205022 Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Thu, 8 Sep 2016 16:44:48 +0300 Subject: [PATCH 04/14] some UIColor convenience initializers --- .../Extensions/UIColor/UIColor+Hex.swift | 68 ++++++++++++++++--- 1 file changed, 59 insertions(+), 9 deletions(-) diff --git a/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift b/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift index bc36b99c..3617a671 100644 --- a/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift +++ b/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift @@ -11,21 +11,71 @@ import UIKit public extension UIColor { /** - convenience initializer which creates an instance with given hex color values + The shorthand three-digit hexadecimal representation of color. + #RGB defines to the color #RRGGBB. - - parameter hex: hex with red, green and blue values - - parameter alpha: alpha component + - parameter hex3: Three-digit hexadecimal value. + - parameter alpha: 0.0 - 1.0. The default is 1.0. - - returns: new instance with given hex color + - returns: new instance with given three-digit hexadecimal value */ - public convenience init(hex: UInt32, alpha: CGFloat = 1) { - let red = CGFloat((hex & 0xFF0000) >> 16) / 0xFF - let green = CGFloat((hex & 0x00FF00) >> 8) / 0xFF - let blue = CGFloat((hex & 0x0000FF) >> 0) / 0xFF + public convenience init(hex3: UInt16, alpha: CGFloat = 1) { + let red = CGFloat((hex3 & 0xF00) >> 8) / 0xFF + let green = CGFloat((hex3 & 0x0F0) >> 4) / 0xFF + let blue = CGFloat((hex3 & 0x00F) >> 0) / 0xFF + self.init(red: red, green: green, blue: blue, alpha: alpha) + } + + /** + The shorthand four-digit hexadecimal representation of color with alpha. + #RGBA defines to the color #RRGGBBAA. + + - parameter hex4: Four-digit hexadecimal value. + + - returns: new instance with given four-digit hexadecimal value + */ + public convenience init(hex4: UInt16) { + let red = CGFloat((hex4 & 0xF000) >> 12) / 0xFF + let green = CGFloat((hex4 & 0x0F00) >> 8) / 0xFF + let blue = CGFloat((hex4 & 0x00F0) >> 4) / 0xFF + let alpha = CGFloat((hex4 & 0x000F) >> 0) / 0xFF self.init(red: red, green: green, blue: blue, alpha: alpha) } + /** + The six-digit hexadecimal representation of color of the form #RRGGBB. + + - parameter hex6: Six-digit hexadecimal value. + - parameter alpha: alpha: 0.0 - 1.0. The default is 1.0. + + - returns: new instance with given six-digit hexadecimal value + */ + public convenience init(hex6: UInt32, alpha: CGFloat = 1) { + let red = CGFloat((hex6 & 0xFF0000) >> 16) / 0xFF + let green = CGFloat((hex6 & 0x00FF00) >> 8) / 0xFF + let blue = CGFloat((hex6 & 0x0000FF) >> 0) / 0xFF + + self.init(red: red, green: green, blue: blue, alpha: alpha) + } + + /** + The six-digit hexadecimal representation of color with alpha of the form #RRGGBBAA. + + - parameter hex8: Eight-digit hexadecimal value. + + - returns: new instance with given eight-digit hexadecimal value + */ + public convenience init(hex8: UInt32) { + let red = CGFloat((hex8 & 0xFF000000) >> 24) / 0xFF + let green = CGFloat((hex8 & 0x00FF0000) >> 16) / 0xFF + let blue = CGFloat((hex8 & 0x0000FF00) >> 8) / 0xFF + let alpha = CGFloat((hex8 & 0x000000FF) >> 0) / 0xFF + + self.init(red: red, green: green, blue: blue, alpha: alpha) + } + + /** convenience failable initializer which creates an instance with given hex color values if string has a correct format @@ -38,7 +88,7 @@ public extension UIColor { let hexStringWithoutHash = hexString.stringByReplacingOccurrencesOfString("#", withString: "", options: .LiteralSearch, range: nil) if let hex = UInt32(hexStringWithoutHash, radix: 16) { - self.init(hex: hex, alpha: alpha) + self.init(hex6: hex, alpha: alpha) } else { return nil } From 1d0c9dac0170e44aa0028c752e17bb0a8d6d1316 Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Thu, 8 Sep 2016 16:45:14 +0300 Subject: [PATCH 05/14] update add macOS gitignore section --- .gitignore | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/.gitignore b/.gitignore index 39642d17..c3760bab 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,38 @@ +# ================ +# macOS.gitignore +# ================ + +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# ================ +# Swift.gitignore +# ================ + # Xcode # # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore From dd7a16571ab694cdd5065c37633b095807003973 Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Thu, 8 Sep 2016 16:46:09 +0300 Subject: [PATCH 06/14] some changes to api --- .../Alamofire/AlamofireManager+Extensions.swift | 6 +++++- .../Structures/Api/ApiRequestParameters.swift | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/LeadKit/LeadKit/Extensions/Alamofire/AlamofireManager+Extensions.swift b/LeadKit/LeadKit/Extensions/Alamofire/AlamofireManager+Extensions.swift index 73915b4b..ad8f110d 100644 --- a/LeadKit/LeadKit/Extensions/Alamofire/AlamofireManager+Extensions.swift +++ b/LeadKit/LeadKit/Extensions/Alamofire/AlamofireManager+Extensions.swift @@ -20,7 +20,11 @@ public extension Alamofire.Manager { - returns: Observable with request */ func apiRequest(apiParameters: ApiRequestParameters) -> Observable { - return rx_request(apiParameters.method, apiParameters.url, parameters: apiParameters.parameters) + return rx_request(apiParameters.method, + apiParameters.url, + parameters: apiParameters.parameters, + encoding: apiParameters.encoding, + headers: apiParameters.headers) } } diff --git a/LeadKit/LeadKit/Structures/Api/ApiRequestParameters.swift b/LeadKit/LeadKit/Structures/Api/ApiRequestParameters.swift index fa948481..6bb00997 100644 --- a/LeadKit/LeadKit/Structures/Api/ApiRequestParameters.swift +++ b/LeadKit/LeadKit/Structures/Api/ApiRequestParameters.swift @@ -18,5 +18,20 @@ public struct ApiRequestParameters { let method: Alamofire.Method let url: URLStringConvertible let parameters: [String: AnyObject]? + let encoding: ParameterEncoding + let headers: [String: String]? + + public init(method: Alamofire.Method, + url: URLStringConvertible, + parameters: [String: AnyObject]? = nil, + encoding: ParameterEncoding = .URL, + headers: [String: String]? = nil) { + + self.method = method + self.url = url + self.parameters = parameters + self.encoding = encoding + self.headers = headers + } } From 9ff20dc074455274c8466f62422f77313c9e9b03 Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Thu, 8 Sep 2016 23:57:06 +0300 Subject: [PATCH 07/14] uicolor+hex for any string format --- .../Extensions/UIColor/UIColor+Hex.swift | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift b/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift index 3617a671..9d31250d 100644 --- a/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift +++ b/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift @@ -80,18 +80,35 @@ public extension UIColor { convenience failable initializer which creates an instance with given hex color values if string has a correct format - parameter hexString: hex string with red green and blue values (can have `#` sign) - - parameter alpha: alpha component + - parameter alpha: alpha component used if not given in hexString - returns: new instance with given hex color or nil if hexString is incorrect */ public convenience init?(hexString: String, alpha: CGFloat = 1) { - let hexStringWithoutHash = hexString.stringByReplacingOccurrencesOfString("#", withString: "", - options: .LiteralSearch, range: nil) - if let hex = UInt32(hexStringWithoutHash, radix: 16) { - self.init(hex6: hex, alpha: alpha) - } else { + let hexStr = hexString.hasPrefix("#") ? hexString.substringFromIndex(hexString.startIndex.advancedBy(1)) : hexString + + switch hexStr.characters.count { + case 3: + if let hex = UInt16(hexStr, radix: 16) { + self.init(hex3: hex, alpha: alpha) + } + case 4: + if let hex = UInt16(hexStr, radix: 16) { + self.init(hex4: hex) + } + case 6: + if let hex = UInt32(hexStr, radix: 16) { + self.init(hex6: hex, alpha: alpha) + } + case 8: + if let hex = UInt32(hexStr, radix: 16) { + self.init(hex8: hex) + } + default: return nil } + + return nil } } From 6cea000af94f5264a601f4252e8710163c0b45bf Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Fri, 9 Sep 2016 10:13:46 +0300 Subject: [PATCH 08/14] refactor string size calculation --- .../NSString/NSString+SizeCalculation.swift | 86 +++++++------------ 1 file changed, 33 insertions(+), 53 deletions(-) diff --git a/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift b/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift index b7275531..2b64d3e9 100644 --- a/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift +++ b/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift @@ -8,77 +8,57 @@ import UIKit -extension NSString { +/** + * Struct for holding result of string size calculation + */ +public struct StringSizeCalculationResult { - /** - method which calculates string height based on given width and character attributes + public let size: CGSize + public let fontLineHeight: CGFloat? - - parameter width: maximum width of string - - parameter attributes: dictionary with string character attributes +} - - returns: string height - */ - public func heightWith(width: CGFloat, attributes: [String: AnyObject]?) -> CGFloat { - return self.boundingRectWithSize(CGSize(width: width, height: CGFloat.max), - options: [.UsesLineFragmentOrigin, .UsesFontLeading], - attributes: attributes, - context: nil).size.height - } +public extension StringSizeCalculationResult { - /** - method which calculates required number of lines to fit string with given width and character attributes + public var numberOfLines: UInt? { + if let lineHeight = fontLineHeight { + let lineHeightRounded = Double(lineHeight).roundValue(withPersicion: 2) - - parameter width: maximum width of string - - parameter attributes: dictionary with string character attributes + let heightRounded = Double(size.height).roundValue(withPersicion: 2) - - returns: minimum number of lines - */ - public func numberOfLinesWith(width: CGFloat, attributes: [String: AnyObject]) -> UInt { - guard let font = attributes[NSFontAttributeName] as? UIFont else { - preconditionFailure("Value for NSFontAttributeName should be defined in attributes") + let numberOfLines = ceil(heightRounded / lineHeightRounded) + + return UInt(numberOfLines) } - let lineHeight = font.lineHeight - - let lineHeightRounded = Double(lineHeight).roundValue(withPersicion: 2) - - let height = heightWith(width, attributes: attributes) - - let heightRounded = Double(height).roundValue(withPersicion: 2) - - let numberOfLines = ceil(heightRounded / lineHeightRounded) - - return UInt(numberOfLines) + return nil } - /** - method which calculates string width based on given character attributes +} - - parameter attriutes: dictionary with string character attributes - - - returns: string width - */ - public func widthWith(attriutes: [String: AnyObject]) -> CGFloat { - return CGFloat(ceil(Double(sizeWithAttributes(attriutes).width))) - } +public extension NSString { /** - method which calculates text size based on given character attributes + method which calculates string size based on given character attributes and (optional) max width and height - - parameter width: maximum width of text - - parameter height: maximum height of text - parameter attributes: dictionary with string character attributes + - parameter maxWidth: maximum width of text + - parameter maxHeight: maximum height of text - - returns: text size + - returns: string size calculation result */ - public func sizeWith(maxWidth width: CGFloat = CGFloat.max, - maxHeight height: CGFloat = CGFloat.max, - attributes: [String: AnyObject]?) -> CGSize { + public func sizeWith(attributes attributes: [String: AnyObject]?, + maxWidth: CGFloat = CGFloat.max, + maxHeight: CGFloat = CGFloat.max) -> StringSizeCalculationResult { - return boundingRectWithSize(CGSize(width: width, height: height), - options: .UsesLineFragmentOrigin, - attributes: attributes, - context: nil).size + let size = boundingRectWithSize(CGSize(width: maxWidth, height: maxHeight), + options: [.UsesLineFragmentOrigin, .UsesFontLeading], + attributes: attributes, + context: nil).size + + let fontLineHeight = (attributes?[NSFontAttributeName] as? UIFont)?.lineHeight + + return StringSizeCalculationResult(size: size, fontLineHeight: fontLineHeight) } } From c16f67f54fd1728b81f1652c8fd3b591aeb32b15 Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Fri, 9 Sep 2016 10:37:49 +0300 Subject: [PATCH 09/14] small refactor string size calculation extension --- .../Extensions/NSString/NSString+SizeCalculation.swift | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift b/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift index 2b64d3e9..b7730c72 100644 --- a/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift +++ b/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift @@ -20,11 +20,15 @@ public struct StringSizeCalculationResult { public extension StringSizeCalculationResult { + public var height: CGFloat { return size.height } + + public var width: CGFloat { return size.width } + public var numberOfLines: UInt? { if let lineHeight = fontLineHeight { let lineHeightRounded = Double(lineHeight).roundValue(withPersicion: 2) - let heightRounded = Double(size.height).roundValue(withPersicion: 2) + let heightRounded = Double(height).roundValue(withPersicion: 2) let numberOfLines = ceil(heightRounded / lineHeightRounded) @@ -47,7 +51,7 @@ public extension NSString { - returns: string size calculation result */ - public func sizeWith(attributes attributes: [String: AnyObject]?, + public func size(withAttributes attributes: [String: AnyObject]?, maxWidth: CGFloat = CGFloat.max, maxHeight: CGFloat = CGFloat.max) -> StringSizeCalculationResult { @@ -57,7 +61,7 @@ public extension NSString { context: nil).size let fontLineHeight = (attributes?[NSFontAttributeName] as? UIFont)?.lineHeight - + return StringSizeCalculationResult(size: size, fontLineHeight: fontLineHeight) } From fa87bf12e68f9dc9cd0330e409bb8262a06053f9 Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Fri, 9 Sep 2016 11:26:54 +0300 Subject: [PATCH 10/14] apply size calculation to String instead of NSString --- LeadKit/LeadKit.xcodeproj/project.pbxproj | 14 +++++++------- .../String+SizeCalculation.swift} | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) rename LeadKit/LeadKit/Extensions/{NSString/NSString+SizeCalculation.swift => String/String+SizeCalculation.swift} (81%) diff --git a/LeadKit/LeadKit.xcodeproj/project.pbxproj b/LeadKit/LeadKit.xcodeproj/project.pbxproj index 98f47eba..fab9f142 100644 --- a/LeadKit/LeadKit.xcodeproj/project.pbxproj +++ b/LeadKit/LeadKit.xcodeproj/project.pbxproj @@ -24,7 +24,7 @@ 786D78EC1D53C46E006B2CEA /* AlamofireManager+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 786D78EB1D53C46E006B2CEA /* AlamofireManager+Extensions.swift */; }; 787682FA1CAD40C300532AB3 /* StaticEstimatedViewHeightProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 787682F91CAD40C200532AB3 /* StaticEstimatedViewHeightProtocol.swift */; }; 787783631CA03CA0001CDC9B /* NSIndexPath+ImmutableIndexPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 787783621CA03CA0001CDC9B /* NSIndexPath+ImmutableIndexPath.swift */; }; - 787783671CA04D4A001CDC9B /* NSString+SizeCalculation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 787783661CA04D4A001CDC9B /* NSString+SizeCalculation.swift */; }; + 787783671CA04D4A001CDC9B /* String+SizeCalculation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 787783661CA04D4A001CDC9B /* String+SizeCalculation.swift */; }; 787A071A1D085750009EC97F /* CellsControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 787A07191D085750009EC97F /* CellsControllerProtocol.swift */; }; 788EC15A1CF64528009CFB6B /* UIStoryboard+InstantiateViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 788EC1591CF64528009CFB6B /* UIStoryboard+InstantiateViewController.swift */; }; 78A74EA91C6B373700FE9724 /* UIView+DefaultNibName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78A74EA81C6B373700FE9724 /* UIView+DefaultNibName.swift */; }; @@ -81,7 +81,7 @@ 786D78EB1D53C46E006B2CEA /* AlamofireManager+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AlamofireManager+Extensions.swift"; sourceTree = ""; }; 787682F91CAD40C200532AB3 /* StaticEstimatedViewHeightProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StaticEstimatedViewHeightProtocol.swift; sourceTree = ""; }; 787783621CA03CA0001CDC9B /* NSIndexPath+ImmutableIndexPath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSIndexPath+ImmutableIndexPath.swift"; sourceTree = ""; }; - 787783661CA04D4A001CDC9B /* NSString+SizeCalculation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSString+SizeCalculation.swift"; sourceTree = ""; }; + 787783661CA04D4A001CDC9B /* String+SizeCalculation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+SizeCalculation.swift"; sourceTree = ""; }; 787A07191D085750009EC97F /* CellsControllerProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CellsControllerProtocol.swift; sourceTree = ""; }; 788EC1591CF64528009CFB6B /* UIStoryboard+InstantiateViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIStoryboard+InstantiateViewController.swift"; sourceTree = ""; }; 78A74EA81C6B373700FE9724 /* UIView+DefaultNibName.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "UIView+DefaultNibName.swift"; path = "LeadKit/Extensions/UIView/UIView+DefaultNibName.swift"; sourceTree = SOURCE_ROOT; }; @@ -200,12 +200,12 @@ path = NSIndexPath; sourceTree = ""; }; - 787783651CA04D14001CDC9B /* NSString */ = { + 787783651CA04D14001CDC9B /* String */ = { isa = PBXGroup; children = ( - 787783661CA04D4A001CDC9B /* NSString+SizeCalculation.swift */, + 787783661CA04D4A001CDC9B /* String+SizeCalculation.swift */, ); - path = NSString; + path = String; sourceTree = ""; }; 78A74EAA1C6B401800FE9724 /* Classes */ = { @@ -291,7 +291,7 @@ children = ( 78C36F7F1D8021D100E7EBEA /* UIColor */, 78C36F7C1D801E2F00E7EBEA /* Double */, - 787783651CA04D14001CDC9B /* NSString */, + 787783651CA04D14001CDC9B /* String */, 787783611CA03C84001CDC9B /* NSIndexPath */, 78E59B2C1C786CD500C6BFE9 /* UIView */, 78E59B2B1C786CBF00C6BFE9 /* UITableView */, @@ -537,7 +537,7 @@ 78B0FC7F1C6B2C4D00358B64 /* Log.swift in Sources */, 78CFEE571C5C45E500F50370 /* StaticNibNameProtocol.swift in Sources */, 788EC15A1CF64528009CFB6B /* UIStoryboard+InstantiateViewController.swift in Sources */, - 787783671CA04D4A001CDC9B /* NSString+SizeCalculation.swift in Sources */, + 787783671CA04D4A001CDC9B /* String+SizeCalculation.swift in Sources */, 78011A641D47ABC500EA16A2 /* UIView+DefaultReuseIdentifier.swift in Sources */, 78CFEE531C5C45E500F50370 /* UITableView+DequeueCustomCell.swift in Sources */, 786D78EC1D53C46E006B2CEA /* AlamofireManager+Extensions.swift in Sources */, diff --git a/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift b/LeadKit/LeadKit/Extensions/String/String+SizeCalculation.swift similarity index 81% rename from LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift rename to LeadKit/LeadKit/Extensions/String/String+SizeCalculation.swift index b7730c72..f4e89b4b 100644 --- a/LeadKit/LeadKit/Extensions/NSString/NSString+SizeCalculation.swift +++ b/LeadKit/LeadKit/Extensions/String/String+SizeCalculation.swift @@ -1,5 +1,5 @@ // -// NSString+SizeCAlculation.swift +// String+SizeCalculation.swift // LeadKit // // Created by Иван Смолин on 21/03/16. @@ -40,7 +40,7 @@ public extension StringSizeCalculationResult { } -public extension NSString { +public extension String { /** method which calculates string size based on given character attributes and (optional) max width and height @@ -55,13 +55,13 @@ public extension NSString { maxWidth: CGFloat = CGFloat.max, maxHeight: CGFloat = CGFloat.max) -> StringSizeCalculationResult { - let size = boundingRectWithSize(CGSize(width: maxWidth, height: maxHeight), - options: [.UsesLineFragmentOrigin, .UsesFontLeading], - attributes: attributes, - context: nil).size + let size = self.boundingRectWithSize(CGSize(width: maxWidth, height: maxHeight), + options: [.UsesLineFragmentOrigin, .UsesFontLeading], + attributes: attributes, + context: nil).size let fontLineHeight = (attributes?[NSFontAttributeName] as? UIFont)?.lineHeight - + return StringSizeCalculationResult(size: size, fontLineHeight: fontLineHeight) } From 7de68b57891c5fff049da4f74315b277c19d48fa Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Fri, 9 Sep 2016 11:33:36 +0300 Subject: [PATCH 11/14] bump library version --- LeadKit.podspec | 2 +- LeadKit/LeadKit/Info.plist | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LeadKit.podspec b/LeadKit.podspec index fa45988b..e8bec314 100644 --- a/LeadKit.podspec +++ b/LeadKit.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "LeadKit" - s.version = "0.0.1" + s.version = "0.0.3" s.summary = "iOS framework with a bunch of tools for rapid development" s.homepage = "https://github.com/TouchInstinct/LeadKit" s.license = "Apache License, Version 2.0" diff --git a/LeadKit/LeadKit/Info.plist b/LeadKit/LeadKit/Info.plist index 11d74583..a1497e57 100644 --- a/LeadKit/LeadKit/Info.plist +++ b/LeadKit/LeadKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.1 + 0.0.3 CFBundleSignature ???? CFBundleVersion From ea4eb6db0ee65743e223b92aa638c48ec95a703e Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Fri, 9 Sep 2016 11:34:10 +0300 Subject: [PATCH 12/14] partially revert gitignore changes --- .gitignore | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/.gitignore b/.gitignore index c3760bab..7489e264 100644 --- a/.gitignore +++ b/.gitignore @@ -1,34 +1,3 @@ -# ================ -# macOS.gitignore -# ================ - -*.DS_Store -.AppleDouble -.LSOverride - -# Icon must end with two \r -Icon - - -# Thumbnails -._* - -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - # ================ # Swift.gitignore # ================ From 8ed1876c7e5a280236b3da0b02158352de1d357a Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Fri, 9 Sep 2016 12:28:05 +0300 Subject: [PATCH 13/14] UIColor+Hex from string fix --- .../Extensions/UIColor/UIColor+Hex.swift | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift b/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift index 9d31250d..b8ab108f 100644 --- a/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift +++ b/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift @@ -87,28 +87,32 @@ public extension UIColor { public convenience init?(hexString: String, alpha: CGFloat = 1) { let hexStr = hexString.hasPrefix("#") ? hexString.substringFromIndex(hexString.startIndex.advancedBy(1)) : hexString - switch hexStr.characters.count { - case 3: + let charactersCount = hexStr.characters.count + + switch charactersCount { + case 3, 4: if let hex = UInt16(hexStr, radix: 16) { - self.init(hex3: hex, alpha: alpha) + if charactersCount == 3 { + self.init(hex3: hex, alpha: alpha) + } else { + self.init(hex4: hex) + } + } else { + return nil } - case 4: - if let hex = UInt16(hexStr, radix: 16) { - self.init(hex4: hex) - } - case 6: + case 6, 8: if let hex = UInt32(hexStr, radix: 16) { - self.init(hex6: hex, alpha: alpha) - } - case 8: - if let hex = UInt32(hexStr, radix: 16) { - self.init(hex8: hex) + if charactersCount == 6 { + self.init(hex6: hex, alpha: alpha) + } else { + self.init(hex8: hex) + } + } else { + return nil } default: return nil } - - return nil } } From 8be0103c1db1d3ba8bee600b7aa48f00de96c825 Mon Sep 17 00:00:00 2001 From: Ivan Smolin Date: Fri, 9 Sep 2016 21:33:24 +0300 Subject: [PATCH 14/14] UIColor extension fix --- .../LeadKit/Extensions/UIColor/UIColor+Hex.swift | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift b/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift index b8ab108f..9c869ade 100644 --- a/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift +++ b/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift @@ -20,9 +20,9 @@ public extension UIColor { - returns: new instance with given three-digit hexadecimal value */ public convenience init(hex3: UInt16, alpha: CGFloat = 1) { - let red = CGFloat((hex3 & 0xF00) >> 8) / 0xFF - let green = CGFloat((hex3 & 0x0F0) >> 4) / 0xFF - let blue = CGFloat((hex3 & 0x00F) >> 0) / 0xFF + let red = CGFloat((hex3 & 0xF00) >> 8) / 0xF + let green = CGFloat((hex3 & 0x0F0) >> 4) / 0xF + let blue = CGFloat((hex3 & 0x00F) >> 0) / 0xF self.init(red: red, green: green, blue: blue, alpha: alpha) } @@ -35,10 +35,10 @@ public extension UIColor { - returns: new instance with given four-digit hexadecimal value */ public convenience init(hex4: UInt16) { - let red = CGFloat((hex4 & 0xF000) >> 12) / 0xFF - let green = CGFloat((hex4 & 0x0F00) >> 8) / 0xFF - let blue = CGFloat((hex4 & 0x00F0) >> 4) / 0xFF - let alpha = CGFloat((hex4 & 0x000F) >> 0) / 0xFF + let red = CGFloat((hex4 & 0xF000) >> 12) / 0xF + let green = CGFloat((hex4 & 0x0F00) >> 8) / 0xF + let blue = CGFloat((hex4 & 0x00F0) >> 4) / 0xF + let alpha = CGFloat((hex4 & 0x000F) >> 0) / 0xF self.init(red: red, green: green, blue: blue, alpha: alpha) }