как затемнить UIImageView

Мне нужно затемнить UIImageView, когда к нему прикасаются, почти точно так же, как значки на трамплине (домашний экран).

Стоит ли добавлять UIView с альфой 0,5 и черным фоном. Это кажется неуклюжим. Должен ли я использовать слои или что-то в этом роде (CALayers).


person Jonathan.    schedule 23.10.2010    source источник
comment
Можно ли вместо этого использовать UIButton?   -  person John Calsbeek    schedule 24.10.2010


Ответы (3)


Как насчет подкласса UIView и добавления ivar UIImage (называемого изображением)? Затем вы можете переопределить -drawRect: что-то вроде этого, при условии, что у вас есть логическая переменная с именем press, которая была установлена ​​при касании.

- (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.

person westsider    schedule 23.10.2010
comment
Рассматриваемый UIImage уже находится в подклассах UIView, поэтому я могу это сделать. Однако зачем мне делать это в методе drawRect, нельзя ли сделать это прямо в начале касаний? - person Jonathan.; 24.10.2010
comment
Если нужно переключить какую-то настройку, то это произойдет в touchesBegan. И это может быть переключено обратно в touchesEnded. Но реальное рисование, я думаю, будет происходить в drawRect. Возможно, вам потребуется вызвать setNeedsDisplay для вашего экземпляра подкласса UIView в сочетании с изменениями переключаемого состояния. (Это может быть лучше всего сделано в пользовательском установщике.) Я не уверен, как будет вести себя подкласс UIImageView, если его drawRect будет переопределен. Вот почему я предложил «более безопасный» подход, заключающийся в написании собственного UIImageView. Надеюсь это поможет. - person westsider; 24.10.2010
comment
вы неправильно поняли мой комментарий, почему пользовательский рисунок должен происходить в drawRect. Почему я не могу поставить весь CGContext... Код в тач начал. - person Jonathan.; 24.10.2010
comment
@Jonathan, цитируя Джо Конвея и Аарона Хиллегасса со страницы 91 их книги «Программирование iPhone: руководство Big Nerd Ranch», «метод drawRect: — это то, куда идет код рисования для представления». Я всегда рисую Core Graphics в drawRect:. Возможно, вы захотите прочитать этот ‹developer.apple.com/library/ios/#documentation/WindowsViews/› для получения более подробной информации. Мне не удалось найти документы, предупреждающие об опасности рисования за пределами drawRect:; думал что-то подобное читал... - person westsider; 25.10.2010

Я бы позволил 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;
}
person Kieran Harper    schedule 25.08.2012
comment
Спасибо! Это то, что я ищу. - person Tony; 11.03.2014

UIImageView может иметь несколько изображений; у вас может быть две версии изображения и при необходимости переключаться на более темную.

person jamihash    schedule 23.10.2010