【问题标题】:Draw image (as an overlay) on top of drawRect NSView (macOS & ObjC)在 drawRect NSView (macOS & ObjC) 之上绘制图像(作为覆盖)
【发布时间】:2021-12-24 00:23:59
【问题描述】:

我在 drawRect 上有一张我很满意的绘图,我现在正试图从特定路径覆盖图像,我希望它作为叠加层出现在当前绘图之上。有谁知道最好的方法是什么,我希望能够设置此图像的位置和大小。

这可以通过核心图形来完成,还是我应该使用 NSImage 来做到这一点 - 任何能指出我正确方向的人都会感激不尽 :)

【问题讨论】:

  • 如果你可以子类化,你的子类可以在你自己的绘图实现之前或之后调用[super drawRect:] inside (self) drawRect:,使其在前一个实现之上或之下有效。
  • 这对我所需要的非常有帮助!我还有一个问题——我的绘图被翻转了,所以我将 isFlipped 设置为 YES——但是在他的 drawRect 中使用 [super drawRect:] 添加图像,图像被翻转(不正确)。如何使主图翻转但现在图像覆盖在顶部?

标签: objective-c macos core-graphics nsview drawrect


【解决方案1】:

您的NSView drawRect: 方法可以在drawRect: 的子类实现之前或之后调用,这使您可以决定是否更早或稍后执行其他绘图代码,因此最终将高于或低于绘图结果super.

// in subclass
- (void)drawRect:(CGRect)dirtyrect {
    [super drawRect:dirtyrect];  //to draw super below
    // ask for flip state first
    CGFloat yFlip = self.flipped ? -1.0 : 1.0;
    // your additional
    // drawing code here..
    // and do something with yFlip
    // ...
    //[super drawRect:dirtyrect]; //to draw super on top
}

由于视图或图层的flip 状态可能在绘图时受到尊重,因此您必须在进行自己的绘图调用之前检查翻转状态。为此,请输入 self.flippedsuper.flipped 以适应如上所示的视图翻转状态。

但是有很多不同的方法可以混合翻转内容和非翻转内容。
以下代码在创建NSImage 时尊重self.flipped 状态,方法是使用lockFocusFlipped: 方法而不是仅lockFocus 锁定焦点。 还展示了其他API,ps:你不必实现imageRepresentation,下面包含或多或少的伪代码

- (NSImage *)imageRepresentation
{
    //BOOL wasHidden = self.isHidden;
    //CGFloat wantedLayer = self.wantsLayer;
    //self.hidden = NO;
    //self.wantsLayer = YES;
    
    NSImage *image = [[NSImage alloc] initWithSize:self.bounds.size];
    
    // to flip an image according to the views flip state
    //[image lockFocus]; 
    [image lockFocusFlipped:self.flipped]; 

    CGContextRef ctx = [NSGraphicsContext currentContext].CGContext;

    // to flip with CoreGraphics API
    //CGContextScaleCTM(ctx, 1.0, -1.0); // <-- see -1.0?
    //CGContextTranslateCTM(ctx, 1.0, 1.0);
    
    // or Affine Transform API, pseudo code
    //NSAffineTransform *trans = [NSAffineTransform transform];
    //[trans translateXBy:0 yBy:existingSize.height];
    //[trans scaleXBy:1 yBy:-1];
    //[trans concat];
    //[image drawAtPoint:NSZeroPoint fromRect:NSMakeRect(0, 0, newSize.width, newSize.height) operation:NSCompositingOperationSourceOver fraction:1.0];

    //[self.layer renderInContext:ctx]; // <-- CALayer backed view drawing

    [self drawRect:self.bounds.size]; // <-- classic View drawing

    [image unlockFocus];

    //self.wantsLayer = wantedLayer;
    //self.hidden = wasHidden;
    return image;
} 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-04
    • 2012-02-05
    • 2013-06-25
    • 2013-02-16
    • 1970-01-01
    相关资源
    最近更新 更多