views:

321

answers:

2

I'm working on a Cocoa project using Core Animation and I've got a custom view that is displayed in two windows. It always shows up in one window, but sometimes does not show up in the other window when I start up the application. So far as I can tell, it is completely random. Here is the code I call when the view is initialized. It gets to this code whether or not the view appears.

[self setWantsLayer:YES];

root = [self layer]; // root is a CALayer

root.layoutManager = [CAConstraintLayoutManager layoutManager];
root.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;

[root setBackgroundColor:CGColorGetConstantColor(kCGColorBlack)];

[self setNeedsDisplay:YES];

Why would the view show up sometimes and other times it does not?

EDIT: Would it make a difference if I create the root CALayer on it's own instead of setting it to the view's "layer" like I'm currently doing?

A: 

When you say that it's displayed in two windows, do you mean that there are two instances of the view's class that are in two windows, or do you mean that you've tried to put the same actual view instance into two windows? A given view can only be part of a single view hierarchy. Installing it into one will remove it from the hierarchy it was in.

Rob Napier
There are two instances of the same custom (sub-classed) view, one in each window. They were both created by dragging a custom view onto the window in Interface Builder, then setting the custom class for each.
Austin
+1  A: 

Looks like there was a pretty simple solution, but it was not well documented. Instead of setting root to the sub-classed view's layer, I create root as a new CALayer and then set the view's layer to root. The code from the original question now looks like:

// self is the sub-classed NSView
[self setWantsLayer:YES];

// Set root to a new CALayer
root = [CALayer layer];

root.layoutManager = [CAConstraintLayoutManager layoutManager];
root.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;

[root setBackgroundColor:CGColorGetConstantColor(kCGColorBlack)];

// Set the view's layer to root
[self setLayer:root];

I'm thinking that sometimes when my initialization code was called, the view had not initialized the layer associated with itself, so root was not getting properly assigned. This is just a hunch, but making the above changes has resolve my problem with the view not always displaying.

Austin