2

我有一个 NSView 的自定义子类,它实现拖放以将视图中的图像复制到另一个应用程序。我的类中的相关代码如下所示:

#pragma mark -
#pragma mark Dragging Support
- (NSImage *)imageWithSubviews
{
    NSSize imgSize = self.bounds.size;
    NSBitmapImageRep *bir = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[self frame]];
    [self cacheDisplayInRect:[self frame] toBitmapImageRep:bir];

    NSImage* image = [[NSImage alloc]initWithSize:imgSize];
    [image addRepresentation:bir];

    return image;
}

- (void)mouseDown:(NSEvent *)theEvent
{
    NSSize dragOffset = NSMakeSize(0.0, 0.0); // not used in the method below, but required.
    NSPasteboard *pboard;
    NSImage *image = [self imageWithSubviews];
    pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
    [pboard declareTypes:[NSArray arrayWithObject:NSTIFFPboardType]
                   owner:self];

    [pboard setData:[image TIFFRepresentation]
            forType:NSTIFFPboardType];

    [self dragImage:image
                 at:self.bounds.origin
             offset:dragOffset
              event:theEvent
         pasteboard:pboard
             source:self
          slideBack:YES];

    return;
}

#pragma mark -
#pragma mark NSDraggingSource Protocol

- (NSDragOperation)draggingSession:(NSDraggingSession *)session sourceOperationMaskForDraggingContext:(NSDraggingContext)context
{
    return NSDragOperationCopy;
}

- (BOOL)ignoreModifierKeysForDraggingSession:(NSDraggingSession *)session
{
    return YES;
}

在我调整主窗口大小之前,这将按预期工作。主窗口仅以相同的增量增加大小/宽度,以在此视图中保持适当的比例。调整窗口大小时,视图会在屏幕上正确显示其内容。

当我将窗口大小调整超过大约 + 25% 时,问题就出现了。虽然它仍按预期显示,但被拖出的图像(例如,进入 Pages)已损坏。它似乎在其自身顶部重复了该图像的一部分。

这是它通常的样子:

正常外观

这是在调整主窗口大小以使其变大后拖动到 Pages 时的样子(缩小到此处显示 - 想象它是第一张图像大小的 2-3 倍): 腐败的外表

请注意,我用虚线矩形突出显示了损坏区域。

还有一些注意事项:我设置了边界,NSMakeRect(-200,-200,400,400)因为它使对称绘图更容易一些。当窗口调整大小时,我重新计算边界以将 0,0 保持在 NSView 的中心。NSView 总是方形的。

最后,Apple 文档为should中的bitmapImageRep参数声明了以下内容cacheDisplayInRect:toBitmapImageRep:

一个 NSBitmapImageRep 对象。为了像素格式的兼容性,应该从 bitmapImageRepForCachingDisplayInRect: 中获得 bitmapImageRep。

我试过使用bitmapImageRepForCachingDisplayInRect:,但我看到的只是图像右上象限中金字塔的左下象限。这让我觉得我需要为捕获添加偏移量bitmapImageRep,但我一直无法确定如何做到这一点。

这是imageWithSubviews我尝试时的代码:

- (NSImage *)imageWithSubviews
{
    NSSize imgSize = self.bounds.size;
    NSBitmapImageRep *bir = [self bitmapImageRepForCachingDisplayInRect:[self bounds]];
    [self cacheDisplayInRect:[self bounds] toBitmapImageRep:bir];

    NSImage* image = [[NSImage alloc]initWithSize:imgSize];
    [image addRepresentation:bir];

    return image;
}

这就是结果图像的显示方式:

只有左下象限显示在右上角

这是在右上角绘制的左下象限的视图。

放大窗口后从 NSView 拖动时导致损坏的原因是什么?如何解决这个问题和/或更改我上面列出的方法的实现以避免问题?


更多信息:

当我将imageWithSubviews方法更改为:

- (NSImage *)imageWithSubviews
{

    NSSize imgSize = self.bounds.size;
    NSBitmapImageRep *bir = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[self frame]];
    [self cacheDisplayInRect:[self bounds] toBitmapImageRep:bir];

    NSImage* image = [[NSImage alloc]initWithSize:imgSize];
    [image addRepresentation:bir];

    return image;
}

我得到一个没有缩放的损坏图像,其中图像的左下象限再次绘制在右上象限的顶部,如下所示:

象限被覆盖

我到底做错了什么?


解决方案:

虽然它没有解决使用 绘图的核心问题NSBitmapImageRep,但以下内容-imageWithSubviews可以防止损坏并输出正确的图像:

- (NSImage *)imageWithSubviews
{
    NSData *pdfData = [self dataWithPDFInsideRect:[self bounds]];
    NSImage* image = [[NSImage alloc] initWithData:pdfData];

    return image;
}
4

1 回答 1

1

根据上面的一些调试,我们确定问题出在-imageWithSubviews.

与其使用 为视图生成图像数据-cacheDisplayInRect:toBitmapImageRep:,不如将其更改为-dataWithPDFInRect:解决问题。

于 2012-12-12T18:27:19.240 回答