我有一个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)
,因为它使对称绘图更容易一些。当窗口调整大小时,我重新计算边界以保持NSView中心的0,0。 NSView总是正方形。
最后,Apple文档声明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;
}
答案 0 :(得分:1)
根据上面的一些调试,我们确定问题出在-imageWithSubviews
。
不是使用-cacheDisplayInRect:toBitmapImageRep:
为视图生成图像数据,而是将其更改为-dataWithPDFInRect:
修复了问题。