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に)ドラッグされた画像は破損しています。この画像の一部がそれ自体の上に繰り返されているように見えます。

通常は次のようになります。

通常の外観

メインウィンドウのサイズを変更して大きくした後、ページにドラッグすると次のようになります(ここに表示するために縮小しました。最初の画像の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;
}
4

1 に答える 1

1

上記のデバッグに基づいて、問題はにあると判断しました-imageWithSubviews

を使用してビューの画像データを生成する代わりに、-cacheDisplayInRect:toBitmapImageRep:それを変更して-dataWithPDFInRect:問題を修正しました。

于 2012-12-12T18:27:19.240 に答える