UITabBarのアイコンを作成すると、画像にグラデーションが適用されます。私はそれがこの勾配を持つのを防ぐ方法を知る必要があります。
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];
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がこれを行うためのアプリケーションを拒否する可能性が非常に高いです。プライベートAPIが将来のOSアップデートで削除された場合、-[UITabBar recolorItemsWithColor:shadowColor:shadowOffset:shadowBlur:]
クラッシュする代わりに何もしません。
グラデーションの追加は非常に簡単です。次のコード行を追加します。
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の動作に非常に近くなりますが、正確ではありません。そこに到達するには、コンポーネントにNULL
の代わりに2つのポイント/色を追加するだけです。 CGGradientCreateWithColorComponents
、{0,0.5,0.6,1.0}
のようなものを使用します。実際、必要なのは1つの背景色と3つのアルファポイントだけです(単一のカラープロファイルを保持しながらシェーディングが必要なため、カラー部分はすべて1です)。 。
これが明確でない場合は、コードを投稿します...乾杯。
IDevレシピサイトにカスタム実装されたタブバーを使用して、これに対する解決策があります。
http://idevrecipes.com/2011/01/04/how-does-the-Twitter-iphone-app-implement-a-custom-tab-bar
ほぼ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];
ボタンの「オフステート」に色を付ける方法について質問しました。誰かが私にグラデーションを削除するというボーナスもある解決策をくれました。これが質問と彼の答えです:
Q: iphone-タブバーセットimagetintcolor(オフステート)
A:UITabBarItemのドキュメントの「完成した画像と選択した画像の管理」タスクのセクションをご覧ください。
次の画像を使用します(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;
}