我有一个NSView的自定义子类,实现拖放操作以将视图中的图像复制到另一个应用程序。我的班级中的相关代码如下所示:从缩放视图拖动时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%时,问题就出现了。虽然它仍然按预期显示,但拖拽它的图像(例如页面)已损坏。它看起来有一部分图像重复在其本身之上。
下面是它看起来像正常:
这里是个什么样子,当拖动到页面调整主窗口后,使之大(缩小显示在这里像 - 想象在2-3倍大小的第一个图像):
请注意,我用虚线矩形突出显示腐败区域。
还有一些注意事项: 我有我的边界像NSMakeRect(-200,-200,400,400)
设置,因为它使对称绘图更容易一些。当窗口调整大小时,我重新计算界限以保持0,0在NSView的中心。 NSView总是方形的。
最后,苹果的文档说明其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;
}
你不使用NSImageView的任何原因? – paulmelnikow
您是否检查过是否多次调用“-imageWithSubviews”? – paulmelnikow
我检查过了,'-imageWithSubviews'只被调用一次。金字塔是根据用户输入(未导入的照片)动态绘制的。我从来没有考虑过使用'NSImageView',我不知道为什么这将是一个更好的选择。对我来说这很奇怪,只有当我将窗口大小放大到超过某个阈值时才会发生,然后才会在金字塔上拖动。它在窗口/视图本身中显得很好。 – Clay