我正在编写一个自定义的UITabBar替换,我想知道如何重新创建内置实现使用UITabBarItem图像的过滤器 - 蓝色照射在选定的选项卡上,灰色渐变在未选择的选项卡上。我想这是使用源图像alpha值作为遮罩并用预先制作的蓝色(或任何颜色)闪亮图像覆盖它而另一个遮盖了灰色的问题,但我想知道什么是最好的方法来自代码观点。
最佳,
答案 0 :(得分:11)
编辑:稍微修正了蓝色滤镜 Edit2:清理了灰色滤镜
我需要代码才能完成这些效果,因此我为它们编写了几个函数:
UIImage *grayTabBarItemFilter(UIImage *image) {
int width = image.size.width, height = image.size.height;
UIImage *result = image;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if (colorSpace == NULL) {
return result;
}
CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedLast);
if (context == NULL) {
CGColorSpaceRelease(colorSpace);
return result;
}
CGFloat colors[8] = {80/255.0,80/255.0,80/255.0,1, 175/255.0,175/255.0,175/255.0,1};
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, NULL, 2);
CGContextDrawLinearGradient(context, gradient, CGPointMake(0,-(32-height)/2.0), CGPointMake(0,height+(32-height)/2.0), 0);
CGGradientRelease(gradient);
CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
CGContextDrawImage(context, CGRectMake(0,0,width,height), image.CGImage);
CGImageRef newImage = CGBitmapContextCreateImage(context);
if (newImage != NULL) {
result = [UIImage imageWithCGImage:newImage];
CGImageRelease(newImage);
}
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
return result;
}
struct RGBA {
unsigned char red;
unsigned char green;
unsigned char blue;
unsigned char alpha;
};
#define BLUE_ALPHA_THRESHOLD 128
#define BLUE_BRIGHTNESS_ADJUST 30
UIImage *blueTabBarItemFilter(UIImage *image) {
int width = image.size.width,
height = image.size.height;
UIImage *result = image;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if (colorSpace == NULL) {
return result;
}
CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedLast);
if (context == NULL) {
CGColorSpaceRelease(colorSpace);
return result;
}
UIImage *gradient = [UIImage imageNamed:@"selection_gradient.png"];
CGContextDrawImage(context, CGRectMake(-(gradient.size.width - width) / 2.0, -(gradient.size.height - height) / 2.0, gradient.size.width, gradient.size.height), gradient.CGImage);
CGContextSetBlendMode(context, kCGBlendModeDestinationIn);
CGContextDrawImage(context, CGRectMake(0,0,width,height), image.CGImage);
struct RGBA *pixels = CGBitmapContextGetData(context);
if (pixels != NULL) {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int offset = x+y*width;
if (pixels[offset].alpha >= BLUE_ALPHA_THRESHOLD &&
((x == 0 || x == width-1 || y == 0 || y == height-1) ||
(pixels[x+(y-1)*width].alpha < BLUE_ALPHA_THRESHOLD) ||
(pixels[x+1+y*width].alpha < BLUE_ALPHA_THRESHOLD) ||
(pixels[x+(y+1)*width].alpha < BLUE_ALPHA_THRESHOLD) ||
(pixels[x-1+y*width].alpha < BLUE_ALPHA_THRESHOLD))) {
pixels[offset].red = MIN(pixels[offset].red + BLUE_BRIGHTNESS_ADJUST,255);
pixels[offset].green = MIN(pixels[offset].green + BLUE_BRIGHTNESS_ADJUST,255);
pixels[offset].blue = MIN(pixels[offset].blue + BLUE_BRIGHTNESS_ADJUST,255);
}
}
}
CGImageRef image = CGBitmapContextCreateImage(context);
if (image != NULL) {
result = [UIImage imageWithCGImage:image];
CGImageRelease(image);
}
}
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
return result;
}
要使蓝色滤镜效果有效,您需要将此图片作为“selection_gradient.png”包含在项目中:selection_gradient.png http://oi55.tinypic.com/bgwv0j.jpg
此外,你可能想要使用定义来获得你想要的效果,我没有花太多时间来完善它们,尽管它们对我来说看起来很好。
当然我不知道Apple应用的确切过滤器,但我“估计”了它们,它们对我来说看起来不错。我不确定这些功能是否与iPhone 4兼容,因为我只是在iPad应用程序中使用它们,但根据自己的喜好编辑它们并不困难。
答案 1 :(得分:1)
试试这个;它更短:
+ (UIImage *)blendImageBlue:(UIImage *)senderImage {
UIImage *image = [UIImage imageNamed:@"selection_gradient"];
CGSize newSize = CGSizeMake(senderImage.size.width, senderImage.size.height);
UIGraphicsBeginImageContextWithOptions(newSize, NO, [UIScreen mainScreen].scale);
[senderImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeSourceAtop alpha:0.8];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
编辑:使用@ poiuy_qwert的“selection_gradient.png”
答案 2 :(得分:0)
如果您对UITabBarItem过滤器的精确副本感兴趣,请尝试此解决方案。您不需要在项目中包含任何额外的图像。
我完全清楚这是一个彻头彻尾的黑客,我对未来的兼容性没有任何承诺,但据我所知,它在iOS 5和iOS 6都有效,并且我认为有适当的错误处理它可能很有用。在这里:
UIImage *grayTabBarItemFilter(UIImage *image) {
UITabBar* bar = [[UITabBar alloc] init];
UITabBarItem* item = [[UITabBarItem alloc] initWithTitle:@"" image:image tag:0];
[bar setItems:@[item]];
[[[[UIApplication sharedApplication] windows] lastObject] addSubview:bar];
UIImage* returnImage;
for(UIView* view in bar.subviews) {
for(UIView* small in view.subviews) {
if([small respondsToSelector:@selector(image)]) {
returnImage = [(UIImageView*)small image];
}
}
}
[bar removeFromSuperview];
return returnImage ? returnImage : image;
}
UIImage *blueTabBarItemFilter(UIImage *image) {
UITabBar* bar = [[UITabBar alloc] init];
UITabBarItem* item = [[UITabBarItem alloc] initWithTitle:@"" image:image tag:0];
[bar setItems:@[item]];
[bar setSelectedItem:item];
[[[[UIApplication sharedApplication] windows] lastObject] addSubview:bar];
UIImage* returnImage;
for(UIView* view in bar.subviews) {
NSInteger count = 0;
for(UIView* small in view.subviews) {
if([small respondsToSelector:@selector(image)]) {
count++;
if(count > 1) {
returnImage = [(UIImageView*)small image];
}
}
}
}
[bar removeFromSuperview];
return returnImage ? returnImage : image;
}
同样,我知道这是一个不稳定的解决方案,但如果你对一个完美的复制品感兴趣,那么它就是。