2013-03-08 17 views
5

私はUINavigationBarのグラデーションをレプリケートして、同じビュー上のカスタムUIButtonサブクラスオブジェクトのグラデーションとして使用しようとしていました。UINavigationBarのグラデーションカラーをどのように再現できますか?

しかし、どのように色が派生しているのかわかりません。つまり、UINavigationBarの背景色をtintColorに設定するには、1つの色のみを指定しますが、少なくとも4色のように見える素晴らしいグラデーションを作成しますか?

私は実際には、内側のトップとボトムの色に興味があります。バーの周りの1pxの境界線の内側です。外側の「境界」の色は実際には異なって表示されます。

EDIT - さらに研究すると1

値これらの異なる色を得るために操作される(最初に考えたとして代わりRBGの)、それはHSB現れます。

getHue:saturation:brightness:alpha: 

参考文献はHSL and HSV Wiki

UIColor Class Reference

これまで

が見つかりました:

役立つはずHSB値を取得するためのUIColorに便利な方法もあり、

Programmatically Lighten a Color

From the book Fundamentals of Interactive Computer Graphics

EDIT - 2

あなたがプログラムでUIButtonの背景にグラデーションを設定することができることを知らなかった場合は、ここでは、そのような操作を行う方法については、いくつかの参照です:

FUN WITH UIBUTTONS AND CORE ANIMATION LAYERS

Five Tips for Creating Stylish UIButtons(このリンクを提供するための名誉)

EDIT - 3

私は一緒にスプレッドシートUINavigationBarにHSB値の(最も外側の色を無視して)オリジナルと「内側」グラデーションの色を示すと、それに対応する「戻る」ボタン(タイトルを入れています無関係で常に白で表示されます)。

ここで私はいくつかのサンプルの色のために収集した情報をGoogleドキュメントへのリンクです:

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

注:これらの値は、網膜を使用してスクリーンショットを保存することで発見された、3.5" iOS 6.1用のiPhone Simulator(Xcodeバージョン4.6)、およびPhotoShopを使用してHSB値を目立たせる

BOUNTYのAWARD基準

私はそれをより多くの露出を持参し、うまくいけば良い答えを得るために、この質問に報奨金を開きました。私が探している答え:

"内側のトップ"と "内側のボトム"のグラデーションの色(スプレッドシートを参照)のRGB値またはHSB値を(ほとんどの場合は)計算/近似する方法を提供しますtintColorUINavigationBarに設定してください。

「戻る」ボタン(これはナビゲーションバーに似ていますが、私は「内側のトップ」と「内側のボトム」のグラデーションカラーを計算する方法も提供しています)これらの色が通常はやや「暗い」と思われる)

+0

、うまくいけば、誰かがとにかく便利な私の答えを見つけるでしょう...あなたの入力のための – danh

答えて

7

短い答え:

ロング回答をグラデーションされない:着色カラーを適用した後、その上にレンダリングされた透明オーバーレイ画像があります。

それは[email protected]と呼ばれ、UIKitアートワークにあります。 (ここにアップロードされた:http://cl.ly/image/2c2V3t1D1T3L

これは2x88ピクセルの画像であり、薄い背景の上で水平に繰り返さなければなりません。

戻るボタンの場合は非常によく似ていますが、その形にするためのマスクもあります。 UItintedBackButtonHighlightおよびUITintedBackButtonMask。

+1

どこに/この画像が見つかりましたか? –

+0

私自身の質問に答えるには、これは役に立ちます:https://github.com/0xced/UIKit-Artwork-Extractor –

+0

これは私が行った解決策です。私の場合は、ボタンのオーバーレイとして追加された、より大きな(より高い高さの)画像勾配を作成しました。私は賞金期限が過ぎたときに賞金を授与します。 –

0

UIButtonは単一のtintColorプロパティを取りますが、それはバックグラウンドのグラデーションで使用する他の色を計算しているわけではありません。 Try this tutorial

+0

おかげで、この答えは誤解を招くと正直に間違っています...(1) 'tintColor'は、** solid **(非勾配)の色である、*押された*色を設定します。(2)' UIButton'に 'backgroundColor'プロパティがあります。ボタンのタイプは 'UIButtonTypeCustom'ですが、これはまだ単色です。(3)はい、チュートリアルのリンクはボタンにグラデーションを適用しようとしている場合に役立ちます(**グラデーションレイヤーを追加することで**行う必要があります)私の知る限り)しかし、これはまだ、ナビゲーションバーのグラデーションをシミュレートする正しい色を決定するのに役立たないという問題です。 –

+0

'UIButton'と' UINavigationBar'の両方に実際に 'tintColor'プロパティがあるので、どうやら誤解を招くかもしれないのでしょうか、私はそれをもっと明確にするために編集しました。あなたの入力のためにもう一度ありがとう。 –

+0

+1リンクについて...私も質問の編集として追加しました –

2

アップルが異なる色のグループに対して異なる計算を行っているように見えるため、正確な動作をコピーするのは難しいです。例えば。明るい色が少し暗くなり、暗い色が点灯します。

バーボタンの項目と同じです。いくつかの色では、通常の「ボーダー付き」ボタンと「完了」スタイルボタンの違いはまったく異なります。時にはターコイズ色のように目立つことはありませんが、オレンジ色は確かに見えます。私はUIViewサブクラスか何かでプロトタイピングのための素晴らしいツールところで...
コピーし、このコードをPaintCodeを使用し、このサンプルコードを作成するための

。または、必要な部分だけを取得してください。

- (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); 
} 
+0

私はこの考え方を当初(RGB値を変更していました)持っていましたが、アップルはそうしていないと思います(私の推測はHSB値を変更します(具体的には、彩度と明度を変更します)。しかし、+1はこれと同じように見えます* ...私はもう少しAppleの色に近いことを望んでいます。 –

+0

私は色相、彩度、明るさを実際に操作しようとしましたが、結果はこれほど良くはありませんでした。 (デモアプリケーションをロードして自分で試してみると、好みの色の操作ができます。例えば、ターキーとオレンジは同じ彩度操作では処理できませんでした)。もう一度、Appleはさまざまな色に対して異なる計算を使用しているようだ。 –

2

良い質問と寛大な恩恵をいただきありがとうございます。私はこれに取り組んで、それがすでに容認されていることを確認するためにチェックしなかった。それにもかかわらず、それは楽しい建物だったし、それが色... QuartzCore.frameworkと

// 
// 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 

リンクの明らかにする次ナビゲーションバーのカテゴリをテスト。このような

// 
// 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); 
} 
+0

+1:きちんとした解決策 - ナビゲーションバーにプログラムでクエリを照会する。ありがとうございます。 –

+0

:-)は、UIViewカテゴリと同じように簡単に投稿できるので、どのビューからでも任意の位置に任意の色を入力できます。 UINavigationBar(色)をUIView(色)に変更するだけです。 – danh

関連する問題