24

UITabBar のアイコンを作成すると、画像にグラデーションが適用されます。このグラデーションが発生しないようにする方法を知る必要があります。

4

7 に答える 7

27

AppleはiOS5にタブバーのカスタマイズを追加しましたが、今ではこの種のものは簡単です。これ以前は、それは巨大なハックであり、推奨されていませんでした。

完全にカスタムのタブバーを作成する方法は次のとおりです。

// custom icons
UITabBarItem *item = [[UITabBarItem alloc] init];
item.title = @"foo";
// setting custom images prevents the OS from applying a tint color
[item setFinishedSelectedImage:[UIImage imageNamed:@"tab1_active.png"] withFinishedUnselectedImage:[UIImage imageNamed:@"tab1_image_deselected.png"]];
tab1ViewController.tabBarItem = item;

    // tab bar

    // set background image - will be used instead of glossy black
    tabBarController.tabBar.backgroundImage = [UIImage imageNamed:@"tab_bar_bg.png"];
    // optionally set the tint color - setting this ti nil will result in the standard, blue tint color. tint color is ignored when custom icons are set as above.
    tabBarController.tabBar.selectedImageTintColor = nil;
    // remove the highlight around the selected tab - or provide an alternate highlight image. If you don't do this the iOS default is to draw a highlighted box beneath the selected tab icon.
    tabBarController.tabBar.selectionIndicatorImage = [[UIImage alloc] init];
于 2012-03-02T08:15:07.330 に答える
18

UITabBarは選択された/選択されていない画像へのアクセスを提供しないため、これは驚くほど困難です。ただし、プライベート API を使用して実現できます。

@interface UITabBar (ColorExtensions)
- (void)recolorItemsWithColor:(UIColor *)color shadowColor:(UIColor *)shadowColor shadowOffset:(CGSize)shadowOffset shadowBlur:(CGFloat)shadowBlur;
@end

@interface UITabBarItem (Private)
@property(retain, nonatomic) UIImage *selectedImage;
- (void)_updateView;
@end

@implementation UITabBar (ColorExtensions)
- (void)recolorItemsWithColor:(UIColor *)color shadowColor:(UIColor *)shadowColor shadowOffset:(CGSize)shadowOffset shadowBlur:(CGFloat)shadowBlur
{
    CGColorRef cgColor = [color CGColor];
    CGColorRef cgShadowColor = [shadowColor CGColor];
    for (UITabBarItem *item in [self items])
        if ([item respondsToSelector:@selector(selectedImage)] &&
            [item respondsToSelector:@selector(setSelectedImage:)] &&
            [item respondsToSelector:@selector(_updateView)])
        {
            CGRect contextRect;
            contextRect.origin.x = 0.0f;
            contextRect.origin.y = 0.0f;
            contextRect.size = [[item selectedImage] size];
            // Retrieve source image and begin image context
            UIImage *itemImage = [item image];
            CGSize itemImageSize = [itemImage size];
            CGPoint itemImagePosition; 
            itemImagePosition.x = ceilf((contextRect.size.width - itemImageSize.width) / 2);
            itemImagePosition.y = ceilf((contextRect.size.height - itemImageSize.height) / 2);
            UIGraphicsBeginImageContext(contextRect.size);
            CGContextRef c = UIGraphicsGetCurrentContext();
            // Setup shadow
            CGContextSetShadowWithColor(c, shadowOffset, shadowBlur, cgShadowColor);
            // Setup transparency layer and clip to mask
            CGContextBeginTransparencyLayer(c, NULL);
            CGContextScaleCTM(c, 1.0, -1.0);
            CGContextClipToMask(c, CGRectMake(itemImagePosition.x, -itemImagePosition.y, itemImageSize.width, -itemImageSize.height), [itemImage CGImage]);
            // Fill and end the transparency layer
            CGContextSetFillColorWithColor(c, cgColor);
            contextRect.size.height = -contextRect.size.height;
            CGContextFillRect(c, contextRect);
            CGContextEndTransparencyLayer(c);
            // Set selected image and end context
            [item setSelectedImage:UIGraphicsGetImageFromCurrentImageContext()];
            UIGraphicsEndImageContext();
            // Update the view
            [item _updateView];
        }
}
@end

