ビュー内の画像を別のアプリケーションにコピーするためのドラッグ/ドロップを実装する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に)ドラッグされた画像は破損しています。この画像の一部がそれ自体の上に繰り返されているように見えます。
通常は次のようになります。
メインウィンドウのサイズを変更して大きくした後、ページにドラッグすると次のようになります(ここに表示するために縮小しました。最初の画像の2〜3倍のサイズで想像してください)。
破損した領域を点線の長方形で強調表示したことに注意してください。
さらにいくつかの注意事項:NSMakeRect(-200,-200,400,400)
対称描画が少し簡単になるため、境界を次のように設定しました。ウィンドウのサイズが変更されたら、境界を再計算して、NSViewの中央に0,0を維持します。NSViewは常に正方形です。
最後に、Appleのドキュメントには、 shouldのbitmapImageRep
パラメータについて次のように記載されています。cacheDisplayInRect:toBitmapImageRep:
NSBitmapImageRepオブジェクト。ピクセル形式の互換性のために、bitmapImageRepはbitmapImageRepForCachingDisplayInRect:から取得されている必要があります。
を使用してみまし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;
}