How to interact with layer-supported views on Mac

I am developing a user interface containing several labels and text fields. I would like a UI style as follows:

  • setting a wallpaper to represent the contents of my NSWindow
  • add custom icon in background in upper left corner

I solved the first problem by creating a layer view of the content, as described in Apple's NSView :

A hidden layer is a view that is supported by a Core Animation layer. Any drawing made with a view is cached in the background layer. You set up the view to support the layer by simply pressing setWantsLayer: with a value of YES . The view class will automatically create a support layer for you, and you use the drawing mechanisms of the view classes. When using layers with layer support, you should never interact directly with the layer.

A hosting layer is a view containing a Core Animation layer that you intend to manipulate directly. You create a placement-level view by creating an instance of a class class in the Core Animation class and setting this layer using the views setLayer: method. After that, you call setWantsLayer: with a value of YES . When using a layer-level layout view, you should not rely on the drawing view, nor should you add subviews to the layout level view.

and then generating a CGColorRef from CGPattern , which draws my CGImage :

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

To set the background image as a template, I used the answer how to draw the contents of CALayer here on SO to complete the first task.

However, for the second task, adding an icon, I used the following code:

 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 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]; 

Questions

  • I'm not sure that I am violating Apple’s restrictions on layers that should not interact directly with the layer. When adjusting the background color of a layer, do I interact directly with the layer or am I mistaken here?
  • I have a bad idea of ​​interacting with a layer hierarchy in layer-supported mode and inserting a new layer, just like for my second task. Is this possible or also violates Apple’s principles? I want to note that this content view, of course, has several sub-tasks, such as labels, text view and buttons.
  • It seems to me that just using one level of NSView hosting seems the purest solution. All text labels can be added as CATextLayers , etc. However, if I understand the Apple documentation correctly, I can no longer add controls to the view. Do I have to code all the controls in the custom CALayers to make it work? It seems like reinventing the wheel de luxe. I also don’t know how to encode NSTextField in CoreAnimation only.

Any advice on how to share design user interfaces with CoreAnimation and standard controls is welcome.

Please note that I am talking about Mac here.

+4
source share
2 answers

IMHO layer support not required:

for 1. I draw an image of the image

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

for 2. add NSImageView as a subset of content

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

on mac some species do not respond well if-layer :: for example. pdfview

+1
source

Create supervisor container A. Add subview B in for all your NSView needs (buttons, etc.). Add subview C in for all your Core Animation needs.

Edit: Better yet: use supervisor A for all your NSView needs and one subheading C for your Core Animation needs, completely ignoring view B.

0
source