I created an empty Cocoa app on Xcode for OS X, and added:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
self.view = [[NSView alloc] initWithFrame:NSMakeRect(100, 100, 200, 200)];
self.view.wantsLayer = YES;
self.view.layer = [CALayer layer];
self.view.layer.backgroundColor = [[NSColor yellowColor] CGColor];
self.view.layer.anchorPoint = CGPointMake(0.5, 0.5);
self.view.layer.transform = CATransform3DMakeRotation(30 * M_PI / 180, 1, 1, 1);
[self.window.contentView addSubview:self.view];
}
But the rotated layer's background is clipped by the view's bounding area:
I thought since some version of OS X and iOS, the view won't clip the content of its subviews and will show everything inside and outside? On iOS, I do see that behavior, but I wonder why it shows up like that and how to make everything show? (I am already using the most current Xcode 4.4.1 on Mountain Lion).
(note: if you try the code above, you will need to link to Quartz Core, and possibly import the quartz core header, although I wonder why I didn't import the header and it still compiles perfectly)
It turns out that if the line:
((NSView *)self.window.contentView).wantsLayer = YES;
is added to the very beginning, then it works as expected:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
((NSView *)self.window.contentView).wantsLayer = YES;
self.view = [[NSView alloc] initWithFrame:NSMakeRect(200, 200, 200, 200)];
self.view.wantsLayer = YES;
self.view.layer.backgroundColor = [[NSColor yellowColor] CGColor];
[self.window.contentView addSubview:self.view];
self.view.layer.anchorPoint = CGPointMake(0.5, 0.5);
self.view.layer.transform = CATransform3DMakeRotation(30 * M_PI / 180, 0, 0, 1);
}
So it looks like if all the views are made to be layer backed, then it works the same as it does on iOS. (If there is a quick way to make all views layer backed automatically, that'd be good).
the anchorPoint
line cannot be moved before addSubview
line, or else it is incorrect, although I wonder why that would make any difference.
The line self.view.layer = [CALayer layer];
can be removed if window.contentView
is layer backed. Both the contentView and self.view
don't need to set the layer, and I wonder why too.
The transform
line cannot be before the addSubview
line, or else it won't rotate, and I wonder why too.
The third thing is that, I thought if I go to Interface Builder and make the contentView a class of ContentView
(subclassing NSView
), and in its init
method, do a self.wantsLayer = YES;
, then it would work too, but it does not.
But anyway, the code above works, and I will update the reasons above why when I find out more.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With