【问题标题】:Retina Support for custom UITabBarController-like highlighting of UIImage?Retina 是否支持自定义 UITabBarController-like UIImage 突出显示?
【发布时间】:2023-03-28 05:20:01
【问题描述】:

我在我的应用程序中使用BCTabBarController,我正在尝试对其进行自定义,以便它使用核心图形自动突出显示图像,这样我就不需要每个图像的四个副本。 (Retina、Retina-selected、Legacy、Legacy-selected)

用户Ephraim 对此有posted a great starting point,但它返回旧尺寸的图像。我玩过一些设置,但我对 Core Graphics 不是很熟悉,所以我在黑暗中拍摄。

以法莲的密码:

- (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 添加了一个类别,然后对 BCTab.h 进行了以下更改:

- (id)initWithIconImageName:(NSString *)imageName {
if (self = [super init]) {
    self.adjustsImageWhenHighlighted = NO;
    self.background = [UIImage imageNamed:@"BCTabBarController.bundle/tab-background.png"];
    self.rightBorder = [UIImage imageNamed:@"BCTabBarController.bundle/tab-right-border.png"];
    self.backgroundColor = [UIColor clearColor];

//      NSString *selectedName = [NSString stringWithFormat:@"%@-selected.%@",
//                                 [imageName stringByDeletingPathExtension],
//                                 [imageName pathExtension]];


    UIImage  *defImage = [UIImage imageNamed:imageName];

    [self setImage:[defImage imageWithBackgroundColor:[UIColor lightGrayColor] shadeAlpha1:0.4 shadeAlpha2:0.0 shadeAlpha3:0.6 shadowColor:[UIColor blackColor] shadowOffset:CGSizeMake(0.0, -1.0f) shadowBlur:3.0] forState:UIControlStateNormal];
    [self setImage:[defImage imageWithBackgroundColor:[UIColor redColor] shadeAlpha1:0.4 shadeAlpha2:0.0 shadeAlpha3:0.6 shadowColor:[UIColor blackColor] shadowOffset:CGSizeMake(0.0, -1.0f) shadowBlur:3.0]  forState:UIControlStateSelected];

}
return self;
}

如何使用Ephraim's 代码与 Retina 显示器正常工作?

【问题讨论】:

    标签: objective-c ios core-graphics quartz-graphics retina-display


    【解决方案1】:

    在网上搜索后,a Google search 带我回到 StackOverflow。我 found this answerthis question 讨论了一种不同的方法,该方法应用于在 UIImageGraphicsContext 初始化时设置它的比例因子。

    UIGraphicsBeginImageContext(contextRect.size); 需要更改为UIGraphicsBeginImageContextWithOptions(contextRect.size, NO, scale);,其中“scale”是 您要使用的比例的值。我是从[[UIScreen mainScreen] scale] 获取的。

    【讨论】:

    • 更好的是,使用 0.0 作为比例尺。然后 UIKit 将自动选择一个适合屏幕的值(通过与您手动执行的操作类似但不完全相同的过程)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-14
    • 2011-04-14
    • 2023-03-13
    • 1970-01-01
    相关资源
    最近更新 更多