Подкласс UIView рисует фон, несмотря на совершенно пустое drawRect: - почему? - PullRequest
10 голосов
/ 11 октября 2009

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

Кто-нибудь объяснит это? Я установил backgroundColor в Интерфейсном Разработчике. Спасибо!

Ответы [ 5 ]

20 голосов
/ 12 октября 2009

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

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

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


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

Определите переменную экземпляра для хранения цвета фона, например, myBackgroundColor . В ваших методах инициализации установите реальный цвет фона на 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 :. Таким образом, вы можете использовать цвет, назначенный из Interface Builder (или Xcode4) в вашем коде.

8 голосов
/ 19 марта 2010

Вот более легкое исправление:

self.backgroundColor = [UIColor clearColor];
6 голосов
/ 12 января 2010

Стесняюсь предложить это, потому что я не хочу вас обидеть, но вы установили непрозрачным значение НЕТ?

0 голосов
/ 30 июля 2012

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

clearsContextBeforeDrawing = NO

Это так просто.

Из справочных документов UIView 1007 *

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

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

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

0 голосов
/ 12 октября 2009

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

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

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

...