かなりクールなエフェクトを作成することもできます:

赤いタブ バー
(ソース: booleanmagic.com )

Apple がこれを行うためのアプリケーションを拒否する可能性は非常に高いです。将来の OS アップデートでプライベート API が削除された場合、
-[UITabBar recolorItemsWithColor:shadowColor:shadowOffset:shadowBlur:]はクラッシュする代わりに何もしません。

于 2009-08-31T09:04:54.263 に答える
4

グラデーションの追加は非常に簡単です。次のコード行を追加します。


CGFloat components[8] = {0.0,0.4,1.0,0.2,0.0,0.6,1.0,1.0};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();  
CGGradientRef colorGradient = CGGradientCreateWithColorComponents(colorSpace, components, NULL, 2);
CGContextDrawLinearGradient(cxt, colorGradient,CGPointZero,CGPointMake(0,contextRect.size.height),0);

これにより、Apple がタブバーで行う操作に非常に近くなりますが、正確ではありません。そこにたどり着くには、コンポーネントにさらに2つのポイント/色を追加し、NULLinの代わりに のCGGradientCreateWithColorComponentsようなものを使用します{0,0.5,0.6,1.0}。実際、必要なのは 1 つの背景色と 3 つのアルファ ポイントだけです (単一のカラー プロファイルを保持しながらシェーディングが必要なだけなので、カラー部分はすべて 1 です)。

これが明確でない場合は、コードを投稿します...乾杯。

于 2010-02-17T09:05:27.407 に答える
3

ほぼ1年が経ちましたが、ここにコードがあります。これをカテゴリとして UIImage に追加するか、クラス全体に変換します。渡す画像 (自己) はアルファのみの画像でなければならないことに注意してください (マスクは画像の可視部分に基づいて作成されます)。



- (UIImage *) imageWithBackgroundColor:(UIColor *)bgColor 
                           shadeAlpha1:(CGFloat)alpha1 
                           shadeAlpha2:(CGFloat)alpha2
                           shadeAlpha3:(CGFloat)alpha3 
                           shadowColor:(UIColor *)shadowColor 
                          shadowOffset:(CGSize)shadowOffset 
                            shadowBlur:(CGFloat)shadowBlur { 

    UIImage *image = self;

    CGColorRef cgColor = [bgColor CGColor];
    CGColorRef cgShadowColor = [shadowColor CGColor];

    CGFloat components[16] = {1,1,1,alpha1,1,1,1,alpha1,1,1,1,alpha2,1,1,1,alpha3};
    CGFloat locations[4] = {0,0.5,0.6,1};

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();  

    CGGradientRef colorGradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, (size_t)4);

    CGRect contextRect;
    contextRect.origin.x = 0.0f;
    contextRect.origin.y = 0.0f;
    contextRect.size = [image size];
    //contextRect.size = CGSizeMake([image size].width+5,[image size].height+5);  
    // Retrieve source image and begin image context
    UIImage *itemImage = image;
    CGSize itemImageSize = [itemImage size];
    CGPoint itemImagePosition; 
    itemImagePosition.x = ceilf((contextRect.size.width - itemImageSize.width) / 2);
    itemImagePosition.y = ceilf((contextRect.size.height - itemImageSize.height) / 2);
    UIGraphicsBeginImageContext(contextRect.size);
    CGContextRef c = UIGraphicsGetCurrentContext();
    // Setup shadow
    CGContextSetShadowWithColor(c, shadowOffset, shadowBlur, cgShadowColor);
    // Setup transparency layer and clip to mask
    CGContextBeginTransparencyLayer(c, NULL);
    CGContextScaleCTM(c, 1.0, -1.0);
    CGContextClipToMask(c, CGRectMake(itemImagePosition.x, -itemImagePosition.y, itemImageSize.width, -itemImageSize.height), [itemImage CGImage]);
    // Fill and end the transparency layer
    CGContextSetFillColorWithColor(c, cgColor);     
    contextRect.size.height = -contextRect.size.height;
    CGContextFillRect(c, contextRect);
    CGContextDrawLinearGradient(c, colorGradient,CGPointZero,CGPointMake(contextRect.size.width*1.0/4.0,contextRect.size.height),0);
    CGContextEndTransparencyLayer(c);
    //CGPointMake(contextRect.size.width*3.0/4.0, 0)
    // Set selected image and end context
    UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    CGColorSpaceRelease(colorSpace);
    CGGradientRelease(colorGradient);

    return resultImage;

}

