From 2dc2ac0c3b273035a2b77bb3fe905f84f7ed726f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B8=CC=86=20=D0=90?= =?UTF-8?q?=D1=88=D0=B0=D0=BD=D0=B8=D0=BD?= Date: Thu, 29 Sep 2016 15:56:39 +0300 Subject: [PATCH 1/5] image extension added --- LeadKit/.DS_Store | Bin 6148 -> 6148 bytes LeadKit/LeadKit.xcodeproj/project.pbxproj | 36 ++++- .../Classes/Cache/ObjectsGenerator.swift | 6 +- .../Classes/Cache/ViewsGenerator.swift | 4 +- .../AlamofireRequest+Extensions.swift | 4 +- .../Extensions/UIColor/UIColor+Hex.swift | 18 +-- .../Extensions/UIImage/UIImage+Alpha.swift | 123 ++++++++++++++++++ .../UIImage/UIImage+CapInsetsUtils.swift | 2 +- .../Extensions/UIImage/UIImage+Creation.swift | 21 +++ .../Extensions/UIImage/UIImage+Cropping.swift | 44 +++++++ .../UIImage/UIImage+Gradients.swift | 122 +++++++++++++++++ .../Extensions/UIImage/UIImage+Loading.swift | 85 ++++++++++++ .../Extensions/UIImage/UIImage+Resize.swift | 49 +++++++ .../Extensions/UIImage/UIImage+Text.swift | 45 +++++++ .../UIImage/UIImage+Transformations.swift | 119 +++++++++++++++++ .../UIImageView+LoadingImage.swift | 51 ++++++++ 16 files changed, 703 insertions(+), 26 deletions(-) create mode 100644 LeadKit/LeadKit/Extensions/UIImage/UIImage+Alpha.swift create mode 100644 LeadKit/LeadKit/Extensions/UIImage/UIImage+Cropping.swift create mode 100644 LeadKit/LeadKit/Extensions/UIImage/UIImage+Gradients.swift create mode 100644 LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift create mode 100644 LeadKit/LeadKit/Extensions/UIImage/UIImage+Text.swift create mode 100644 LeadKit/LeadKit/Extensions/UIImageView/UIImageView+LoadingImage.swift diff --git a/LeadKit/.DS_Store b/LeadKit/.DS_Store index ff34d0557148e086cf7266146c6336d809da14ba..36540d453b4d9c36e0702f3ad79d5fc0e927cb19 100644 GIT binary patch delta 61 zcmZoMXffDe&&bTkD?ND~qZ(gszKcsrX-P5z!xf=@+>_TZYD}KT$i;F+u+<*OG28rA Qgr9j6lNj@6c85CL(voBbhRc^-geI?H)R;Vvk&ET>W#?l+jv1rC S=8ueGY!e&!HnVg5 { /** initializer function - - parameter poolSize: number of objects to generate - - parameter contructor: objects constructor closure - - - returns: nothing + - parameter poolSize: number of objects to generate + - parameter contructor: objects constructor closure */ init(poolSize: UInt, objectsContructor contructor: ObjectConstructor) { self.poolSize = poolSize diff --git a/LeadKit/LeadKit/Classes/Cache/ViewsGenerator.swift b/LeadKit/LeadKit/Classes/Cache/ViewsGenerator.swift index 352bc3de..5b7bef95 100644 --- a/LeadKit/LeadKit/Classes/Cache/ViewsGenerator.swift +++ b/LeadKit/LeadKit/Classes/Cache/ViewsGenerator.swift @@ -14,9 +14,7 @@ public class ViewsGenerator: ObjectsGenerator { initializer function - parameter poolSize: number of cells to generate - - parameter nibName: view nib name - - - returns: nothing + - parameter nibName: view nib name */ init(poolSize: UInt, nibName: String) { super.init(poolSize: poolSize, objectsContructor: { T.loadFromNib(named: nibName) }) diff --git a/LeadKit/LeadKit/Extensions/Alamofire/AlamofireRequest+Extensions.swift b/LeadKit/LeadKit/Extensions/Alamofire/AlamofireRequest+Extensions.swift index 7ab3ec86..af933a9f 100644 --- a/LeadKit/LeadKit/Extensions/Alamofire/AlamofireRequest+Extensions.swift +++ b/LeadKit/LeadKit/Extensions/Alamofire/AlamofireRequest+Extensions.swift @@ -24,8 +24,8 @@ public extension Alamofire.Request { return .Failure(.Network(error: err)) } - let JSONResponseSerializer = Request.JSONResponseSerializer(options: .AllowFragments) - let result = JSONResponseSerializer.serializeResponse(request, response, data, error) + let jsonResponseSerializer = Request.JSONResponseSerializer(options: .AllowFragments) + let result = jsonResponseSerializer.serializeResponse(request, response, data, error) switch result { case .Success(let value): diff --git a/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift b/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift index 9c869ade..1ef9f821 100644 --- a/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift +++ b/LeadKit/LeadKit/Extensions/UIColor/UIColor+Hex.swift @@ -11,13 +11,11 @@ import UIKit public extension UIColor { /** - The shorthand three-digit hexadecimal representation of color. + the shorthand three-digit hexadecimal representation of color. #RGB defines to the color #RRGGBB. - parameter hex3: Three-digit hexadecimal value. - parameter alpha: 0.0 - 1.0. The default is 1.0. - - - returns: new instance with given three-digit hexadecimal value */ public convenience init(hex3: UInt16, alpha: CGFloat = 1) { let red = CGFloat((hex3 & 0xF00) >> 8) / 0xF @@ -27,12 +25,10 @@ public extension UIColor { } /** - The shorthand four-digit hexadecimal representation of color with 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) / 0xF @@ -44,12 +40,10 @@ public extension UIColor { } /** - The six-digit hexadecimal representation of color of the form #RRGGBB. + 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 @@ -60,11 +54,9 @@ public extension UIColor { } /** - The six-digit hexadecimal representation of color with alpha of the form #RRGGBBAA. + 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 @@ -81,8 +73,6 @@ public extension UIColor { - parameter hexString: hex string with red green and blue values (can have `#` sign) - 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 hexStr = hexString.hasPrefix("#") ? hexString.substringFromIndex(hexString.startIndex.advancedBy(1)) : hexString diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Alpha.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Alpha.swift new file mode 100644 index 00000000..bb23247e --- /dev/null +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Alpha.swift @@ -0,0 +1,123 @@ +// +// UIImage+Alpha.swift +// LeadKit +// +// Created by Николай Ашанин on 28.09.16. +// Copyright © 2016 Touch Instinct. All rights reserved. +// + +import UIKit + +public extension UIImage { + + /** + - returns: true if the image has an alpha layer. + */ + public func hasAlpha() -> Bool { + let alpha = CGImageGetAlphaInfo(CGImage) + switch alpha { + case .First, .Last, .PremultipliedFirst, .PremultipliedLast: + return true + default: + return false + } + } + + /** + - returns: a copy of the given image, adding an alpha channel if it doesn't already have one. + */ + public func applyAlpha() -> UIImage? { + if hasAlpha() { + return self + } + + let imageRef = CGImage + let width = CGImageGetWidth(imageRef) + let height = CGImageGetHeight(imageRef) + let colorSpace = CGImageGetColorSpace(imageRef) + + // The bitsPerComponent and bitmapInfo values are hard-coded to prevent an "unsupported parameter combination" error + let bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo.ByteOrderDefault.rawValue | + CGImageAlphaInfo.PremultipliedFirst.rawValue) + let offscreenContext = CGBitmapContextCreate(nil, width, height, 8, 0, colorSpace, bitmapInfo.rawValue) + + // Draw the image into the context and retrieve the new image, which will now have an alpha layer + CGContextDrawImage(offscreenContext, + CGRect(x: 0, y: 0, width: width, height: height), + imageRef) + guard let cgImage = CGBitmapContextCreateImage(offscreenContext) else { + return nil + } + let imageWithAlpha = UIImage(CGImage: cgImage) + return imageWithAlpha + } + + /** + returns a copy of the image with a transparent border of the given size added around its edges. + i.e. For rotating an image without getting jagged edges. + + - parameter padding: The padding amount. + + - returns: A new image. + */ + public func applyPadding(padding: CGFloat) -> UIImage? { + // If the image does not have an alpha layer, add one + guard let image = applyAlpha() else { + return nil + } + let rect = CGRect(x: 0, y: 0, width: size.width + padding * 2, height: size.height + padding * 2) + + // Build a context that's the same dimensions as the new size + let colorSpace = CGImageGetColorSpace(CGImage) + let bitmapInfo = CGImageGetBitmapInfo(CGImage) + let bitsPerComponent = CGImageGetBitsPerComponent(CGImage) + let context = CGBitmapContextCreate(nil, + Int(rect.size.width), + Int(rect.size.height), + bitsPerComponent, 0, colorSpace, + bitmapInfo.rawValue) + + // Draw the image in the center of the context, leaving a gap around the edges + let imageLocation = CGRect(x: padding, y: padding, width: image.size.width, height: image.size.height) + CGContextDrawImage(context, imageLocation, CGImage) + + // Create a mask to make the border transparent, and combine it with the image + let imageWithPadding = imageRefWithPadding(padding, size: rect.size) + guard let cgImage = CGImageCreateWithMask(CGBitmapContextCreateImage(context), imageWithPadding) else { + return nil + } + let transparentImage = UIImage(CGImage: cgImage) + return transparentImage + } + + /** + creates a mask that makes the outer edges transparent and everything else opaque. + The size must include the entire mask (opaque part + transparent border). + + - parameter padding: The padding amount. + - parameter size: The size of the image. + + - returns: A Core Graphics Image Ref + */ + private func imageRefWithPadding(padding: CGFloat, + size: CGSize) -> CGImageRef? { + // Build a context that's the same dimensions as the new size + let colorSpace = CGColorSpaceCreateDeviceGray() + let bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo.ByteOrderDefault.rawValue | CGImageAlphaInfo.None.rawValue) + let context = CGBitmapContextCreate(nil, Int(size.width), Int(size.height), 8, 0, colorSpace, bitmapInfo.rawValue) + // Start with a mask that's entirely transparent + CGContextSetFillColorWithColor(context, UIColor.blackColor().CGColor) + CGContextFillRect(context, CGRect(x: 0, y: 0, width: size.width, height: size.height)) + // Make the inner part (within the border) opaque + CGContextSetFillColorWithColor(context, UIColor.whiteColor().CGColor) + let fillRect = CGRect(x: padding, + y: padding, + width: size.width - padding * 2, + height: size.height - padding * 2) + CGContextFillRect(context, fillRect) + // Get an image of the context + let maskImageRef = CGBitmapContextCreateImage(context) + return maskImageRef + } + +} diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+CapInsetsUtils.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+CapInsetsUtils.swift index 80d4d84e..6883fb60 100644 --- a/LeadKit/LeadKit/Extensions/UIImage/UIImage+CapInsetsUtils.swift +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+CapInsetsUtils.swift @@ -40,7 +40,7 @@ public extension UIImage { } /** - this metho tries to find requested image with specific parameters in cache, and if doesn't exists - create it + this method tries to find requested image with specific parameters in cache, and if doesn't exists - create it - parameter name: name of the image used in UIImage(named:) - parameter size: size of rendered image diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Creation.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Creation.swift index 7ca919a9..9417d85a 100644 --- a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Creation.swift +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Creation.swift @@ -33,4 +33,25 @@ public extension UIImage { return UIGraphicsGetImageFromCurrentImageContext() } + /** + creates an image from a UIView. + + - parameter fromView: The source view. + + - returns A new image + */ + public convenience init?(fromView view: UIView) { + UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0) + + guard let context = UIGraphicsGetCurrentContext() else { + return nil + } + view.layer.renderInContext(context) + guard let cgImage = UIGraphicsGetImageFromCurrentImageContext().CGImage else { + return nil + } + self.init(CGImage: cgImage) + UIGraphicsEndImageContext() + } + } diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Cropping.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Cropping.swift new file mode 100644 index 00000000..7b3ed8e5 --- /dev/null +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Cropping.swift @@ -0,0 +1,44 @@ +// +// UIImage+Cropping.swift +// LeadKit +// +// Created by Николай Ашанин on 28.09.16. +// Copyright © 2016 Touch Instinct. All rights reserved. +// + +import UIKit + +public extension UIImage { + + /** + creates a cropped copy of an image. + + - parameter bounds: The bounds of the rectangle inside the image. + + - returns: A new image + */ + public func crop(bounds: CGRect) -> UIImage? { + guard let cgImage = CGImageCreateWithImageInRect(CGImage, bounds) else { + return nil + } + return UIImage(CGImage: cgImage, + scale: 0.0, + orientation: imageOrientation) + } + + /** + crop image to square + + - returns: cropped image + */ + public func cropToSquare() -> UIImage? { + let newSize = CGSize(width: size.width * scale, height: size.height * scale) + let shortest = min(newSize.width, newSize.height) + let left: CGFloat = newSize.width > shortest ? (newSize.width-shortest)/2 : 0 + let top: CGFloat = newSize.height > shortest ? (newSize.height-shortest)/2 : 0 + let rect = CGRect(x: 0, y: 0, width: size.width, height: newSize.height) + let insetRect = CGRectInset(rect, left, top) + return crop(insetRect) + } + +} diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Gradients.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Gradients.swift new file mode 100644 index 00000000..09f15ec4 --- /dev/null +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Gradients.swift @@ -0,0 +1,122 @@ +// +// UIImage+Gradients.swift +// LeadKit +// +// Created by Николай Ашанин on 28.09.16. +// Copyright © 2016 Touch Instinct. All rights reserved. +// + +import UIKit + +public extension UIImage { + + /** + creates a gradient color image. + + - parameter gradientColors: An array of colors to use for the gradient. + - parameter size: Image size (defaults: 10x10) + */ + public convenience init?(gradientColors: [UIColor], + size: CGSize = CGSize(width: 10, height: 10)) { + UIGraphicsBeginImageContextWithOptions(size, false, 0) + let context = UIGraphicsGetCurrentContext() + let colorSpace = CGColorSpaceCreateDeviceRGB() + let colors = gradientColors.map {(color: UIColor) -> AnyObject? in return color.CGColor as AnyObject? } as NSArray + let gradient = CGGradientCreateWithColors(colorSpace, colors, nil) + CGContextDrawLinearGradient(context, gradient, + CGPoint(x: 0, y: 0), + CGPoint(x: 0, y: size.height), + CGGradientDrawingOptions(rawValue: 0)) + guard let cgImage = UIGraphicsGetImageFromCurrentImageContext().CGImage else { + return nil + } + self.init(CGImage: cgImage) + UIGraphicsEndImageContext() + } + + /** + applies gradient color overlay to an image. + + - parameter gradientColors: An array of colors to use for the gradient. + - parameter blendMode: The blending type to use. + + - returns: A new image + */ + public func applyGradientColors(gradientColors: [UIColor], + blendMode: CGBlendMode = .Normal) -> UIImage { + UIGraphicsBeginImageContextWithOptions(size, false, scale) + let context = UIGraphicsGetCurrentContext() + CGContextTranslateCTM(context, 0, size.height) + CGContextScaleCTM(context, 1.0, -1.0) + CGContextSetBlendMode(context, blendMode) + let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) + CGContextDrawImage(context, rect, CGImage) + // Create gradient + let colorSpace = CGColorSpaceCreateDeviceRGB() + let colors = gradientColors.map {(color: UIColor) -> AnyObject? in return color.CGColor as AnyObject? } as NSArray + let gradient = CGGradientCreateWithColors(colorSpace, colors, nil) + // Apply gradient + CGContextClipToMask(context, rect, CGImage) + CGContextDrawLinearGradient(context, + gradient, + CGPoint(x: 0, y: 0), + CGPoint(x: 0, y: size.height), + CGGradientDrawingOptions(rawValue: 0)) + let image = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + return image + } + + /** + creates a radial gradient. + + - parameter startColor: The start color + - parameter endColor: The end color + - parameter radialGradientCenter: The gradient center (default:0.5,0.5). + - parameter radius: Radius size (default: 0.5) + - parameter size: Image size (default: 100x100) + */ + public convenience init?(startColor: UIColor, + endColor: UIColor, + radialGradientCenter: CGPoint = CGPoint(x: 0.5, y: 0.5), + radius: Float = 0.5, + size: CGSize = CGSize(width: 100, height: 100)) { + UIGraphicsBeginImageContextWithOptions(size, true, 0) + + let numLocations: Int = 2 + let locations: [CGFloat] = [0.0, 1.0] as [CGFloat] + + let startComponents = CGColorGetComponents(startColor.CGColor) + let endComponents = CGColorGetComponents(endColor.CGColor) + + let components: [CGFloat] = [startComponents[0], + startComponents[1], + startComponents[2], + startComponents[3], + endComponents[0], + endComponents[1], + endComponents[2], + endComponents[3]] as [CGFloat] + + let colorSpace = CGColorSpaceCreateDeviceRGB() + let gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, numLocations) + + // Normalize the 0-1 ranged inputs to the width of the image + let aCenter = CGPoint(x: radialGradientCenter.x * size.width, + y: radialGradientCenter.y * size.height) + let aRadius = CGFloat(min(size.width, size.height)) * CGFloat(radius) + + // Draw it + CGContextDrawRadialGradient(UIGraphicsGetCurrentContext(), + gradient, aCenter, 0, + aCenter, aRadius, + CGGradientDrawingOptions.DrawsAfterEndLocation) + guard let cgImage = UIGraphicsGetImageFromCurrentImageContext().CGImage else { + return nil + } + self.init(CGImage: cgImage) + // Clean up + UIGraphicsEndImageContext() + } + +} diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift new file mode 100644 index 00000000..ef329849 --- /dev/null +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift @@ -0,0 +1,85 @@ +// +// UIImage+Loading.swift +// LeadKit +// +// Created by Николай Ашанин on 28.09.16. +// Copyright © 2016 Touch Instinct. All rights reserved. +// + +import UIKit +import QuartzCore +import CoreGraphics +import Accelerate + +public enum UIImageContentMode { + case ScaleToFill, ScaleAspectFit, ScaleAspectFill +} + +struct StaticSharedCache { + static var sharedCache: NSCache? = nil + static var onceToken: dispatch_once_t = 0 +} + +public extension UIImage { + + /** + a singleton shared NSURL cache used for images from URL + + - returns: shared image cache + */ + private class func sharedCache() -> NSCache { + dispatch_once(&StaticSharedCache.onceToken) { + StaticSharedCache.sharedCache = NSCache() + } + return StaticSharedCache.sharedCache + } + + // MARK: Image From URL + + /** + creates a new image from a URL with optional caching. + if cached, the cached image is returned. + otherwise, a place holder is used until the image from web is returned by the closure. + + - parameter url: The image URL. + - parameter placeholder: The placeholder image. + - parameter shouldCacheImage: Weather or not we should cache the NSURL response (default: true) + - parameter closure: Returns the image from the web the first time is fetched. + + - returns: A new image + */ + public class func imageFromURL(url: String, + placeholder: UIImage, + shouldCacheImage: Bool = true, + closure: (image: UIImage?) -> ()) -> UIImage? { + // From Cache + if shouldCacheImage { + if let image = UIImage.sharedCache().objectForKey(url) as? UIImage { + closure(image: nil) + return image + } + } + // Fetch Image + let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration()) + if let nsURL = NSURL(string: url) { + session.dataTaskWithURL(nsURL, completionHandler: { (data, response, error) -> Void in + if error != nil { + dispatch_async(dispatch_get_main_queue()) { + closure(image: nil) + } + } + if let data = data, image = UIImage(data: data) { + if shouldCacheImage { + UIImage.sharedCache().setObject(image, forKey: url) + } + dispatch_async(dispatch_get_main_queue()) { + closure(image: image) + } + } + session.finishTasksAndInvalidate() + }).resume() + } + return placeholder + } + +} diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Resize.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Resize.swift index 4acae7da..1e9a2213 100644 --- a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Resize.swift +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Resize.swift @@ -28,4 +28,53 @@ public extension UIImage { return UIGraphicsGetImageFromCurrentImageContext() } + /** + creates a resized copy of an image. + + - parameter size: the new size of the image. + - parameter contentMode: the way to handle the content in the new size. + + - returns: a new image + */ + public func resize(size: CGSize, + contentMode: UIImageContentMode = .ScaleToFill) -> UIImage? { + let horizontalRatio = size.width/size.width + let verticalRatio = size.height/size.height + var ratio: CGFloat = 1 + + switch contentMode { + case .ScaleToFill: + ratio = 1 + case .ScaleAspectFill: + ratio = max(horizontalRatio, verticalRatio) + case .ScaleAspectFit: + ratio = min(horizontalRatio, verticalRatio) + } + + let rect = CGRect(x: 0, y: 0, width: size.width * ratio, height: size.height * ratio) + + let colorSpace = CGColorSpaceCreateDeviceRGB() + let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedLast.rawValue) + let context = CGBitmapContextCreate(nil, + Int(rect.size.width), + Int(rect.size.height), 8, 0, colorSpace, + bitmapInfo.rawValue) + let transform = CGAffineTransformIdentity + CGContextConcatCTM(context, transform) + // Set the quality level to use when rescaling + guard let interpolationQuality = CGInterpolationQuality(rawValue: 3) else { + return nil + } + CGContextSetInterpolationQuality(context, interpolationQuality) + CGContextDrawImage(context, rect, CGImage) + + guard let newContext = context else { + return nil + } + let newImage = UIImage(CGImage: CGBitmapContextCreateImage(newContext), + scale: scale, + orientation: imageOrientation) + return newImage + } + } diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Text.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Text.swift new file mode 100644 index 00000000..79dfe2b2 --- /dev/null +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Text.swift @@ -0,0 +1,45 @@ +// +// UIImage+Text.swift +// LeadKit +// +// Created by Николай Ашанин on 28.09.16. +// Copyright © 2016 Touch Instinct. All rights reserved. +// + +import UIKit + +public extension UIImage { + + /** + creates a text label image. + + - parameter text: The text to use in the label. + - parameter font: The font (default: System font of size 18) + - parameter color: The text color (default: White) + - parameter backgroundColor: The background color (default:Gray). + - parameter size: Image size (default: 10x10) + - parameter offset: Center offset (default: 0x0) + */ + public convenience init?(text: String, + font: UIFont = UIFont.systemFontOfSize(18), + color: UIColor = UIColor.whiteColor(), + backgroundColor: UIColor = UIColor.grayColor(), + size: CGSize = CGSize(width: 10, height: 10), + offset: CGPoint = CGPoint(x: 0, y: 0)) { + let label = UILabel(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height)) + label.font = font + label.text = text + label.textColor = color + label.textAlignment = .Center + label.backgroundColor = backgroundColor + let image = UIImage(fromView: label) + UIGraphicsBeginImageContextWithOptions(size, false, 0) + image?.drawInRect(CGRect(x: 0, y: 0, width: size.width, height: size.height)) + guard let cgImage = UIGraphicsGetImageFromCurrentImageContext().CGImage else { + return nil + } + self.init(CGImage: cgImage) + UIGraphicsEndImageContext() + } + +} diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Transformations.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Transformations.swift index bad69574..e45964b6 100644 --- a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Transformations.swift +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Transformations.swift @@ -32,4 +32,123 @@ public extension UIImage { return UIGraphicsGetImageFromCurrentImageContext() } + /** + creates a new image with rounded corners. + + - parameter cornerRadius: The corner radius. + + - returns: A new image + */ + public func roundCorners(cornerRadius: CGFloat) -> UIImage? { + guard let imageWithAlpha = applyAlpha() else { + return nil + } + UIGraphicsBeginImageContextWithOptions(size, false, 0) + let width = CGImageGetWidth(imageWithAlpha?.CGImage) + let height = CGImageGetHeight(imageWithAlpha?.CGImage) + let bits = CGImageGetBitsPerComponent(imageWithAlpha?.CGImage) + let colorSpace = CGImageGetColorSpace(imageWithAlpha?.CGImage) + let bitmapInfo = CGImageGetBitmapInfo(imageWithAlpha?.CGImage) + let context = CGBitmapContextCreate(nil, width, height, bits, 0, colorSpace, bitmapInfo.rawValue) + let rect = CGRect(x: 0, y: 0, width: CGFloat(width) * scale, height: CGFloat(height) * scale) + CGContextBeginPath(context) + if cornerRadius == 0 { + CGContextAddRect(context, rect) + } else { + CGContextSaveGState(context) + CGContextTranslateCTM(context, rect.minX, rect.minY) + CGContextScaleCTM(context, cornerRadius, cornerRadius) + let fw = rect.size.width / cornerRadius + let fh = rect.size.height / cornerRadius + CGContextMoveToPoint(context, fw, fh/2) + CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1) + CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1) + CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1) + CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1) + CGContextRestoreGState(context) + } + CGContextClosePath(context) + CGContextClip(context) + CGContextDrawImage(context, rect, imageWithAlpha?.CGImage) + guard let bitmapImage = CGBitmapContextCreateImage(context) else { + return nil + } + let image = UIImage(CGImage: bitmapImage, + scale: scale, + orientation: .Up) + UIGraphicsEndImageContext() + return image + } + + /** + creates a new image with rounded corners and border. + + - parameter cornerRadius: The corner radius. + - parameter border: The size of the border. + - parameter color: The color of the border. + + - returns: A new image + */ + public func roundCorners(cornerRadius: CGFloat, + border: CGFloat, + color: UIColor) -> UIImage? { + return roundCorners(cornerRadius)?.applyBorder(border, color: color) + } + + /** + creates a new circle image. + + - returns: A new image + */ + public func roundCornersToCircle() -> UIImage? { + let shortest = min(size.width, size.height) + return cropToSquare()?.roundCorners(shortest/2) + } + + /** + creates a new circle image with a border. + + - parameter border: CGFloat The size of the border. + - parameter color: UIColor The color of the border. + + - returns: UIImage? + */ + public func roundCornersToCircle(border border: CGFloat, color: UIColor) -> UIImage? { + let shortest = min(size.width, size.height) + return cropToSquare()?.roundCorners(shortest/2, border: border, color: color) + } + + /** + creates a new image with a border. + + - parameter border: The size of the border. + - parameter color: The color of the border. + + - returns: A new image + */ + public func applyBorder(border: CGFloat, + color: UIColor) -> UIImage? { + UIGraphicsBeginImageContextWithOptions(size, false, 0) + let width = CGImageGetWidth(CGImage) + let height = CGImageGetHeight(CGImage) + let bits = CGImageGetBitsPerComponent(CGImage) + let colorSpace = CGImageGetColorSpace(CGImage) + let bitmapInfo = CGImageGetBitmapInfo(CGImage) + let context = CGBitmapContextCreate(nil, width, height, bits, 0, colorSpace, bitmapInfo.rawValue) + var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, alpha: CGFloat = 0 + color.getRed(&red, green: &green, blue: &blue, alpha: &alpha) + CGContextSetRGBStrokeColor(context, red, green, blue, alpha) + CGContextSetLineWidth(context, border) + let rect = CGRect(x: 0, y: 0, width: size.width*scale, height: size.height*scale) + let inset = CGRectInset(rect, border*scale, border*scale) + CGContextStrokeEllipseInRect(context, inset) + CGContextDrawImage(context, inset, CGImage) + guard let bitmapImage = CGBitmapContextCreateImage(context) else { + return nil + } + let image = UIImage(CGImage: bitmapImage) + UIGraphicsEndImageContext() + return image + } + } diff --git a/LeadKit/LeadKit/Extensions/UIImageView/UIImageView+LoadingImage.swift b/LeadKit/LeadKit/Extensions/UIImageView/UIImageView+LoadingImage.swift new file mode 100644 index 00000000..ab4d9dbb --- /dev/null +++ b/LeadKit/LeadKit/Extensions/UIImageView/UIImageView+LoadingImage.swift @@ -0,0 +1,51 @@ +// +// UIImageView+LoadingImage.swift +// LeadKit +// +// Created by Николай Ашанин on 28.09.16. +// Copyright © 2016 Touch Instinct. All rights reserved. +// + +import UIKit +import QuartzCore + +public extension UIImageView { + + /** + loads an image from a URL. If cached, the cached image is returned. + otherwise, a place holder is used until the image from web is returned by the closure. + + - parameter url: The image URL. + - parameter placeholder: The placeholder image. + - parameter fadeIn: Weather the mage should fade in. + - parameter shouldCacheImage: Should be image cached. + - parameter closure: Returns the image from the web the first time is fetched. + + - returns: A new image + */ + public func imageFromURL(url: String, + placeholder: UIImage, + fadeIn: Bool = true, + shouldCacheImage: Bool = true, + closure: ((image: UIImage?) -> ())? = nil) { + + image = UIImage.imageFromURL(url, + placeholder: placeholder, + shouldCacheImage: shouldCacheImage) { (uploadedImage: UIImage?) in + + guard let image = uploadedImage else { + return nil + } + self.image = image + if fadeIn { + let transition = CATransition() + transition.duration = 0.5 + transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) + transition.type = kCATransitionFade + layer.addAnimation(transition, forKey: nil) + } + closure?(image: image) + } + } + +} From 6f6ff9f3ecb863e2d6dc5547ca539828314038ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B8=CC=86=20=D0=90?= =?UTF-8?q?=D1=88=D0=B0=D0=BD=D0=B8=D0=BD?= Date: Thu, 29 Sep 2016 17:51:52 +0300 Subject: [PATCH 2/5] review notes fixed --- LeadKit/.DS_Store | Bin 6148 -> 6148 bytes LeadKit/LeadKit.xcodeproj/project.pbxproj | 4 +++ .../String/String+Localization.swift | 22 +++++++++++++++ .../Extensions/UIImage/UIImage+Alpha.swift | 2 +- .../Extensions/UIImage/UIImage+Cropping.swift | 10 +++---- .../UIImage/UIImage+Gradients.swift | 9 +++--- .../Extensions/UIImage/UIImage+Loading.swift | 26 ++++++------------ .../Extensions/UIImage/UIImage+Resize.swift | 4 +-- .../UIImage/UIImage+Transformations.swift | 14 +++++----- .../UIImageView+LoadingImage.swift | 5 ++-- 10 files changed, 57 insertions(+), 39 deletions(-) create mode 100644 LeadKit/LeadKit/Extensions/String/String+Localization.swift diff --git a/LeadKit/.DS_Store b/LeadKit/.DS_Store index 36540d453b4d9c36e0702f3ad79d5fc0e927cb19..4048ccc14543e5957360688839c9f0c6ddf2bee4 100644 GIT binary patch delta 38 ucmZoMXffE}z{n(VeDXR*waFQbJWQw5Ca+=Cm^_b>n_1|T+U7Nk5n=%GkPH<7 delta 38 ucmZoMXffE}z{tcaJ$W6Y+T;vI9;SWVlh-h6OrFQc%`Dhzzj+N~gctzWs|yMM diff --git a/LeadKit/LeadKit.xcodeproj/project.pbxproj b/LeadKit/LeadKit.xcodeproj/project.pbxproj index b1f336a7..fc5b240d 100644 --- a/LeadKit/LeadKit.xcodeproj/project.pbxproj +++ b/LeadKit/LeadKit.xcodeproj/project.pbxproj @@ -57,6 +57,7 @@ 95B39A7E1D9C069B0057BD54 /* UIImage+Text.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B39A7D1D9C069B0057BD54 /* UIImage+Text.swift */; }; 95B39A801D9C09440057BD54 /* UIImage+Cropping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B39A7F1D9C09440057BD54 /* UIImage+Cropping.swift */; }; 95B39A841D9C0C3E0057BD54 /* UIImage+Alpha.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B39A831D9C0C3E0057BD54 /* UIImage+Alpha.swift */; }; + 95B39A861D9D51250057BD54 /* String+Localization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95B39A851D9D51250057BD54 /* String+Localization.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -123,6 +124,7 @@ 95B39A7D1D9C069B0057BD54 /* UIImage+Text.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Text.swift"; sourceTree = ""; }; 95B39A7F1D9C09440057BD54 /* UIImage+Cropping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Cropping.swift"; sourceTree = ""; }; 95B39A831D9C0C3E0057BD54 /* UIImage+Alpha.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Alpha.swift"; sourceTree = ""; }; + 95B39A851D9D51250057BD54 /* String+Localization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Localization.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -216,6 +218,7 @@ isa = PBXGroup; children = ( 787783661CA04D4A001CDC9B /* String+SizeCalculation.swift */, + 95B39A851D9D51250057BD54 /* String+Localization.swift */, ); path = String; sourceTree = ""; @@ -575,6 +578,7 @@ 78C36F771D80117D00E7EBEA /* UIImage+Transformations.swift in Sources */, 786D78EA1D53C43E006B2CEA /* ApiError.swift in Sources */, 787A071A1D085750009EC97F /* CellsControllerProtocol.swift in Sources */, + 95B39A861D9D51250057BD54 /* String+Localization.swift in Sources */, 78C36F7E1D801E3E00E7EBEA /* Double+Rounding.swift in Sources */, 78CFEE551C5C45E500F50370 /* NibNameProtocol.swift in Sources */, 78CFEE561C5C45E500F50370 /* ReuseIdentifierProtocol.swift in Sources */, diff --git a/LeadKit/LeadKit/Extensions/String/String+Localization.swift b/LeadKit/LeadKit/Extensions/String/String+Localization.swift new file mode 100644 index 00000000..98c45e4d --- /dev/null +++ b/LeadKit/LeadKit/Extensions/String/String+Localization.swift @@ -0,0 +1,22 @@ +// +// String+Localization.swift +// LeadKit +// +// Created by Николай Ашанин on 29.09.16. +// Copyright © 2016 Touch Instinct. All rights reserved. +// + +import UIKit + +public extension String { + + /** + method returns localized string with default comment and self name + + - returns: localized string + */ + public func localized() -> String { + return NSLocalizedString(self, comment: "") + } + +} diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Alpha.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Alpha.swift index bb23247e..8f19bff8 100644 --- a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Alpha.swift +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Alpha.swift @@ -27,7 +27,7 @@ public extension UIImage { - returns: a copy of the given image, adding an alpha channel if it doesn't already have one. */ public func applyAlpha() -> UIImage? { - if hasAlpha() { + guard !hasAlpha() else { return self } diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Cropping.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Cropping.swift index 7b3ed8e5..e0d5a149 100644 --- a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Cropping.swift +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Cropping.swift @@ -32,11 +32,11 @@ public extension UIImage { - returns: cropped image */ public func cropToSquare() -> UIImage? { - let newSize = CGSize(width: size.width * scale, height: size.height * scale) - let shortest = min(newSize.width, newSize.height) - let left: CGFloat = newSize.width > shortest ? (newSize.width-shortest)/2 : 0 - let top: CGFloat = newSize.height > shortest ? (newSize.height-shortest)/2 : 0 - let rect = CGRect(x: 0, y: 0, width: size.width, height: newSize.height) + let scaledSize = CGSize(width: size.width * scale, height: size.height * scale) + let shortest = min(scaledSize.width, scaledSize.height) + let left: CGFloat = scaledSize.width > shortest ? (scaledSize.width-shortest)/2 : 0 + let top: CGFloat = scaledSize.height > shortest ? (scaledSize.height-shortest)/2 : 0 + let rect = CGRect(x: 0, y: 0, width: scaledSize.width, height: scaledSize.height) let insetRect = CGRectInset(rect, left, top) return crop(insetRect) } diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Gradients.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Gradients.swift index 09f15ec4..78c12d0e 100644 --- a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Gradients.swift +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Gradients.swift @@ -23,7 +23,8 @@ public extension UIImage { let colorSpace = CGColorSpaceCreateDeviceRGB() let colors = gradientColors.map {(color: UIColor) -> AnyObject? in return color.CGColor as AnyObject? } as NSArray let gradient = CGGradientCreateWithColors(colorSpace, colors, nil) - CGContextDrawLinearGradient(context, gradient, + CGContextDrawLinearGradient(context, + gradient, CGPoint(x: 0, y: 0), CGPoint(x: 0, y: size.height), CGGradientDrawingOptions(rawValue: 0)) @@ -79,12 +80,12 @@ public extension UIImage { public convenience init?(startColor: UIColor, endColor: UIColor, radialGradientCenter: CGPoint = CGPoint(x: 0.5, y: 0.5), - radius: Float = 0.5, + radius: CGFloat = 0.5, size: CGSize = CGSize(width: 100, height: 100)) { UIGraphicsBeginImageContextWithOptions(size, true, 0) let numLocations: Int = 2 - let locations: [CGFloat] = [0.0, 1.0] as [CGFloat] + let locations: [CGFloat] = [0.0, 1.0] let startComponents = CGColorGetComponents(startColor.CGColor) let endComponents = CGColorGetComponents(endColor.CGColor) @@ -104,7 +105,7 @@ public extension UIImage { // Normalize the 0-1 ranged inputs to the width of the image let aCenter = CGPoint(x: radialGradientCenter.x * size.width, y: radialGradientCenter.y * size.height) - let aRadius = CGFloat(min(size.width, size.height)) * CGFloat(radius) + let aRadius = (min(size.width, size.height)) * (radius) // Draw it CGContextDrawRadialGradient(UIGraphicsGetCurrentContext(), diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift index ef329849..6e54eb49 100644 --- a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift @@ -15,23 +15,13 @@ public enum UIImageContentMode { case ScaleToFill, ScaleAspectFit, ScaleAspectFill } -struct StaticSharedCache { - static var sharedCache: NSCache? = nil - static var onceToken: dispatch_once_t = 0 -} - public extension UIImage { /** a singleton shared NSURL cache used for images from URL - - - returns: shared image cache */ - private class func sharedCache() -> NSCache { - dispatch_once(&StaticSharedCache.onceToken) { - StaticSharedCache.sharedCache = NSCache() - } - return StaticSharedCache.sharedCache + static var sharedCache: NSCache = { + return NSCache() } // MARK: Image From URL @@ -39,23 +29,23 @@ public extension UIImage { /** creates a new image from a URL with optional caching. if cached, the cached image is returned. - otherwise, a place holder is used until the image from web is returned by the closure. + otherwise, a place holder is used until the image from web is returned by the fetchComplete. - parameter url: The image URL. - parameter placeholder: The placeholder image. - parameter shouldCacheImage: Weather or not we should cache the NSURL response (default: true) - - parameter closure: Returns the image from the web the first time is fetched. + - parameter fetchComplete: Returns the image from the web the first time is fetched. - returns: A new image */ public class func imageFromURL(url: String, placeholder: UIImage, shouldCacheImage: Bool = true, - closure: (image: UIImage?) -> ()) -> UIImage? { + fetchComplete: (image: UIImage?) -> ()) -> UIImage? { // From Cache if shouldCacheImage { if let image = UIImage.sharedCache().objectForKey(url) as? UIImage { - closure(image: nil) + fetchComplete(image: nil) return image } } @@ -65,7 +55,7 @@ public extension UIImage { session.dataTaskWithURL(nsURL, completionHandler: { (data, response, error) -> Void in if error != nil { dispatch_async(dispatch_get_main_queue()) { - closure(image: nil) + fetchComplete(image: nil) } } if let data = data, image = UIImage(data: data) { @@ -73,7 +63,7 @@ public extension UIImage { UIImage.sharedCache().setObject(image, forKey: url) } dispatch_async(dispatch_get_main_queue()) { - closure(image: image) + fetchComplete(image: image) } } session.finishTasksAndInvalidate() diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Resize.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Resize.swift index 1e9a2213..46fedd49 100644 --- a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Resize.swift +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Resize.swift @@ -38,8 +38,8 @@ public extension UIImage { */ public func resize(size: CGSize, contentMode: UIImageContentMode = .ScaleToFill) -> UIImage? { - let horizontalRatio = size.width/size.width - let verticalRatio = size.height/size.height + let horizontalRatio = size.width / size.width + let verticalRatio = size.height / size.height var ratio: CGFloat = 1 switch contentMode { diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Transformations.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Transformations.swift index e45964b6..4fa8864b 100644 --- a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Transformations.swift +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Transformations.swift @@ -58,13 +58,13 @@ public extension UIImage { CGContextSaveGState(context) CGContextTranslateCTM(context, rect.minX, rect.minY) CGContextScaleCTM(context, cornerRadius, cornerRadius) - let fw = rect.size.width / cornerRadius - let fh = rect.size.height / cornerRadius - CGContextMoveToPoint(context, fw, fh/2) - CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1) - CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1) - CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1) - CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1) + let roundedWidth = rect.size.width / cornerRadius + let roundedHeight = rect.size.height / cornerRadius + CGContextMoveToPoint(context, roundedWidth, roundedHeight/2) + CGContextAddArcToPoint(context, roundedWidth, roundedHeight, roundedWidth/2, roundedHeight, 1) + CGContextAddArcToPoint(context, 0, roundedHeight, 0, roundedHeight/2, 1) + CGContextAddArcToPoint(context, 0, 0, roundedWidth/2, 0, 1) + CGContextAddArcToPoint(context, roundedWidth, 0, roundedWidth, roundedHeight/2, 1) CGContextRestoreGState(context) } CGContextClosePath(context) diff --git a/LeadKit/LeadKit/Extensions/UIImageView/UIImageView+LoadingImage.swift b/LeadKit/LeadKit/Extensions/UIImageView/UIImageView+LoadingImage.swift index ab4d9dbb..4e1db836 100644 --- a/LeadKit/LeadKit/Extensions/UIImageView/UIImageView+LoadingImage.swift +++ b/LeadKit/LeadKit/Extensions/UIImageView/UIImageView+LoadingImage.swift @@ -31,12 +31,13 @@ public extension UIImageView { image = UIImage.imageFromURL(url, placeholder: placeholder, - shouldCacheImage: shouldCacheImage) { (uploadedImage: UIImage?) in + shouldCacheImage: shouldCacheImage) { [weak self] + (uploadedImage: UIImage?) in guard let image = uploadedImage else { return nil } - self.image = image + self?.image = image if fadeIn { let transition = CATransition() transition.duration = 0.5 From 02d35231acbf0d64d86fa44bfdc444d53354def5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B8=CC=86=20=D0=90?= =?UTF-8?q?=D1=88=D0=B0=D0=BD=D0=B8=D0=BD?= Date: Thu, 29 Sep 2016 17:56:46 +0300 Subject: [PATCH 3/5] cacheimage param naming fixed --- LeadKit/.DS_Store | Bin 6148 -> 6148 bytes .../Extensions/UIImage/UIImage+Loading.swift | 8 ++++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/LeadKit/.DS_Store b/LeadKit/.DS_Store index 4048ccc14543e5957360688839c9f0c6ddf2bee4..c6f0f0f96b79a6f70826ef7b6c3225c4e3479510 100644 GIT binary patch delta 18 ZcmZoMXffE}$jDeYc^#wL<_yL;VgNe+1_J;9 delta 18 ZcmZoMXffE}$jEqn@;XMf%^8ey!~i~823Y_A diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift index 6e54eb49..9d5cb82a 100644 --- a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift @@ -33,17 +33,17 @@ public extension UIImage { - parameter url: The image URL. - parameter placeholder: The placeholder image. - - parameter shouldCacheImage: Weather or not we should cache the NSURL response (default: true) + - parameter cacheImage: Weather or not we should cache the NSURL response (default: true) - parameter fetchComplete: Returns the image from the web the first time is fetched. - returns: A new image */ public class func imageFromURL(url: String, placeholder: UIImage, - shouldCacheImage: Bool = true, + cacheImage: Bool = true, fetchComplete: (image: UIImage?) -> ()) -> UIImage? { // From Cache - if shouldCacheImage { + if cacheImage { if let image = UIImage.sharedCache().objectForKey(url) as? UIImage { fetchComplete(image: nil) return image @@ -59,7 +59,7 @@ public extension UIImage { } } if let data = data, image = UIImage(data: data) { - if shouldCacheImage { + if cacheImage { UIImage.sharedCache().setObject(image, forKey: url) } dispatch_async(dispatch_get_main_queue()) { From 96c9ed1d528e89964cbd157d9dda91f5016a326d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B8=CC=86=20=D0=90?= =?UTF-8?q?=D1=88=D0=B0=D0=BD=D0=B8=D0=BD?= Date: Thu, 29 Sep 2016 18:03:33 +0300 Subject: [PATCH 4/5] cached image description fixed --- LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift index 9d5cb82a..a2956e56 100644 --- a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift @@ -28,7 +28,7 @@ public extension UIImage { /** creates a new image from a URL with optional caching. - if cached, the cached image is returned. + if using cache, the cached image is returned. otherwise, a place holder is used until the image from web is returned by the fetchComplete. - parameter url: The image URL. From df79bfdb6fdf6c2bda245d2ce898c4ad9f0f93ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=BE=D0=BB=D0=B0=D0=B8=CC=86=20=D0=90?= =?UTF-8?q?=D1=88=D0=B0=D0=BD=D0=B8=D0=BD?= Date: Thu, 29 Sep 2016 18:06:23 +0300 Subject: [PATCH 5/5] condition error fixed --- LeadKit/.DS_Store | Bin 6148 -> 6148 bytes .../Extensions/UIImage/UIImage+Loading.swift | 3 +-- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/LeadKit/.DS_Store b/LeadKit/.DS_Store index c6f0f0f96b79a6f70826ef7b6c3225c4e3479510..2b1134c490d637d4b0ad82f01b53c74f22a44be1 100644 GIT binary patch delta 18 ZcmZoMXffE}$jG>O@;XMf%^8ey!~i_<1~mWx delta 18 ZcmZoMXffE}$jDeYc^#wL<_yL;VgNe+1_J;9 diff --git a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift index a2956e56..31751cf0 100644 --- a/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift +++ b/LeadKit/LeadKit/Extensions/UIImage/UIImage+Loading.swift @@ -57,8 +57,7 @@ public extension UIImage { dispatch_async(dispatch_get_main_queue()) { fetchComplete(image: nil) } - } - if let data = data, image = UIImage(data: data) { + } else if let data = data, image = UIImage(data: data) { if cacheImage { UIImage.sharedCache().setObject(image, forKey: url) }