How can I copy the colors of a UINavigationBar gradient?

I am trying to replicate a gradient from UINavigationBarto use it as a gradient for custom subclass objects UIButtonin the same view.

However, I can’t understand how colors are produced? That is, you specify only one color to set the background color UINavigationBar- tintColor- but it creates a good gradient, does it seem to have at least 4 colors?

I'm really interested in the "inner" upper and lower colors, though - only inside the 1px border around the bar ... the outer borders of the "border" really look different, though.

EDIT - 1

With further research, it seems that HSB (instead of RBG as a first thought) manipulate values ​​to produce different colors.

There is also a convenience method on UIColorto obtain HSB values ​​that should be useful:

getHue:saturation:brightness:alpha:

Useful links found so far

HSL and HSV Wiki

UIColor class reference

Program color highlight

From the book Basics of Interactive Computer Graphics

EDIT - 2

If you did not know that you can set the gradient for the background on UIButtonprogrammatically, here are some links for how to do this:

FUN WITH UIBUTTONS AND CORE ANIMATION LAYERS

Five tips for creating stylish UIButtons (kudos to @cdo to provide this link)

EDIT - 3

, "" ( ) HSB UINavigationBar "" ( ).

Google , :

https://docs.google.com/spreadsheet/ccc?key=0AnKVtzkNS9scdGVRN01pa1NQcC1hdThNbEVzQU8wRlE&usp=sharing

: 3.5 "iPhone Simulator ( Xcode 4.6) iOS 6.1 HSB PhotoShop.

, , , . , :

/ ( ) RGB HSB " " " " (. ), tintColor UINavigationBar.

( ), " " " " "" ( , ve , "" )?

+5
4

:

: .

: UITintedTopBarHighlight@2x.png, UIKit. ( : http://cl.ly/image/2c2V3t1D1T3L)

2x88 .

"" , , . UItintedBackButtonHighlight UITintedBackButtonMask.

+7

, , Apple . . , .

. "bordered" "done" . , , .

PaintCode btw..
UIView - . , .

- (void)drawRect:(CGRect)rect
{
    //// General Declarations
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = UIGraphicsGetCurrentContext();

    //// Color Declarations
    UIColor* tint = [UIColor colorWithRed: 1 green: 0.66 blue: 0.329 alpha: 1];
    CGFloat tintRGBA[4];
    [tint getRed: &tintRGBA[0] green: &tintRGBA[1] blue: &tintRGBA[2] alpha: &tintRGBA[3]];

    UIColor* lighter = [UIColor colorWithRed: (tintRGBA[0] * 0.58 + 0.42) green: (tintRGBA[1] * 0.58 + 0.42) blue: (tintRGBA[2] * 0.58 + 0.42) alpha: (tintRGBA[3] * 0.58 + 0.42)];
    CGFloat lighterRGBA[4];
    [lighter getRed: &lighterRGBA[0] green: &lighterRGBA[1] blue: &lighterRGBA[2] alpha: &lighterRGBA[3]];

    UIColor* lightest = [UIColor colorWithRed: (lighterRGBA[0] * 0.55 + 0.45) green: (lighterRGBA[1] * 0.55 + 0.45) blue: (lighterRGBA[2] * 0.55 + 0.45) alpha: (lighterRGBA[3] * 0.55 + 0.45)];
    UIColor* darker = [UIColor colorWithRed: (tintRGBA[0] * 0.92) green: (tintRGBA[1] * 0.92) blue: (tintRGBA[2] * 0.92) alpha: (tintRGBA[3] * 0.92 + 0.08)];
    CGFloat darkerRGBA[4];
    [darker getRed: &darkerRGBA[0] green: &darkerRGBA[1] blue: &darkerRGBA[2] alpha: &darkerRGBA[3]];

    UIColor* darkest = [UIColor colorWithRed: (darkerRGBA[0] * 0.65) green: (darkerRGBA[1] * 0.65) blue: (darkerRGBA[2] * 0.65) alpha: (darkerRGBA[3] * 0.65 + 0.35)];

    //// Gradient Declarations
    NSArray* gradientColors = [NSArray arrayWithObjects:
                               (id)lighter.CGColor,
                               (id)darker.CGColor, nil];
    CGFloat gradientLocations[] = {0, 1};
    CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)gradientColors, gradientLocations);


    //// top Drawing
    UIBezierPath* topPath = [UIBezierPath bezierPathWithRect: CGRectMake(0, 0, rect.size.width, 1)];
    [lightest setFill];
    [topPath fill];

    //// theGradient Drawing
    UIBezierPath* theGradientPath = [UIBezierPath bezierPathWithRect: CGRectMake(0, 1, rect.size.width, rect.size.height - 1.0f)];
    CGContextSaveGState(context);
    [theGradientPath addClip];
    CGContextDrawLinearGradient(context, gradient, CGPointMake(50, 1), CGPointMake(50, rect.size.height-1.0f), 0);
    CGContextRestoreGState(context);

    //// bottom Drawing
    UIBezierPath* bottomPath = [UIBezierPath bezierPathWithRect: CGRectMake(0, rect.size.height-1.0f, rect.size.width, 1)];
    [darkest setFill];
    [bottomPath fill];


    //// Cleanup
    CGGradientRelease(gradient);
    CGColorSpaceRelease(colorSpace);
}
+2

