如何使UIImageView变暗

6

当UIImageView被触摸时,我需要将其变暗,就像SpringBoard(主屏幕)上的图标一样。

我应该添加一个alpha为0.5且背景为黑色的UIView。这似乎很笨拙。我应该使用图层或类似的东西吗(CALayers)。


可以使用 UIButton 吗? - John Calsbeek
3个回答

6

我会让UIImageView处理图像的实际绘制,但切换到提前加深的图像。以下是我用来生成保持透明度的加深图像的一些代码:

+ (UIImage *)darkenImage:(UIImage *)image toLevel:(CGFloat)level
{
    // Create a temporary view to act as a darkening layer
    CGRect frame = CGRectMake(0.0, 0.0, image.size.width, image.size.height);
    UIView *tempView = [[UIView alloc] initWithFrame:frame];
    tempView.backgroundColor = [UIColor blackColor];
    tempView.alpha = level;

    // Draw the image into a new graphics context
    UIGraphicsBeginImageContext(frame.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [image drawInRect:frame];

    // Flip the context vertically so we can draw the dark layer via a mask that
    // aligns with the image's alpha pixels (Quartz uses flipped coordinates)
    CGContextTranslateCTM(context, 0, frame.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextClipToMask(context, frame, image.CGImage);
    [tempView.layer renderInContext:context];

    // Produce a new image from this context
    CGImageRef imageRef = CGBitmapContextCreateImage(context);
    UIImage *toReturn = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    UIGraphicsEndImageContext();
    [tempView release];
    return toReturn;
}

谢谢!这就是我要找的。 - Tony

4
如何子类化UIView并添加一个UIImage实例变量(称为image)?然后,如果你有一个布尔值实例变量pressed,在触摸时设置它,你可以重写-drawRect:方法来实现以下内容:
- (void)drawRect:(CGRect)rect
{
[image drawAtPoint:(CGPointMake(0.0, 0.0))];

// if pressed, fill rect with dark translucent color
if (pressed)
    {
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSaveGState(ctx);
    CGContextSetRGBFillColor(ctx, 0.5, 0.5, 0.5, 0.5);
    CGContextFillRect(ctx, rect);
    CGContextRestoreGState(ctx);
    }
}

您可以尝试使用更高的RGBA值进行实验。当然,非矩形形状需要更多的工作——例如CGMutablePathRef。

1
这个问题中的UIImage已经在一个子类UIView中了,所以我可以这样做。但是为什么要在drawRect方法中这样做呢?我不能直接在touches began方法中这样做吗? - Jonathan.
如果只是切换某些设置,那么应该在touchesBegan中进行。并且可能会在touchesEnded中切换回来。但是实际的绘图,我认为应该在drawRect中进行。您可能需要在UIView子类实例上调用setNeedsDisplay,以配合切换状态更改。(最好在自定义setter中完成此操作。)我不确定UIImageView的子类在其drawRect被覆盖时会如何行为。这就是为什么我建议采用“更安全”的方法,基本上编写自己的UIImageView。希望这可以帮助到您。 - westsider
你误解了我的评论,为什么必须在drawRect中进行自定义绘图。我为什么不能把所有的CGContext...代码放在touchesBegan中呢? - Jonathan.
@Jonathan,引用Joe Conway和Aaron Hillegass在他们的书籍《iPhone编程:大牛栏指南》第91页上的话,“drawRect:方法是视图绘制代码的位置。”我总是在drawRect:中进行我的核心图形绘制。您可能需要阅读此文档http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/GraphicsandDrawing/GraphicsandDrawing.html%23//apple_ref/doc/uid/TP40009503-CH3-SW3以获取更多详细信息。我一直无法找到警告不要在drawRect:之外绘制的文档;虽然我记得看到过这样的内容... - westsider

1

UIImageView 可以拥有多个图片;当需要时,你可以切换到较暗的版本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接