Skip to content

Commit

Permalink
Version 0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
soffes committed Jun 30, 2013
1 parent 9f89382 commit 142b67d
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 51 deletions.
9 changes: 4 additions & 5 deletions Example/Classes/SAMDemoViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ - (void)viewDidLoad {
self.title = @"Gradient View";

SAMGradientView *gradientView = [[SAMGradientView alloc] initWithFrame:CGRectMake(20.0f, 20.0f, 280.0f, 280.0f)];
gradientView.backgroundColor = [UIColor lightGrayColor];
gradientView.topBorderColor = [UIColor redColor];
gradientView.bottomBorderColor = [UIColor blueColor];
gradientView.gradientColors = @[[UIColor greenColor], [UIColor yellowColor]];
gradientView.gradientLocations = @[@0.8, @1.0];
gradientView.gradientColors = @[
[UIColor colorWithRed:0.0f green:0.0f blue:1.0f alpha:1.0f],
[UIColor colorWithRed:0.0f green:0.0f blue:0.5f alpha:1.0f]
];
[self.view addSubview:gradientView];
}

Expand Down
40 changes: 40 additions & 0 deletions Readme.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# SAMGradientView

Easily use gradients in UIKit. SAMGradientView is a simple UIView wrapper around CGGradient.

SAMGradientView is tested on iOS 6 and requires ARC. Released under the [MIT license](LICENSE).

## Example

