DrawRect не вызывается в моем подклассе UIImageView

Я подклассифицировал UIImageView и попытался переопределить drawRect, чтобы рисовать поверх изображения с помощью Quartz 2D. Я знаю, что это глупый вопрос новичков, но я не вижу, что я сделал неправильно. Здесь интерфейс:

#import <UIKit/UIKit.h>

@interface UIImageViewCustom : UIImageView {

}
- (void)drawRect:(CGRect)rect;
@end

И реализация:

#import "UIImageViewCustom.h"

@implementation UIImageViewCustom

- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    // do stuff
}

- (void)dealloc {
    [super dealloc];
}
@end

Я установил точку останова на drawRect, и она никогда не ударяется, что заставляет меня думать, что ее вообще не называют. Разве он не должен вызываться, когда сначала загружается представление? Я неправильно его переопределил?

Ответ 1

Он вызывается только в том случае, если вид видимый и грязный. Может быть, проблема в коде, который создает представление или в вашем Nib, если это так, как вы его создаете?

Вы также иногда видите, что точки останова не могут быть правильно настроены, если вы пытаетесь отладить сборку "Release".


Я как-то пропустил первый раз, когда вы подклассифицируете UIImageView. Из документов:

Особые соображения

Класс UIImageView оптимизирован для нарисуйте его изображения на дисплее. UIImageView не будет называть drawRect: в подкласс. Если ваш подкласс необходим пользовательский код чертежа, рекомендуется вы используете UIView в качестве базового класса.

Итак, у вас это есть. Учитывая, как легко нарисовать изображение в вашем представлении, используя [UIImage drawInRect:] или используя CALayer, в любом случае, вероятно, нет веских оснований для подкласса UIImageView.

Ответ 2

Попробуйте добавить

Edit:

- (id)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
        [self setClearsContextBeforeDrawing:YES];//add this line also
    }
    return self;
}


- (void)setNeedsDisplay{
    [self setNeedsDisplayInRect:self.frame];
}

в ваш код.

надеюсь, что это поможет.

Спасибо,

madhup

Ответ 3

Непосредственно отвечая на ваш вопрос, но может решить вашу проблему:

Почему это с подклассом UIImageView? Подкласс всегда может быть проблематичным, особенно для классов, которые не предназначены для подкласса - и я уверен, что UIImageView не является. Если вы просто хотите нарисовать материал поверх изображения, создайте представление с прозрачным фоном, нарисуйте все, что захотите, и поместите его прямо над изображением.

Ответ 4

В зависимости от вашего конкретного случая, имеет смысл использовать UIButton с фоновым изображением вместо UIImageView. Вы даже можете установить userInteractionEnabled в НЕТ, и результат будет неотличим от UIImageView.

В этом случае ваш подкласс UIButton будет просто включать:

- (void)drawRect:(CGRect)rect
{
  if (kSomethingSpecial) {
    [self setBackgroundImage:[UIImage imageNamed:@"RedBackground.png"] 
                    forState:UIControlStateNormal];
  }
}

Отказ от ответственности - я бы рекомендовал это только в том случае, если у вас есть планы использовать изображение как кнопку, по крайней мере, некоторое время. Я не могу полностью одобрить использование UIButton в качестве обходного пути для этого поведения drawRect в UIImageView, так как я уверен, что у Apple есть причины для написания своего API таким образом, как указано на Mark.

Ответ 5

Я думаю, UIImageView не может использовать для переопределения drawRect