Подкласс UIView рисует фон, несмотря на полностью пустой drawRect: - почему?

Итак, у меня есть пользовательский подкласс UIView, который позволяет рисовать закругленные края. Это прекрасно получается, однако фон всегда заполняет все границы, несмотря на то, что сначала отсекает путь. Граница также рисуется над прямоугольным фоном, несмотря на то, что я рисую границу в drawRect: перед фоном. Таким образом, я удалил весь контент drawRect:, который теперь практически пуст - тем не менее фон рисуется!

Кто-нибудь объясняет это? Я устанавливаю backgroundColor в Interface Builder. Спасибо!

Ответ 1

Извините за этот монолог.:)

Дело в том, что слой UIView, по-видимому, рисует фон, который не зависит от drawRect:. Вот почему вы не можете избавиться от фона, переопределив drawRect:.

Вы можете либо переопределить - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx, либо сделать слой рисованным, что хотите, или переопределить - (void) setBackgroundColor:(UIColor *)newColor, и не назначать newColor backgroundColor, а вашему собственному ivar, например myBackgroundColor. Затем вы можете использовать myBackgroundColor в drawRect; для рисования фона, как вам нравится.


Переопределение setBackgroundColor:

Определите переменную экземпляра, чтобы удерживать фоновый цвет, например. myBackgroundColor. В ваших методах init установите реальный цвет фона как clearColor:

- (id) initWithCoder:(NSCoder *)aDecoder
{
    if ((self = [super init...])) {
        [super setBackgroundColor:[UIColor clearColor]];
    }
    return self;
}

Override:

- (void) setBackgroundColor:(UIColor *)newColor
{
    if (newColor != myBackgroundColor) {
        [myBackgroundColor release];
        myBackgroundColor = [newColor retain];
    }
}

Затем используйте метод myBackgroundColor в методе drawRect:. Таким образом вы можете использовать цвет, назначенный из интерфейса Builder (или Xcode4) в вашем коде.

Ответ 2

Здесь проще установить:

self.backgroundColor = [UIColor clearColor];

Ответ 3

Не стесняюсь предлагать это, потому что я не хочу вас оскорблять, но у вас нет непрозрачности NO?

Ответ 4

Это легко воспроизводится:

Создайте новое приложение для iPhone на основе View. Создайте подкласс UIView и оставьте метод drawRect: полностью пустым. В Interface Builder перетащите UIView в основной вид, назначьте ему цвет фона и установите класс представления в свой подкласс. Сохраните, создайте и запустите и посмотрите, на экране отображается цвет фона.

Я обошел это поведение, переопределив setBackgroundColor и присвоив цвет своему собственному ivar, всегда оставляя свойство backgroundColor nil. Это работает, однако мне все еще интересно, почему это работает таким образом.

Ответ 5

Вы должны установить

clearsContextBeforeDrawing = NO

Это просто.

Из UIView Reference Docs

К сожалению. Я не понял этот вопрос. OP (оригинальный плакат) хочет, чтобы их пользовательский элемент управления поддерживал стандартное свойство backgroundColor (например, установленным дизайнером gui), но НЕ хочет, чтобы система рисовала этот цвет. OP хочет нарисовать сам bg, чтобы он мог обогнуть углы.

В этом случае сообщение об переопределении чертежа уровня будет правильным.

Решение, которое я разместил, не позволит системе пользовательского интерфейса очистить буфер до рисования. Если у вас нет bg defined, если установлено cleararsContextBeforeDrawing, iOS очистит ваш буфер просмотра, установив все пиксели в прозрачный черный. Выполнение этого для полноэкранного просмотра занимает около 5 мс в iPad3, поэтому оно не бесплатное (нажатие на 2048x1536 пикселей никогда не будет). Для сравнения рисунок полноэкранного растрового изображения (с использованием kCGBlendModeCopy для принудительного blitting) занимает ~ 25 мс (с использованием кварца, а не GPU).