Как взаимодействовать со слоями на Mac - PullRequest
4 голосов
/ 05 мая 2011

Я проектирую пользовательский интерфейс, содержащий несколько меток и текстовых полей.Я хотел бы стилизовать пользовательский интерфейс следующим образом:

  1. , установив шаблон фона для представления содержимого моего NSWindow
  2. , добавив пользовательский значок на фон в верхнем левом углу.

Первую проблему я решил, сделав представление контента слоистым представлением , как описано в Документация Apple NSView:

Представление на основе слоя - это представление, которое поддерживается слоем Core Animation.Любой рисунок, сделанный представлением, кэшируется в резервном слое.Вы настроили представление на основе слоев, просто вызвав setWantsLayer: со значением YES.Класс представления автоматически создаст для вас вспомогательный слой, и вы будете использовать механизмы рисования класса представления. При использовании представлений со слоем никогда не следует напрямую взаимодействовать со слоем.

Представление с размещением слоев - это представление, содержащее слой Core Animation, которым вы намерены манипулировать напрямую.Вы создаете представление размещения слоя, создавая экземпляр класса слоя Core Animation и устанавливая этот слой, используя метод представления setLayer:.После этого вы вызываете setWantsLayer: со значением YES. При использовании представления с размещением слоев вы не должны полагаться на представление для рисования и не должны добавлять подпредставления к представлению с размещением слоев.

, а затем генерировать CGColorRef из CGPattern, который рисует мой CGImage:

NSView *mainView = [[self window]contentView];
[mainView setWantsLayer:YES];

Чтобы установить фоновое изображение в качестве шаблона, я использовал ответ из Как разбить содержимое CALayer здесь, на SO, чтобы выполнить первое задание.

Однако для второго задания, добавив значок, я использовал следующий код:

CGImageRef iconImage = NULL;
NSString *path = [[NSBundle mainBundle] pathForResource:@"icon_128" ofType:@"png"];
if(path != nil) {
    NSURL *imageURL = [NSURL fileURLWithPath:path];
    provider = CGDataProviderCreateWithURL((CFURLRef)imageURL);
    iconImage = CGImageCreateWithPNGDataProvider(provider,NULL,FALSE,kCGRenderingIntentDefault); 
    CFRelease(provider);
}
CALayer *iconLayer = [[CALayer alloc] init];
// layer is the mainView's layer
CGRect layerFrame = layer.frame;
CGFloat iconWidth = 128.f;
iconLayer.frame = CGRectMake(0.f, CGRectGetHeight(layerFrame)-iconWidth, 128.f, 128.f);
iconLayer.contents = (id)iconImage;
CGImageRelease(iconImage);
[layer insertSublayer:iconLayer  atIndex:0];
[iconLayer release];

Вопросы

  1. Я не уверен, что нарушаю ограничения Apple относительно представлений со слоями , которые запрещают вам напрямую взаимодействовать со слоем.При настройке цвета фона слоя Я напрямую взаимодействую со слоем, или я здесь ошибаюсь?
  2. У меня плохое предчувствие взаимодействия с иерархией слоев с поддержкой слоя просмотреть непосредственно и вставить новый слой, как я сделал для моей второй задачи.Возможно ли это или также нарушает правила Apple?Я хочу отметить, что у этого представления контента, конечно, есть несколько подпредставлений, таких как ярлыки, текстовое представление и кнопки.
  3. Мне кажется, что просто используется один layer-hosting NSView кажется самым чистым решением.Все текстовые метки могут быть добавлены как CATextLayers и т. Д. Однако, если я правильно понимаю документацию Apple, я не могу больше добавлять элементы управления в представление.Должен ли я сам кодировать все элементы управления в пользовательском CALayers, чтобы он заработал?Звучит как изобретать велосипед люкс .Я также понятия не имею, как можно кодировать NSTextField исключительно в CoreAnimation.

Любой совет о том, как ценится сплит-проектирование пользовательских интерфейсов с CoreAnimation и стандартными элементами управления.

Обратите внимание, что я говорю о Mac здесь.

Ответы [ 2 ]

1 голос
/ 08 ноября 2012

слой не требуется ИМХО:

для 1. Я делаю шаблон изображения

NSImage *patternImage = [NSImage imageNamed:@"pattern"];
[window setBackgroungdColor:[NSColor colorWithPatternImage:patternImage]];

для 2. добавить NSImageView в качестве подпредставления viewview

NSImageView *v = ...
[[window contentView] addSubview:v]; 

на mac некоторые представления не реагируют хорошо, если слой поддерживается :: например pdfview

0 голосов
/ 05 мая 2011

Создайте контейнер суперпредставления A. Добавьте подпредставление B в A для всех ваших потребностей NSView (кнопки и т. Д.).Добавьте подпредставление C к A для всех ваших потребностей Core Animation.

Редактировать: Еще лучше: используйте superview A для всех ваших потребностей NSView и одно subview C для ваших потребностей Core Animation, полностью игнорируя представление B.

...