我有一個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