Pregunta

This is causing me some pain...

I wish to use layer-hosting views in my app and I'm having this weird problem.

Here is a simple example. Simply implemented by creating a new project in Xcode and entering the following in the AddDelegate: (after adding QuartzCore to the project):

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    NSView *thisView = [[NSView alloc] initWithFrame:CGRectInset([self.window.contentView bounds], 50, 50)];

    [thisView setLayer:[CALayer layer]];
    [thisView setWantsLayer:YES];
    thisView.layer.delegate = self;

    thisView.layer.backgroundColor = CGColorCreateGenericRGB(1,1,0,1);
    thisView.layer.anchorPoint = NSMakePoint(0.5, 0.5);
    [self.window.contentView addSubview:thisView];

    //Create custom content
    [thisView.layer display];
}

I also implement the following CALayer Delegate method:

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
    [[NSColor blueColor] setFill];
    NSBezierPath *theBez = [NSBezierPath bezierPathWithOvalInRect:layer.bounds];
    [theBez fill];
}

If I run this code, I can see the subview being added to the windows contentView (big yellow rectangle), and I'm supposing it is a layer-hosting view... and I can see the oval being drawn in blue, but it is underneath the yellow rectangle, and it's origin is at (0,0) in the main Window... it is like it is not actually being drawn inside the yellow layer.

I'm guessing either my view is not really layer-hosting, or that the context being passed to the layer is wrong... but why would it be underneath?

I must be doing something wrong...

To continue with the weirdness, if I add a CABasicAnimation to the layer, like so:

CABasicAnimation *myAnimation = [CABasicAnimation animation];
myAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
myAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
myAnimation.fromValue = [NSNumber numberWithFloat:0.0];
myAnimation.toValue = [NSNumber numberWithFloat:((360*M_PI)/180)];

myAnimation.duration = 1.0;
myAnimation.repeatCount = HUGE_VALF;

[thisView.layer addAnimation:myAnimation forKey:@"testAnimation"];
thisView.layer.anchorPoint = NSMakePoint(0.5, 0.5);

The yellow background gets animated, rotating about its center, but the blue ellipse gets drawn correctly inside the layer's frame (but also outside, at the origin of the Window, so it is there twice) but does not animate. I would expect the ellipse to rotate with the rest of the layer of course.

I have made this project available here for those willing to give a hand.

Renaud

¿Fue útil?

Solución

Got it. I was confused by the fact that the context being called in this situation is a CGContextRef, not an NSGraphicsContext!

I seem to be able to get the result I need by setting the NSGraphicsContext from the CGContextRef:

NSGraphicsContext *gc = [NSGraphicsContext graphicsContextWithGraphicsPort:ctx flipped:NO];
[NSGraphicsContext saveGraphicsState];

[NSGraphicsContext setCurrentContext:gc];

//Insert drawing code here

[NSGraphicsContext restoreGraphicsState];
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top