代码之家  ›  专栏  ›  技术社区  ›  rboisjoly

drawLayer:inContext:使用Layer Hosting NSView时在内容上绘制背景

  •  0
  • rboisjoly  · 技术社区  · 12 年前

    这让我有些痛苦。。。

    我希望在我的应用程序中使用层托管视图,但我遇到了这个奇怪的问题。

    这里有一个简单的例子。只需在Xcode中创建一个新项目并在AddDelegate中输入以下内容即可实现:(在将QuartzCore添加到项目中之后):

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

    我还实现了以下CALayer Delegate方法:

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

    如果我运行这段代码,我可以看到子视图被添加到windows contentView(黄色的大矩形)中,我假设它是一个层托管视图。。。我可以看到椭圆形是用蓝色画的,但它是 在下面 黄色矩形,它的原点在主窗口中的(0,0)。。。就好像它实际上并没有被绘制在黄色层的内部。

    我猜测要么我的观点不是真正的层托管,要么传递给层的上下文是错误的。。。但为什么它会在下面呢?

    我一定做错了什么。。。

    为了继续怪异,如果我在图层中添加CABasicAnimation,如下所示:

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

    黄色背景将设置动画,围绕其中心旋转,但蓝色椭圆将在层的框架内正确绘制(但也在外部,在窗口的原点处,因此它在那里两次),但不会设置动画。当然,我希望椭圆能和层的其他部分一起旋转。

    我做了这个项目 available here 为那些愿意伸出援手的人。

    雷诺

    1 回复  |  直到 11 年前
        1
  •  1
  •   rboisjoly    12 年前

    明白了。我很困惑,在这种情况下调用的上下文是CGContextRef,而不是NSGraphicsContext!

    我似乎可以通过从CGContextRef设置NSGraphicsContext来获得所需的结果:

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

    //在此处插入绘图代码

    [NSGraphicsContext restoreGraphicsState];