Ответ 1
Здесь представлен простой пример перетаскивания, соответствующий этим критериям:
MDDragDropView.h
:
@interface MDDragDropView : NSView {
BOOL isHighlighted;
}
@property (assign, setter=setHighlighted:) BOOL isHighlighted;
@end
MDDragDropView.m
:
@implementation MDDragDropView
@dynamic isHighlighted;
- (void)awakeFromNib {
NSLog(@"[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
[self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, nil]];
}
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender {
NSLog(@"[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
NSPasteboard *pboard = [sender draggingPasteboard];
if ([[pboard types] containsObject:NSFilenamesPboardType]) {
NSArray *paths = [pboard propertyListForType:NSFilenamesPboardType];
for (NSString *path in paths) {
NSError *error = nil;
NSString *utiType = [[NSWorkspace sharedWorkspace]
typeOfFile:path error:&error];
if (![[NSWorkspace sharedWorkspace]
type:utiType conformsToType:(id)kUTTypeFolder]) {
[self setHighlighted:NO];
return NSDragOperationNone;
}
}
}
[self setHighlighted:YES];
return NSDragOperationEvery;
}
И остальные методы:
- (void)draggingExited:(id <NSDraggingInfo>)sender {
[self setHighlighted:NO];
}
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender {
return YES;
}
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
[self setHighlighted:NO];
return YES;
}
- (BOOL)isHighlighted {
return isHighlighted;
}
- (void)setHighlighted:(BOOL)value {
isHighlighted = value;
[self setNeedsDisplay:YES];
}
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
if (isHighlighted) {
[NSBezierPath setDefaultLineWidth:6.0];
[[NSColor keyboardFocusIndicatorColor] set];
[NSBezierPath strokeRect:self.frame];
}
}
@end
Причина prepareForDragOperation:
не вызывается, так это то, что последовательность назначения перетаскивания следует за точным набором шагов, и если предыдущие шаги не реализованы или реализованы, но возвращают тип "остановить операцию перетаскивания" ответ, более поздние методы никогда не достигаются. (В вашем случае, похоже, вы не реализовали метод draggingEntered:
, который должен был бы вернуть что-то, кроме NSDragOperationNone
, чтобы продолжить в последовательности).
Прежде чем отправляться prepareForDragOperation:
, сначала открывается точка перетаскивания сообщений назначения:
Один - (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
.
В зависимости от маски NSDragOperation
, возвращаемой с помощью этого метода, будет вызываться следующее, если оно реализовано в вашем классе:
Несколько - (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
.
В зависимости от маски NSDragOperation
, возвращаемой этим методом, вызывается prepareForDragOperation:
.