Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge https://github.com/mruegenberg/objc-utils

  • Loading branch information...
commit e5b4fbd3eff1819d6794cb8f708eeda757a5b0c6 2 parents 2a11f52 + 121461b
Yevhene Shemet authored
View
14 UIKitAdditions/UIImage+Additions.h
@@ -22,3 +22,17 @@
*/
- (UIImage *)horizontallyStretchedImage;
@end
+
+// UIImage+Alpha.h
+// Created by Trevor Harmon on 9/20/09.
+// Free for personal or commercial use, with or without modification.
+// No warranty is expressed or implied.
+
+// Helper methods for adding an alpha layer to an image
+@interface UIImage (Alpha)
+
+- (BOOL)hasAlpha;
+- (UIImage *)imageWithAlpha;
+- (UIImage *)transparentBorderImage: (NSUInteger)borderSize;
+
+@end
View
129 UIKitAdditions/UIImage+Additions.m
@@ -50,4 +50,133 @@ @implementation UIImage (Additions)
- (UIImage *)horizontallyStretchedImage {
return [self stretchableImageWithLeftCapWidth:((self.size.width - 1) / 2.0) topCapHeight:0];
}
+
+@end
+
+
+// UIImage+Alpha.m
+// Created by Trevor Harmon on 9/20/09.
+// Free for personal or commercial use, with or without modification.
+// No warranty is expressed or implied.
+
+// Private helper methods
+@interface UIImage ()
+- (CGImageRef)newBorderMask:(NSUInteger)borderSize size:(CGSize)size;
+@end
+
+
+@implementation UIImage (Alpha)
+
+// Returns true if the image has an alpha layer
+- (BOOL)hasAlpha {
+ CGImageAlphaInfo alpha = CGImageGetAlphaInfo(self.CGImage);
+ return (alpha == kCGImageAlphaFirst ||
+ alpha == kCGImageAlphaLast ||
+ alpha == kCGImageAlphaPremultipliedFirst ||
+ alpha == kCGImageAlphaPremultipliedLast);
+}
+
+// Returns a copy of the given image, adding an alpha channel if it doesn't already have one
+- (UIImage *)imageWithAlpha {
+ if ([self hasAlpha]) {
+ return self;
+ }
+
+ CGImageRef imageRef = self.CGImage;
+ size_t width = CGImageGetWidth(imageRef);
+ size_t height = CGImageGetHeight(imageRef);
+
+ // The bitsPerComponent and bitmapInfo values are hard-coded to prevent an "unsupported parameter combination" error
+ CGContextRef offscreenContext = CGBitmapContextCreate(NULL,
+ width,
+ height,
+ 8,
+ 0,
+ CGImageGetColorSpace(imageRef),
+ kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);
+
+ // Draw the image into the context and retrieve the new image, which will now have an alpha layer
+ CGContextDrawImage(offscreenContext, CGRectMake(0, 0, width, height), imageRef);
+ CGImageRef imageRefWithAlpha = CGBitmapContextCreateImage(offscreenContext);
+ UIImage *imageWithAlpha = [UIImage imageWithCGImage:imageRefWithAlpha];
+
+ // Clean up
+ CGContextRelease(offscreenContext);
+ CGImageRelease(imageRefWithAlpha);
+
+ return imageWithAlpha;
+}
+
+// Returns a copy of the image with a transparent border of the given size added around its edges.
+// If the image has no alpha layer, one will be added to it.
+- (UIImage *)transparentBorderImage:(NSUInteger)borderSize {
+ // If the image does not have an alpha layer, add one
+ UIImage *image = [self imageWithAlpha];
+
+ CGRect newRect = CGRectMake(0, 0, image.size.width + borderSize * 2, image.size.height + borderSize * 2);
+
+ // Build a context that's the same dimensions as the new size
+ CGContextRef bitmap = CGBitmapContextCreate(NULL,
+ newRect.size.width,
+ newRect.size.height,
+ CGImageGetBitsPerComponent(self.CGImage),
+ 0,
+ CGImageGetColorSpace(self.CGImage),
+ CGImageGetBitmapInfo(self.CGImage));
+
+ // Draw the image in the center of the context, leaving a gap around the edges
+ CGRect imageLocation = CGRectMake(borderSize, borderSize, image.size.width, image.size.height);
+ CGContextDrawImage(bitmap, imageLocation, self.CGImage);
+ CGImageRef borderImageRef = CGBitmapContextCreateImage(bitmap);
+
+ // Create a mask to make the border transparent, and combine it with the image
+ CGImageRef maskImageRef = [self newBorderMask:borderSize size:newRect.size];
+ CGImageRef transparentBorderImageRef = CGImageCreateWithMask(borderImageRef, maskImageRef);
+ UIImage *transparentBorderImage = [UIImage imageWithCGImage:transparentBorderImageRef];
+
+ // Clean up
+ CGContextRelease(bitmap);
+ CGImageRelease(borderImageRef);
+ CGImageRelease(maskImageRef);
+ CGImageRelease(transparentBorderImageRef);
+
+ return transparentBorderImage;
+}
+
+#pragma mark -
+#pragma mark Private helper methods
+
+// Creates a mask that makes the outer edges transparent and everything else opaque
+// The size must include the entire mask (opaque part + transparent border)
+// The caller is responsible for releasing the returned reference by calling CGImageRelease
+- (CGImageRef)newBorderMask:(NSUInteger)borderSize size:(CGSize)size {
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
+
+ // Build a context that's the same dimensions as the new size
+ CGContextRef maskContext = CGBitmapContextCreate(NULL,
+ size.width,
+ size.height,
+ 8, // 8-bit grayscale
+ 0,
+ colorSpace,
+ kCGBitmapByteOrderDefault | kCGImageAlphaNone);
+
+ // Start with a mask that's entirely transparent
+ CGContextSetFillColorWithColor(maskContext, [UIColor blackColor].CGColor);
+ CGContextFillRect(maskContext, CGRectMake(0, 0, size.width, size.height));
+
+ // Make the inner part (within the border) opaque
+ CGContextSetFillColorWithColor(maskContext, [UIColor whiteColor].CGColor);
+ CGContextFillRect(maskContext, CGRectMake(borderSize, borderSize, size.width - borderSize * 2, size.height - borderSize * 2));
+
+ // Get an image of the context
+ CGImageRef maskImageRef = CGBitmapContextCreateImage(maskContext);
+
+ // Clean up
+ CGContextRelease(maskContext);
+ CGColorSpaceRelease(colorSpace);
+
+ return maskImageRef;
+}
+
@end
View
18 UIKitAdditions/UIImage+Alpha.h
@@ -1,18 +0,0 @@
-// UIImage+Alpha.h
-// Created by Trevor Harmon on 9/20/09.
-// Free for personal or commercial use, with or without modification.
-// No warranty is expressed or implied.
-
-#import <UIKit/UIKit.h>
-
-
-// Helper methods for adding an alpha layer to an image
-@interface UIImage (Alpha)
-
-- (BOOL)hasAlpha;
-
-- (UIImage *)imageWithAlpha;
-
-- (UIImage *)transparentBorderImage: (NSUInteger)borderSize;
-
-@end
View
127 UIKitAdditions/UIImage+Alpha.m
@@ -1,127 +0,0 @@
-// UIImage+Alpha.m
-// Created by Trevor Harmon on 9/20/09.
-// Free for personal or commercial use, with or without modification.
-// No warranty is expressed or implied.
-
-#import "UIImage+Alpha.h"
-
-// Private helper methods
-@interface UIImage ()
-- (CGImageRef)newBorderMask:(NSUInteger)borderSize size:(CGSize)size;
-@end
-
-@implementation UIImage (Alpha)
-
-// Returns true if the image has an alpha layer
-- (BOOL)hasAlpha {
- CGImageAlphaInfo alpha = CGImageGetAlphaInfo(self.CGImage);
- return (alpha == kCGImageAlphaFirst ||
- alpha == kCGImageAlphaLast ||
- alpha == kCGImageAlphaPremultipliedFirst ||
- alpha == kCGImageAlphaPremultipliedLast);
-}
-
-// Returns a copy of the given image, adding an alpha channel if it doesn't already have one
-- (UIImage *)imageWithAlpha {
- if ([self hasAlpha]) {
- return self;
- }
-
- CGImageRef imageRef = self.CGImage;
- size_t width = CGImageGetWidth(imageRef);
- size_t height = CGImageGetHeight(imageRef);
-
- // The bitsPerComponent and bitmapInfo values are hard-coded to prevent an "unsupported parameter combination" error
- CGContextRef offscreenContext = CGBitmapContextCreate(NULL,
- width,
- height,
- 8,
- 0,
- CGImageGetColorSpace(imageRef),
- kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);
-
- // Draw the image into the context and retrieve the new image, which will now have an alpha layer
- CGContextDrawImage(offscreenContext, CGRectMake(0, 0, width, height), imageRef);
- CGImageRef imageRefWithAlpha = CGBitmapContextCreateImage(offscreenContext);
- UIImage *imageWithAlpha = [UIImage imageWithCGImage:imageRefWithAlpha];
-
- // Clean up
- CGContextRelease(offscreenContext);
- CGImageRelease(imageRefWithAlpha);
-
- return imageWithAlpha;
-}
-
-// Returns a copy of the image with a transparent border of the given size added around its edges.
-// If the image has no alpha layer, one will be added to it.
-- (UIImage *)transparentBorderImage:(NSUInteger)borderSize {
- // If the image does not have an alpha layer, add one
- UIImage *image = [self imageWithAlpha];
-
- CGRect newRect = CGRectMake(0, 0, image.size.width + borderSize * 2, image.size.height + borderSize * 2);
-
- // Build a context that's the same dimensions as the new size
- CGContextRef bitmap = CGBitmapContextCreate(NULL,
- newRect.size.width,
- newRect.size.height,
- CGImageGetBitsPerComponent(self.CGImage),
- 0,
- CGImageGetColorSpace(self.CGImage),
- CGImageGetBitmapInfo(self.CGImage));
-
- // Draw the image in the center of the context, leaving a gap around the edges
- CGRect imageLocation = CGRectMake(borderSize, borderSize, image.size.width, image.size.height);
- CGContextDrawImage(bitmap, imageLocation, self.CGImage);
- CGImageRef borderImageRef = CGBitmapContextCreateImage(bitmap);
-
- // Create a mask to make the border transparent, and combine it with the image
- CGImageRef maskImageRef = [self newBorderMask:borderSize size:newRect.size];
- CGImageRef transparentBorderImageRef = CGImageCreateWithMask(borderImageRef, maskImageRef);
- UIImage *transparentBorderImage = [UIImage imageWithCGImage:transparentBorderImageRef];
-
- // Clean up
- CGContextRelease(bitmap);
- CGImageRelease(borderImageRef);
- CGImageRelease(maskImageRef);
- CGImageRelease(transparentBorderImageRef);
-
- return transparentBorderImage;
-}
-
-#pragma mark -
-#pragma mark Private helper methods
-
-// Creates a mask that makes the outer edges transparent and everything else opaque
-// The size must include the entire mask (opaque part + transparent border)
-// The caller is responsible for releasing the returned reference by calling CGImageRelease
-- (CGImageRef)newBorderMask:(NSUInteger)borderSize size:(CGSize)size {
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
-
- // Build a context that's the same dimensions as the new size
- CGContextRef maskContext = CGBitmapContextCreate(NULL,
- size.width,
- size.height,
- 8, // 8-bit grayscale
- 0,
- colorSpace,
- kCGBitmapByteOrderDefault | kCGImageAlphaNone);
-
- // Start with a mask that's entirely transparent
- CGContextSetFillColorWithColor(maskContext, [UIColor blackColor].CGColor);
- CGContextFillRect(maskContext, CGRectMake(0, 0, size.width, size.height));
-
- // Make the inner part (within the border) opaque
- CGContextSetFillColorWithColor(maskContext, [UIColor whiteColor].CGColor);
- CGContextFillRect(maskContext, CGRectMake(borderSize, borderSize, size.width - borderSize * 2, size.height - borderSize * 2));
-
- // Get an image of the context
- CGImageRef maskImageRef = CGBitmapContextCreateImage(maskContext);
-
- // Clean up
- CGContextRelease(maskContext);
- CGColorSpaceRelease(colorSpace);
-
- return maskImageRef;
-}
-
-@end
View
2  UIKitAdditions/UIImage+Resize.m
@@ -5,7 +5,7 @@
#import "UIImage+Resize.h"
#import "UIImage+RoundedCorner.h"
-#import "UIImage+Alpha.h"
+#import "UIImage+Additions.h"
// Private helper methods
@interface UIImage ()
View
39 UIKitAdditions/UIImage+RoundedCorner.m
@@ -4,12 +4,9 @@
// No warranty is expressed or implied.
#import "UIImage+RoundedCorner.h"
-#import "UIImage+Alpha.h"
+#import "UIImage+Additions.h"
+#import "UIKit+DrawingHelpers.h"
-// Private helper methods
-@interface UIImage ()
-- (void)addRoundedRectToPath:(CGRect)rect context:(CGContextRef)context ovalWidth:(CGFloat)ovalWidth ovalHeight:(CGFloat)ovalHeight;
-@end
@implementation UIImage (RoundedCorner)
@@ -30,13 +27,7 @@ - (UIImage *)roundedCornerImage:(NSInteger)cornerSize borderSize:(NSInteger)bord
CGImageGetBitmapInfo(image.CGImage));
// Create a clipping path with rounded corners
- CGContextBeginPath(context);
- [self addRoundedRectToPath:CGRectMake(borderSize, borderSize, image.size.width - borderSize * 2, image.size.height - borderSize * 2)
- context:context
- ovalWidth:cornerSize
- ovalHeight:cornerSize];
- CGContextClosePath(context);
- CGContextClip(context);
+ CGContextClipToRoundedRect(context, CGRectMake(borderSize, borderSize, image.size.width, image.size.height), cornerSize);
// Draw the image to the context; the clipping path will make anything outside the rounded rect transparent
CGContextDrawImage(context, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage);
@@ -52,28 +43,4 @@ - (UIImage *)roundedCornerImage:(NSInteger)cornerSize borderSize:(NSInteger)bord
return roundedImage;
}
-#pragma mark -
-#pragma mark Private helper methods
-
-// Adds a rectangular path to the given context and rounds its corners by the given extents
-// Original author: Björn Sållarp. Used with permission. See: http://blog.sallarp.com/iphone-uiimage-round-corners/
-- (void)addRoundedRectToPath:(CGRect)rect context:(CGContextRef)context ovalWidth:(CGFloat)ovalWidth ovalHeight:(CGFloat)ovalHeight {
- if (ovalWidth == 0 || ovalHeight == 0) {
- CGContextAddRect(context, rect);
- return;
- }
- CGContextSaveGState(context);
- CGContextTranslateCTM(context, CGRectGetMinX(rect), CGRectGetMinY(rect));
- CGContextScaleCTM(context, ovalWidth, ovalHeight);
- CGFloat fw = CGRectGetWidth(rect) / ovalWidth;
- CGFloat fh = CGRectGetHeight(rect) / ovalHeight;
- 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);
- CGContextClosePath(context);
- CGContextRestoreGState(context);
-}
-
@end
View
60 UIKitAdditions/UIKit+DrawingHelpers.h
@@ -0,0 +1,60 @@
+//
+// DrawingHelpers.h
+//
+//
+// Created by Marcel Ruegenberg on 21.09.09.
+// Copyright 2009 Dustlab. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+
+/**
+ Add a rounded rectangle to the current CGContext.
+ @param c the CGContext
+ @param rect the rectangle to which the rounded rectangle corresponds
+ @param radius the radius of the arcs of the rectangle corners
+ */
+void CGContextAddRoundedRect(CGContextRef c, CGRect rect, CGFloat radius);
+
+/**
+ Stroke a rounded rectangle in a CGContext.
+ */
+void CGContextStrokeRoundedRect(CGContextRef c, CGRect rect, CGFloat radius);
+
+/**
+ Fill a rounded rectangle in a CGContext.
+ */
+void CGContextFillRoundedRect(CGContextRef c, CGRect rect, CGFloat radius);
+
+/**
+ Clip a CGContext to a rounded rectangle.
+ */
+void CGContextClipToRoundedRect(CGContextRef c, CGRect rect, CGFloat radius);
+
+
+/**
+ Draw a linear gradient with a number of colors.
+ This function is very similar to CGGradientCreateWithColors, but immediately draws the gradient and keeps us from having to worry about color spaces.
+
+ Please note that the supplied UIColors in the array must be RGB colors.
+ */
+void DL_CGContextDrawLinearGradient(CGContextRef context, NSArray *colors, const CGFloat locations[], CGPoint startPoint, CGPoint endPoint);
+
+/**
+ Draw a linear gradient from top to bottom of a supplied rectangle.
+ */
+void DL_CGContextDrawLinearGradientOverRect(CGContextRef context, NSArray *colors, const CGFloat locations[], CGRect rect);
+
+/**
+ Draw the typical steel gradient.
+ */
+void DL_CGContextDrawSteelGradientOverRect(CGContextRef context, CGRect rect);
+
+#define DISCLOSURE_IND_SIZE 6
+/**
+ Draw a disclosure indicator
+ @param upLeft The upper left corner of the disclosure indicator.
+ */
+void DL_CGContextDrawDisclosureIndicatorAtPoint(CGContextRef context, CGPoint upLeft);
+
View
83 UIKitAdditions/UIKit+DrawingHelpers.m
@@ -0,0 +1,83 @@
+//
+// DrawingHelpers.m
+// Planner
+//
+// Created by Marcel Ruegenberg on 21.09.09.
+// Copyright 2009 Dustlab. All rights reserved.
+//
+
+#import "UIKit+DrawingHelpers.h"
+
+
+void CGContextAddRoundedRect(CGContextRef c, CGRect rect, CGFloat radius) {
+ if(2 * radius > rect.size.height) radius = rect.size.height / 2.0;
+ if(2 * radius > rect.size.width) radius = rect.size.width / 2.0;
+ CGContextAddArc(c, rect.origin.x + radius, rect.origin.y + radius, radius, M_PI, M_PI * 1.5, 0);
+ CGContextAddArc(c, rect.origin.x + rect.size.width - radius, rect.origin.y + radius, radius, M_PI * 1.5, M_PI * 2, 0);
+ CGContextAddArc(c, rect.origin.x + rect.size.width - radius, rect.origin.y + rect.size.height - radius, radius, M_PI * 2, M_PI * 0.5, 0);
+ CGContextAddArc(c, rect.origin.x + radius, rect.origin.y + rect.size.height - radius, radius, M_PI * 0.5, M_PI, 0);
+ CGContextAddLineToPoint(c, rect.origin.x, rect.origin.y + radius);
+}
+
+void CGContextStrokeRoundedRect(CGContextRef c, CGRect rect, CGFloat radius) {
+ CGContextBeginPath(c);
+ CGContextAddRoundedRect(c, rect, radius);
+ CGContextStrokePath(c);
+}
+
+void CGContextFillRoundedRect(CGContextRef c, CGRect rect, CGFloat radius) {
+ CGContextBeginPath(c);
+ CGContextAddRoundedRect(c, rect, radius);
+ CGContextFillPath(c);
+}
+
+void CGContextClipToRoundedRect(CGContextRef c, CGRect rect, CGFloat radius) {
+ CGContextBeginPath(c);
+ CGContextAddRoundedRect(c, rect, radius);
+ CGContextClip(c);
+}
+
+
+
+void DL_CGContextDrawLinearGradient(CGContextRef context, NSArray *colors, const CGFloat locations[], CGPoint startPoint, CGPoint endPoint) {
+ CGColorSpaceRef myColorspace = CGColorSpaceCreateDeviceRGB();
+ NSMutableArray *arr = [NSMutableArray arrayWithCapacity:[colors count]];
+ for(UIColor *c in colors) { [arr addObject:(id)[c CGColor]]; }
+ CGGradientRef gradient = CGGradientCreateWithColors(myColorspace, (CFArrayRef)arr, locations);
+
+ CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
+
+ CGGradientRelease(gradient);
+ CGColorSpaceRelease(myColorspace);
+}
+
+void DL_CGContextDrawLinearGradientOverRect(CGContextRef context, NSArray *colors, const CGFloat locations[], CGRect rect) {
+ DL_CGContextDrawLinearGradient(context, colors, locations, rect.origin, CGPointMake(rect.origin.x, rect.origin.y + rect.size.height));
+}
+
+void DL_CGContextDrawSteelGradientOverRect(CGContextRef context, CGRect rect) {
+ CGFloat locations[4] = { 0.0, 0.015, 0.985, 1.0 };
+ DL_CGContextDrawLinearGradientOverRect(context,
+ [NSArray arrayWithObjects:
+ [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0],
+ [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.0],
+ [UIColor colorWithRed:0.7 green:0.7 blue:0.7 alpha:1.0],
+ [UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:1.0],nil],
+ locations, rect);
+}
+
+void DL_CGContextDrawDisclosureIndicatorAtPoint(CGContextRef context, CGPoint p) {
+ CGContextSetLineWidth(context, 3);
+ [[UIColor blackColor] set];
+ CGContextSetAlpha(context, 0.66);
+ p.x += 0.5; p.y += 0.5;
+ CGContextMoveToPoint(context, p.x, p.y);
+ p.x += DISCLOSURE_IND_SIZE;
+ p.y += DISCLOSURE_IND_SIZE;
+ CGContextAddLineToPoint(context, p.x, p.y);
+ p.x -= DISCLOSURE_IND_SIZE;
+ p.y += DISCLOSURE_IND_SIZE;
+ CGContextAddLineToPoint(context, p.x, p.y);
+ CGContextStrokePath(context);
+ CGContextSetAlpha(context, 1.0);
+}
Please sign in to comment.
Something went wrong with that request. Please try again.