ContentScaleFactor UIView зависит от реализации drawRect :? - PullRequest
9 голосов
/ 28 февраля 2012

Я наткнулся на странную вещь. Похоже, что UIView contentScaleFactor всегда равно 1, даже на устройствах Retina, если вы не внедрили drawRect:. Рассмотрим этот код:

@interface MyView : UIView
@end

@implementation MyView

- (id) initWithFrame: (CGRect) frame
{
    self = [super initWithFrame: frame];
    if (self) {
        NSLog(@"%s %g %g %g", __PRETTY_FUNCTION__, self.contentScaleFactor, self.layer.contentsScale, [UIScreen mainScreen].scale);
    }
    return self;
}

- (void) didMoveToWindow
{
    if (self.window)
        NSLog(@"%s %g %g %g", __PRETTY_FUNCTION__, self.contentScaleFactor, self.layer.contentsScale, [UIScreen mainScreen].scale);
}

@end

На устройстве Retina он печатает следующее:

-[MyView initWithFrame:] 1 1 2
-[MyView didMoveToWindow] 1 1 2

Если я добавлю пустую реализацию drawRect:, например:

- (void) drawRect: (CGRect) rect
{
}

работает как положено:

-[MyView initWithFrame:] 2 2 2
-[MyView didMoveToWindow] 2 2 2

Так что, похоже, на самом деле не имеет значения, находится ли представление в какой-либо иерархии представления и на каком экране оно отображается. Единственное, что имеет значение, это то, реализует ли представление drawRect: или нет.

Это ошибка или особенность? Я знаю, что могу изменить didMoveToWindow, как показано ниже, чтобы исправить это

- (void) didMoveToWindow
{
    if (self.window)
        self.contentScaleFactor = self.window.screen.scale;
}

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

Вы можете спросить, зачем мне вообще нужен contentScaleFactor, если я ничего не рисую. Это потому, что я просто установил self.layer.contents на готовое изображение, а затем растянул изображение на contentStretch. Однако изображение на устройствах Retina не растягивается должным образом, если contentScaleFactor не установлен правильно, даже если используется изображение @2x. Точнее, он работает правильно , если не используется a @2x изображение. Это, наверное, ошибка.

Может кто-нибудь поделиться вашим пониманием того, почему contentScaleFactor ведет себя так? Это специфично только для iOS 5?

Ответы [ 2 ]

10 голосов
/ 28 февраля 2012

Предположительно, если вы не переопределите drawRect:, тогда UIKit знает, что UIView ничего не рисует, поэтому он принимает (предположительно) быстрый случай наличия слоя с масштабом содержимого 1. Как только хотя вы переопределяете drawRect:, он знает, что ему нужно настроить слой с правильным масштабом содержимого, в который вы можете рисовать, если хотите. Он не знает, что вы ничего не делаете в drawRect:, поэтому он не может сделать то же предположение, что и раньше.

Фактически все, что упоминается в документах:

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

Почему бы вам просто не переопределить drawRect: и на этом нарисовать свое изображение? Или, возможно, вы могли бы сойти с рук, что вы делаете в настоящее время и получить заглушку drawRect:. Учитывая то, что говорят документы, я бы сказал, что вполне разумно предположить, что он продолжит работать и будет вести себя правильно.

0 голосов
/ 26 сентября 2014

Родные технологии рисования, такие как Core Graphics, учитывают текущий масштабный коэффициент. Например, если одно из ваших представлений реализует метод drawRect:, UIKit автоматически устанавливает масштабный коэффициент для этого представления равным масштабному коэффициенту экрана. Кроме того, UIKit автоматически изменяет текущую матрицу преобразования любых графических контекстов, используемых во время рисования, чтобы учитывать масштабный коэффициент вида. Таким образом, любой контент, который вы рисуете в своем методе drawRect:, масштабируется соответствующим образом для экрана основного устройства.

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