たとえば、次のようにすると、ネイティブのタブバーと非常によく似た効果が得られます。



UIImage *niceImage = [[UIImage imageNamed:@"image_name"] imageWithBackgroundColor:[UIColor colorWithRed:41.0/255.0 green:147.0/255.0 blue:239.0/255.0 alpha:1.0] 
                                                                      shadeAlpha1:0.6 
                                                                      shadeAlpha2:0.0 
                                                                      shadeAlpha3:0.4 
                                                                      shadowColor:[UIColor blackColor] 
                                                                     shadowOffset:CGSizeMake(0.0f, -1.0f)  
                                                                       shadowBlur:3.0]; 

于 2011-01-22T01:33:32.303 に答える
3

iDev Recipes サイトで、カスタム実装されたタブ バーを使用してこれを解決する方法があります。

http://idevrecipes.com/2011/01/04/how-does-the-twitter-iphone-app-implement-a-custom-tab-bar

于 2011-03-11T02:20:24.977 に答える
1

ボタンの「オフステート」に色を付ける方法について質問しました。誰かが、グラデーションを削除するというボーナスもある解決策を教えてくれました。これが質問と彼の答えです:

Q: iphone - タブバー セット imagetintcolor (offstate)

A: UITabBarItem のドキュメントの「完成した画像と選択した画像の管理」タスクのセクションをご覧ください。

于 2012-06-02T15:08:24.913 に答える
1

次の画像を使用します(次のように、tabBarに5つのタブがあると仮定します)

  • ここに画像の説明を入力
  • ここに画像の説明を入力
  • ここに画像の説明を入力
  • ここに画像の説明を入力
  • ここに画像の説明を入力

「TabBar Application」テンプレートを使用して新しいプロジェクトを作成し、次のコードを配置します。

AppDel.h ファイルの内容。

#import <UIKit/UIKit.h>

@interface cTabBarAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {

}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
@property (nonatomic, retain) IBOutlet UIImageView *imgV;

@end

AppDel.m ファイルの内容。

#import "cTabBarAppDelegate.h"

@implementation cTabBarAppDelegate
@synthesize window=_window;
@synthesize tabBarController=_tabBarController;
@synthesize imgV = _imgV;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.tabBarController.delegate=self;
    self.imgV.frame=CGRectMake(0, 425, 320, 55);
    [self.tabBarController.view addSubview:self.imgV];
    self.tabBarController.selectedIndex=0;
    self.window.rootViewController = self.tabBarController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{
    NSUInteger index=[[tabBarController viewControllers] indexOfObject:viewController];
    switch (index) {
        case 0:
            self.imgV.image=[UIImage imageNamed:@"tBar1.png"];
            break;
        case 1:
            self.imgV.image=[UIImage imageNamed:@"tBar2.png"];
            break;
        case 2:
            self.imgV.image=[UIImage imageNamed:@"tBar3.png"];
            break;
        case 3:
            self.imgV.image=[UIImage imageNamed:@"tBar4.png"];
            break;
        case 4:
            self.imgV.image=[UIImage imageNamed:@"tBar5.png"];
            break;
        default:
            break;
    }
    return YES;
}
于 2011-07-01T10:28:58.357 に答える