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