Подтвердить что ты не робот

Когда мне нужно установить свойство contentsScale CALayer?

В documentation Apple заявляет, что вам нужно учитывать масштабный коэффициент слоя, когда он:

  • Создает дополнительные слои Core Animation с различными масштабными коэффициентами и компонует их в свой собственный контент.
  • Устанавливает свойство содержимого слоя основной анимации напрямую

Последнее утверждение мне не совсем понятно. Они также говорят:

Приложения, которые используют уровни Core Animation, чтобы обеспечить может потребоваться корректировка кода чертежа для учета масштаба факторы. Обычно, когда вы рисуете свои виды drawRect: метод или в drawLayer: inContext: метод делегата слоев, система автоматически настраивает графический контекст для учета масштаба факторы.

Нормально или всегда? и это справедливо только для видимого поддерживаемого слоя поддержки или каждого слоя, который я добавляю в качестве подуровня для слоя подложки? потому что они также говорят:

Если ваше приложение создает слои без соответствующего вида, каждый новый масштабный коэффициент объектов уровня устанавливается на 1.0. Если ты не измените масштабный коэффициент, и если впоследствии вы нарисуете слой на экрана с высоким разрешением, содержимое слоев автоматически масштабируется для компенсации разницы в масштабных коэффициентах. Если вы не хотите содержимое масштабируется, вы можете изменить масштабный коэффициент слоев на 2.0, но если вы сделаете это без предоставления контента с высоким разрешением, ваш существующий контент может оказаться меньше, чем вы ожидали. Исправить эта проблема, вам необходимо предоставить контент с более высоким разрешением для вашего слой.


У меня возникли трудности с представлением слоя без представления, я могу представить себе иерархию слоев, но как только я хочу их отобразить, я должен добавить его в качестве подъяречности слоя поддержки представления или использовать некоторые другие способы их использования (например, создание и просто просмотр в контексте)?

Механизм компоновки Core Animations смотрит на contentsScale свойства каждого слоя, чтобы определить, содержит ли содержимое этого слоя необходимо масштабировать во время компоновки. Если ваше приложение создает слоев без соответствующего вида, каждая новая шкала объектов Сначала коэффициент устанавливается на 1.0. Если вы не измените эту шкалу фактор, и если впоследствии вы нарисуете слой с высоким разрешением экрана, содержимое слоев автоматически масштабируется для компенсации за разницу в масштабных факторах. Если вы не хотите, чтобы содержимое для масштабирования вы можете изменить коэффициент масштабирования слоев на 2,0, но если вы делаете это без предоставления контента с высоким разрешением, существующих контент может оказаться меньше, чем вы ожидали. Чтобы исправить это проблема, вам нужно предоставить контент с более высоким разрешением для вашего слоя.

Что это значит? Когда я делаю что-то вроде этого layer.contents = (id)image.CGImage, мне нужно установить contentsScale.
Нужно ли мне также устанавливать его, когда мой слой рисует его содержимое, вызывая метод делегата drawLayer:inContext:, а слой не является поддерживающим слоем представления?

4b9b3361

Ответ 1

re: содержимое слоя через -drawRect: или -drawLayer: inContext:

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

Всегда. Когда эти методы вызывают, в текущем контексте уже будет применен коэффициент масштабирования. Например, если ваш слой равен 10pt x 10pt, он имеет границы {0,0,10,10}, независимо от содержимогоScale. Если contentsScale = 2 (например, вы находитесь на сетчатке), это фактически 20x20 пикселей. CALayer уже установит хранилище резервных копий 20x20px и применит масштабный коэффициент CGContextScaleCTM (контекст, 2, 2).

Это так, что вы можете сделать свой рисунок в своем концептуальном пространстве 10x10 в любом случае, но резервное хранилище удваивается, если пиксели удваиваются.

У меня возникают трудности с представлением слоя без представления, я могу представить себе иерархию слоев, но как только я хочу их отобразить, я должен добавить его как подчисток вид слоя поддержки, или существуют некоторые другие способы их использования (например, создание и просто renderring в контексте)?

Вы можете создавать их, добавлять их в качестве подслоев и либо устанавливать их делегат на объект, где вы реализуете -drawLayer: inContext:, или вы можете напрямую установить содержимое слоя. В iOS UIView является довольно мелкой оболочкой вокруг CALayer, поэтому обычно имеет смысл создавать subviews вместо прямого создания подслоев, поэтому вы не знакомы с этим использованием. В OS X, NSW с поддержкой слоев является большой и сложной оболочкой вокруг CALayer, поэтому имеет смысл сделать целые иерархии слоев в пределах одного представления.

Что это значит? Когда я делаю что-то вроде этого layer.contents = (id) image.CGImage Мне нужно установить contentsScale.

Да. Но то, что этот отрывок в документации говорит вам, заключается в том, что если вы хотите не выглядеть уродливым, то 10pt x 10pt-слой с содержимымScale 2, нуждается в содержимом 20px x 20px. То есть Вы должны обратить внимание на contentsScale слоя, когда вы непосредственно устанавливаете содержимое слоя, если хотите избежать масштабирования артефактов.

Мне также нужно установить его, когда мой слой рисует его содержимое, вызывая метод делегата drawLayer: inContext: а слой не является поддерживающим слоем представления?

Да. Если вы сами создаете слои (не создаваемые с помощью UIView), вам необходимо установить их масштаб вручную. Обычно это просто layer.contentsScale = [[UIScreen mainScreen]]. (Опять же, в OS X это немного сложнее, так как экраны могут приходить и уходить во время работы.)

Ответ 2

В то время как слой почти всегда используется внутри представления, этот слой, возможно, был создан ad-hoc и добавлен в качестве подуровня слоя представления или назначен как другая маска слоя. В обоих случаях свойство contentsScale должно быть установлено. Например:

UIView *myMaskedView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
CALayer *myMaskLayer = [CALayer new];
myMaskLayer.frame = myMaskedView.bounds;
UIImage *maskImage = [UIImage imageNamed:@"some_image"];
myMaskLayer.contents = (id)maskImage.CGImage;
myMaskLayer.contentsScale = maskImage.scale;
myMaskedView.layer.mask = myMaskLayer;

Вы также можете создать иерархию слоев для выполнения анимаций, не используя каждый слой для возврата к представлению:

UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];

CALayer *sublayerA = [CALayer new];
sublayerA.contentsScale = myView.layer.contentsScale;
[myView.layer addSublayer:sublayerA];

CALayer *sublayerB = [CALayer new];
sublayerB.contentsScale = myView.layer.contentsScale;
[myView.layer addSublayer:sublayerB];

// Continue adding layers   

Это особенно важно для устройств Retina, которые имеют собственную экранную шкалу 2,0; слой со шкалой по умолчанию 1.0 будет отображать заметную пикселизацию.

Ответ 3

В OS X вы в основном

  • захватить ваши окна -backingScaleFactor
  • установите для каждого (!) слоя -contentsScale этот масштабФактор
  • реализовать -layer:shouldInheritContentsScale:fromWindow: в контроллере
  • установите для каждого уровня -delegate этот контроллер

Я знаю, что он нахмурился здесь, на SO, чтобы просто ссылаться на внешний URL-адрес, но его трудно описать. Вот код, который корректно работает для меня в отношении масштабных факторов:

https://github.com/JanX2/ScrollingAboutWindow

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