. , , . , , ...

//
//  UINavigationBar+colors.h

#import <UIKit/UIKit.h>

@interface UINavigationBar (Colors)

// Answer an array of colors representing the color of the reciever, starting at fromY, up to toY
- (NSArray *)colorsFromY:(NSUInteger)fromY to:(NSUInteger)toY;

@end

QuartzCore.framework.

//
//  UINavigationBar+colors.m

#import "UINavigationBar+colors.h"
#import <QuartzCore/QuartzCore.h>

#define UIIMAGE_BYTES_PER_PIXEL 4u

@implementation UINavigationBar (Colors)

+ (NSData *)dataFromImage:(UIImage *)image {

    CGImageRef imageRef = [image CGImage];
    NSUInteger width = CGImageGetWidth(imageRef);
    NSUInteger height = CGImageGetHeight(imageRef);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    NSUInteger dataSize = height * width * UIIMAGE_BYTES_PER_PIXEL;
    unsigned char *rawData = malloc(dataSize);
    NSUInteger bytesPerRow = width * UIIMAGE_BYTES_PER_PIXEL;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                                 bitsPerComponent, bytesPerRow, colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    CGContextRelease(context);

    NSData *rtn = [NSData dataWithBytes:rawData length:dataSize];
    free(rawData);
    return rtn;
}


+ (UIColor *)colorOfImage:(UIImage *)image atX:(NSUInteger)px atY:(NSUInteger)py  {

    NSData *imgData = [self dataFromImage:image];
    if (!imgData) return nil;

    NSUInteger byteIndex = UIIMAGE_BYTES_PER_PIXEL * (image.size.width * py + px);

    unsigned char rgbaData[4];
    NSRange range = { byteIndex, 4u };
    [imgData getBytes:rgbaData range:range];
    CGFloat red   = rgbaData[0] / 255.0;
    CGFloat green = rgbaData[1] / 255.0;
    CGFloat blue  = rgbaData[2] / 255.0;
    CGFloat alpha = rgbaData[3] / 255.0;

    return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
}

- (UIImage *)asImage {

    UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.opaque, 0.0);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return img;
}

- (NSArray *)colorsFromY:(NSUInteger)fromY to:(NSUInteger)toY {

    NSMutableArray *answer = [NSMutableArray array];
    UIImage *image = [self asImage];

    for (NSUInteger y = MAX(0, fromY); y < MIN(self.bounds.size.height, toY); y++) {
        [answer addObject:[self.class colorOfImage:image atX:1 atY:y]];
    }
    return [NSArray arrayWithArray:answer];
}

@end

:

// from a view controller contained by a navigation controller...
UINavigationBar *bar = self.navigationController.navigationBar;

NSArray *colors = [bar colorsFromY:0 to:bar.bounds.size.height];
for (UIColor *color in colors) {
    NSLog(@"%@", color);
}
+2

UIButton uses one property tintColor, but this does not mean that it does not calculate other colors for use in the gradient behind the scenes. Try this tutorial .

0
source

All Articles