drawRect не вызывается в моем подклассе UIImageView - PullRequest
40 голосов
/ 10 апреля 2010

Я создал подкласс 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, и она никогда не срабатывает, заставляя меня думать, что ее вообще никогда не вызывают. Разве он не должен вызываться при первой загрузке представления? Я неправильно переопределил это?

Ответы [ 4 ]

85 голосов
/ 10 апреля 2010

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

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


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

Особые замечания

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

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

1 голос
/ 10 апреля 2010

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

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

0 голосов
/ 09 ноября 2013

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

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

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

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

0 голосов
/ 10 апреля 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...