![Screenshot](http://soff.me/PzUc/iOS%20Simulator%20Screen%20shot%20Jun%2030,%202013%205.30.40%20PM.png)

Open up the included Xcode project for an example app and the tests.

## Usage

``` objc
// Initialize a gradient view
SAMGradientView *gradientView = [[SAMGradientView alloc] initWithFrame:CGRectMake(20.0f, 20.0f, 280.0f, 280.0f)];

// Set the gradient colors
gradientView.gradientColors = @[[UIColor greenColor], [UIColor yellowColor]];

// Optionally set some locations
gradientView.gradientLocations = @[@0.8, @1.0];

// Optionally change the direction. The default is vertical.
gradientView.gradientDirection = SAMGradientViewDirectionHorizontal;

// Add some borders too if you want
gradientView.topBorderColor = [UIColor redColor];
gradientView.bottomBorderColor = [UIColor blueColor];

// Add it as a subview in all of its awesome
[self.view addSubview:gradientView];
```
See the [header](SAMGradientView/SAMGradientView.h) for full documentation.
## Installation
Simply add the files in the `SAMGradientView.h` and `SAMGradientView.m` to your project or add `SAMGradientView` to your Podfile if you're using CocoaPods.
14 changes: 14 additions & 0 deletions SAMGradientView.podspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Pod::Spec.new do |s|
s.name = 'SAMGradientView'
s.version = '0.1.0'
s.authors = {'Sam Soffes' => '[email protected]'}
s.homepage = 'https://github.com/soffes/SAMGradientView'
s.summary = 'Easily use gradients in UIKit.'
s.source = {:git => 'https://github.com/soffes/SAMGradientView.git', :tag => 'v0.1.0'}
s.license = { :type => 'MIT', :file => 'LICENSE' }

s.platform = :ios
s.requires_arc = true
s.frameworks = 'UIKit', 'CoreGraphics'
s.source_files = 'SAMGradientView'
end
8 changes: 8 additions & 0 deletions SAMGradientView.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
objects = {

/* Begin PBXBuildFile section */
2149F1B81780C7E20083349D /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2149F1B71780C7E20083349D /* QuartzCore.framework */; };
2149F1BD1780CACC0083349D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21845E2E177E6E4C0002AA46 /* CoreGraphics.framework */; };
21845E2B177E6E4C0002AA46 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21845E2A177E6E4C0002AA46 /* UIKit.framework */; };
21845E2D177E6E4C0002AA46 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21845E2C177E6E4C0002AA46 /* Foundation.framework */; };
21845E2F177E6E4C0002AA46 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21845E2E177E6E4C0002AA46 /* CoreGraphics.framework */; };
Expand Down Expand Up @@ -34,6 +36,7 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
2149F1B71780C7E20083349D /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
21845E27177E6E4C0002AA46 /* SAMGradientView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SAMGradientView.app; sourceTree = BUILT_PRODUCTS_DIR; };
21845E2A177E6E4C0002AA46 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
21845E2C177E6E4C0002AA46 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -72,6 +75,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
2149F1BD1780CACC0083349D /* CoreGraphics.framework in Frameworks */,
2149F1B81780C7E20083349D /* QuartzCore.framework in Frameworks */,
21845E49177E6E4C0002AA46 /* SenTestingKit.framework in Frameworks */,
21845E4A177E6E4C0002AA46 /* UIKit.framework in Frameworks */,
21845E4B177E6E4C0002AA46 /* Foundation.framework in Frameworks */,
Expand Down Expand Up @@ -106,6 +111,7 @@
21845E29177E6E4C0002AA46 /* Frameworks */ = {
isa = PBXGroup;
children = (
2149F1B71780C7E20083349D /* QuartzCore.framework */,
21845E2A177E6E4C0002AA46 /* UIKit.framework */,
21845E2C177E6E4C0002AA46 /* Foundation.framework */,
21845E2E177E6E4C0002AA46 /* CoreGraphics.framework */,
Expand Down Expand Up @@ -365,6 +371,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Example/Other Sources/SAMGradientView-Prefix.pch";
INFOPLIST_FILE = "Example/Resources/SAMGradientView-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
Expand All @@ -376,6 +383,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Example/Other Sources/SAMGradientView-Prefix.pch";
INFOPLIST_FILE = "Example/Resources/SAMGradientView-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
Expand Down
2 changes: 1 addition & 1 deletion SAMGradientView/SAMGradientView.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ typedef NS_ENUM(NSUInteger, SAMGradientViewDirection) {
The default is `SSGradientViewDirectionVertical`.
*/
@property (nonatomic, assign) SAMGradientViewDirection direction;
@property (nonatomic, assign) SAMGradientViewDirection gradientDirection;


///--------------------------
Expand Down
72 changes: 40 additions & 32 deletions SAMGradientView/SAMGradientView.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,24 @@

#import "SAMGradientView.h"

@implementation SAMGradientView {
CGGradientRef _gradient;
}
@interface SAMGradientView ()
@property (nonatomic, assign) CGGradientRef gradient;
@end

@implementation SAMGradientView

#pragma mark - Accessors

- (void)setGradient:(CGGradientRef)gradient {
if (_gradient) {
CGGradientRelease(_gradient);
}

_gradient = gradient;
[self setNeedsDisplay];
}


- (void)setGradientColors:(NSArray *)colors {
_gradientColors = colors;
[self refreshGradient];
Expand All @@ -26,8 +38,8 @@ - (void)setGradientLocations:(NSArray *)locations {
}


- (void)setDirection:(SAMGradientViewDirection)direction {
_direction = direction;
- (void)setGradientDirection:(SAMGradientViewDirection)direction {
_gradientDirection = direction;
[self setNeedsDisplay];
}

Expand Down Expand Up @@ -113,72 +125,72 @@ - (void)drawRect:(CGRect)rect {
CGFloat const borderWidth = 1.0f;

// Gradient
if (_gradient) {
if (self.gradient) {
CGPoint start = CGPointMake(0.0f, 0.0f);
CGPoint end = (_direction == SAMGradientViewDirectionVertical ? CGPointMake(0.0f, size.height) :
CGPoint end = (self.gradientDirection == SAMGradientViewDirectionVertical ? CGPointMake(0.0f, size.height) :
CGPointMake(size.width, 0.0f));
CGContextDrawLinearGradient(context, _gradient, start, end, kNilOptions);
CGContextDrawLinearGradient(context, self.gradient, start, end, kNilOptions);
}

// Top
if (_topBorderColor) {
if (self.topBorderColor) {
// Top border
CGContextSetFillColorWithColor(context, _topBorderColor.CGColor);
CGContextSetFillColorWithColor(context, self.topBorderColor.CGColor);
CGContextFillRect(context, CGRectMake(0.0f, 0.0f, size.width, borderWidth));

// Top inset
if (_topInsetColor) {
CGContextSetFillColorWithColor(context, _topInsetColor.CGColor);
if (self.topInsetColor) {
CGContextSetFillColorWithColor(context, self.topInsetColor.CGColor);
CGContextFillRect(context, CGRectMake(0.0f, borderWidth, size.width, borderWidth));
}
}

CGFloat sideY = _topBorderColor ? 1.0f : 0.0f;
CGFloat sideY = self.topBorderColor ? 1.0f : 0.0f;
CGFloat sideHeight = size.height;
if (_topBorderColor) {
if (self.topBorderColor) {
sideHeight -= 1.0f;
}

if (_bottomBorderColor) {
if (self.bottomBorderColor) {
sideHeight -= 1.0f;
}

// Right
if (_rightBorderColor) {
if (self.rightBorderColor) {
// Right inset
if (_rightInsetColor) {
CGContextSetFillColorWithColor(context, _rightInsetColor.CGColor);
if (self.rightInsetColor) {
CGContextSetFillColorWithColor(context, self.rightInsetColor.CGColor);
CGContextFillRect(context, CGRectMake(size.width - borderWidth - borderWidth, sideY, borderWidth, sideHeight));
}

// Right border
CGContextSetFillColorWithColor(context, _rightBorderColor.CGColor);
CGContextSetFillColorWithColor(context, self.rightBorderColor.CGColor);
CGContextFillRect(context, CGRectMake(size.width - borderWidth, sideY, borderWidth, sideHeight));
}

// Bottom
if (_bottomBorderColor) {
if (self.bottomBorderColor) {
// Bottom inset
if (_bottomInsetColor) {
CGContextSetFillColorWithColor(context, _bottomInsetColor.CGColor);
if (self.bottomInsetColor) {
CGContextSetFillColorWithColor(context, self.bottomInsetColor.CGColor);
CGContextFillRect(context, CGRectMake(0.0f, rect.size.height - borderWidth - borderWidth, size.width, borderWidth));
}

// Bottom border
CGContextSetFillColorWithColor(context, _bottomBorderColor.CGColor);
CGContextSetFillColorWithColor(context, self.bottomBorderColor.CGColor);
CGContextFillRect(context, CGRectMake(0.0f, rect.size.height - borderWidth, size.width, borderWidth));
}

// Left
if (_leftBorderColor) {
if (self.leftBorderColor) {
// Left inset
if (_leftInsetColor) {
CGContextSetFillColorWithColor(context, _leftInsetColor.CGColor);
if (self.leftInsetColor) {
CGContextSetFillColorWithColor(context, self.leftInsetColor.CGColor);
CGContextFillRect(context, CGRectMake(borderWidth, sideY, borderWidth, sideHeight));
}

// Left border
CGContextSetFillColorWithColor(context, _leftBorderColor.CGColor);
CGContextSetFillColorWithColor(context, self.leftBorderColor.CGColor);
CGContextFillRect(context, CGRectMake(0.0f, sideY, borderWidth, sideHeight));
}
}
Expand All @@ -192,11 +204,7 @@ - (void)initialize {


- (void)refreshGradient {
CGGradientRelease(_gradient);
_gradient = SAMGradientCreateWithColorsAndLocations(_gradientColors, _gradientLocations);

// Redraw
[self setNeedsDisplay];
self.gradient = SAMGradientCreateWithColorsAndLocations(self.gradientColors, self.gradientLocations);
}

@end
Expand Down
5 changes: 5 additions & 0 deletions Tests/SAMGradientViewTests.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
//

#import <SenTestingKit/SenTestingKit.h>
#import <UIKit/UIKit.h>
#import <CoreGraphics/CoreGraphics.h>
#import "SAMGradientView.h"

@interface SAMGradientViewTests : SenTestCase

@property (nonatomic, strong) SAMGradientView *gradientView;

@end
77 changes: 64 additions & 13 deletions Tests/SAMGradientViewTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,77 @@
//

#import "SAMGradientViewTests.h"
#import <QuartzCore/QuartzCore.h>

@implementation SAMGradientViewTests

- (void)setUp
{
[super setUp];

// Set-up code here.
- (void)setUp {
[super setUp];
self.gradientView = [[SAMGradientView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 10.0f, 10.0f)];
self.gradientView.backgroundColor = [UIColor blueColor];
}

- (void)tearDown
{
// Tear-down code here.

[super tearDown];

- (void)testTopInset {
self.gradientView.topInsetColor = [UIColor redColor];
STAssertEqualObjects(self.gradientView.backgroundColor, [self colorAtPoint:CGPointMake(0.0f, 1.0f)], nil);

self.gradientView.topBorderColor = [UIColor greenColor];
STAssertEqualObjects(self.gradientView.topInsetColor, [self colorAtPoint:CGPointMake(0.0f, 1.0f)], nil);
}


- (void)testRightBorder {
self.gradientView.rightBorderColor = [UIColor redColor];
STAssertEqualObjects(self.gradientView.rightBorderColor, [self colorAtPoint:CGPointMake(9.0f, 0.0f)], nil);
}

- (void)testExample
{
STFail(@"Unit tests are not implemented yet in SAMGradientViewTests");

- (void)testBottomBorder {
self.gradientView.bottomBorderColor = [UIColor redColor];
STAssertEqualObjects(self.gradientView.bottomBorderColor, [self colorAtPoint:CGPointMake(0.0f, 9.0f)], nil);
}


- (void)testBottomInset {
self.gradientView.bottomInsetColor = [UIColor redColor];
STAssertEqualObjects(self.gradientView.backgroundColor, [self colorAtPoint:CGPointMake(0.0f, 8.0f)], nil);

self.gradientView.bottomBorderColor = [UIColor greenColor];
STAssertEqualObjects(self.gradientView.bottomInsetColor, [self colorAtPoint:CGPointMake(0.0f, 8.0f)], nil);
}


- (void)testLeftBorder {
self.gradientView.leftBorderColor = [UIColor redColor];
STAssertEqualObjects(self.gradientView.leftBorderColor, [self colorAtPoint:CGPointMake(0.0f, 1.0f)], nil);
}


#pragma mark - Utilities

- (UIColor *)colorAtPoint:(CGPoint)point {
// Get image
UIGraphicsBeginImageContextWithOptions(self.gradientView.bounds.size, self.gradientView.opaque, 1.0f);
[self.gradientView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

// Get the pixel at a given point
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *data = malloc(image.size.height * image.size.width * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * image.size.width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(data, image.size.width, image.size.height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, image.size.width, image.size.height), image.CGImage);
CGContextRelease(context);
int index = (bytesPerRow * point.y) + point.x * bytesPerPixel;
free(data);

// Create and return the color
return [UIColor colorWithRed:(CGFloat)data[index] / 255.0f green:(CGFloat)data[index + 1] / 255.0f blue:(CGFloat)data[index + 2] / 255.0f alpha:(CGFloat)data[index + 3] / 255.0f];
}

@end

0 comments on commit 142b67d

Please sign in to comment.