私には 2 つの見方があります。1. 1 つのビューには、画像を含む NSImageViews のグリッドがあります。2. もう一方のビューには、ドラッグした画像を配置できる場所のグリッドがあります。
私は仕事を引きずっていると思います。ビュー 1 から画像をクリック アンド ドラッグすると問題なく動作しますが、配置しようとすると、ソース画像のパスが、プロジェクトの一部ではないデスクトップ上の画像になります。以下のコードの結果は、carryedData = nil ですが、NSLog でいくつかのテストを行ったところ、デスクトップではないプロジェクト外のイメージのパスが送信されていることがわかりました。
以下は、私が実装した D&D プロトコル メソッドの一部です。myDragState は、ドラッグが現在ホバリングしているグリッド スペースを強調表示するために使用する列挙型です。
初期化中...
[self registerForDraggedTypes:[NSImage imagePasteboardTypes]];
myDragState = dragStateNone;
次に、プロトコルメソッド
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) == NSDragOperationGeneric)
{
myDragState = dragStateOver;
[self setNeedsDisplay];
return NSDragOperationGeneric;
}
else
{
return NSDragOperationNone;
}
}
- (void)draggingExited:(id <NSDraggingInfo>)sender
{
//turn off focus ring
myDragState = dragStateExited;
[self setNeedsDisplay];
}
- (void)draggingEnded:(id <NSDraggingInfo>)sender { }
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
{
return YES;
}
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
NSPasteboard *paste = [sender draggingPasteboard];
//gets the dragging-specific pasteboard from the sender
NSArray *types = [NSArray arrayWithObjects:NSTIFFPboardType, nil];
//a list of types that we can accept
NSString *desiredType = [paste availableTypeFromArray:types];
NSData *carriedData = [paste dataForType:desiredType];
if (nil == carriedData)
{
//the operation failed for some reason
NSRunAlertPanel(@"Paste Error", @"Sorry, but the past operation failed", nil, nil, nil);
myDragState = dragStateNone;
[self setNeedsDisplay];
return NO;
}
else
{
//the pasteboard was able to give us some meaningful data
if ([desiredType isEqualToString:NSTIFFPboardType])
{
NSLog(@"TIFF");
//we have TIFF bitmap data in the NSData object
NSImage *newImage = [[NSImage alloc] initWithData:carriedData];
[self setImage:newImage];
myDragState = dragStateSet;
}
else
{
//this can't happen
//NSAssert(NO, @"This can't happen");
NSLog(@"Other type");
myDragState = dragStateNone;
[self setNeedsDisplay];
return NO;
}
}
//redraw us with the new image
return YES;
}
- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
{
//re-draw the view with our new data
[self setNeedsDisplay:YES];
}
- (void)drawRect:(NSRect)dirtyRect
{
// Drawing code here.
NSRect ourBounds = [self bounds];
if (myDragState == dragStateSet)
{
NSImage *image = [self image];
[super drawRect:dirtyRect];
[image compositeToPoint:(ourBounds.origin) operation:NSCompositeSourceOver];
}
else if (myDragState == dragStateOver)
{
[[NSColor colorWithDeviceRed:1.0f green:1.0f blue:1.0f alpha:0.4f] set];
[NSBezierPath fillRect:ourBounds];
}
else {
//draw nothing
}
}
編集:だから私はこれを理解しました。問題は実際にはソースにありました。PBoard に正しくコピーしていませんでした。そのための私のコードは次のとおりです。
NSPasteboard *zPasteBoard = [NSPasteboard pasteboardWithName:NSDragPboard];
[zPasteBoard declareTypes:[NSArray arrayWithObject:NSTIFFPboardType] owner:self];
[zPasteBoard setData:[tileImageView.image TIFFRepresentation] forType:NSTIFFPboardType];
ただし、画像が表示されると、奇妙な効果が得られます。画像が目的の画像ビューに配置されると、サイズが変更されますが、ドラッグ可能なより大きなバージョンも表示されます。そのため、画像ビューで2つの画像を取得しています。