Технические вопросы и ответы QA1866

IKImageView с перетаскиванием

Q: IKImageView имеет возможность получить, перетаскивает. Как я могу добавить, что возможность выполнить выход перетаскивает? Что разновидность должна я использовать для перетаскивания изображений к экземплярам IKImageView?

A: IKImageView обеспечивает обработчики перетаскивания для получения изображений посредством NSFilenamesPboardType разновидность области монтажа. Они в состоянии получить, перетаскивают файлы образа, но у них нет созданного в возможности обеспечить, выход перетаскивает. Можно добавить что возможность сами путем добавления -mouseDown: (или -mouseMoved:) обработчик к подклассу IKImageView то, что можно использовать для инициирования выхода, перетаскивает.

NSFilenamesPboardType требует специальной обработки, потому что она должна сослаться на файлы образа, экономил на диске и не то же как просто добавляющий данные изображения к области монтажа. Если требуется предоставить данные перетаскивания экземплярам IKImageView в Ваших собственных окнах или в окнах другого приложения, тогда необходимо будет реализовать собственный выход, перетаскивает использование NSFilenamesPboardType разновидность и управляет файлами самостоятельно.

Упоминание ниже показывает пример того, как инициировать перетаскивание изнутри -mouseDown: обработчик на подклассе IKImageView это позволит Вам перетаскивать изображения к другим экземплярам IKImageView.

Перечисление 1  , Инициирующее исходящее перетаскивание от IKImageView

- (void)mouseDown:(NSEvent*)event
{
  NSLog(@"%s",__FUNCTION__);
 
  // if there is an image to drag around...
  if ( [self image] != NULL ) {
 
    // generate a file name, path, and url
    NSString *fileName = [NSString stringWithFormat:@"%@-%@",
        [[NSProcessInfo processInfo] globallyUniqueString],
        @"dragfile.png"];
    NSString *filePath =
        [NSTemporaryDirectory() stringByAppendingPathComponent:fileName];
    NSURL *fileURL = [NSURL fileURLWithPath:filePath];
 
 
    // create a temporary file to house the image
    CGImageDestinationRef destination = CGImageDestinationCreateWithURL(
        (__bridge CFURLRef) fileURL, kUTTypePNG, 1, NULL);
    if ( destination != NULL ) {
      CGImageDestinationAddImage(destination, [self image], nil);
      if ( CGImageDestinationFinalize(destination) ) {
 
        // add a reference to the file path to the drag pasteboard
        // using the special NSFilenamesPboardType type
        NSPasteboard *dragPasteboard =
            [NSPasteboard pasteboardWithName:NSDragPboard];
        [dragPasteboard declareTypes:@[NSFilenamesPboardType] owner:nil];
        [dragPasteboard setPropertyList:@[filePath]
            forType:NSFilenamesPboardType];
 
        // calculate the drag image and position
        NSImage* dragImage = [[NSWorkspace sharedWorkspace]
            iconForFile:filePath];
        NSPoint dragPosition = [self convertPoint:[event locationInWindow]
            fromView:nil];
 
        // perform the drag operation
        // this method call runs synchronously
        // so we can delete the file after it is
        // compete
        [self dragImage:dragImage
            at:dragPosition
            offset:NSZeroSize
            event:event
            pasteboard: dragPasteboard
            source:self
            slideBack:YES];
 
        // the above dragImage method runs synchronously, so when we return
        // here the drag operation is technically complete, the receiver will
        // have been called, etc.... However, some receivers will only have
        // made note of the drag operation and they may not be finished
        // with the file just yet so it's important not to delete it right away.
        // In this sample we maintain the file on disk for a short time
        // before deleting it.
        const uint64_t kSecondsToKeepFile = 3, kNanosecondsPerSecond = 1000000000;
        dispatch_queue_t mainqueue =
            dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_time_t when =
            dispatch_time(0, kNanosecondsPerSecond*kSecondsToKeepFile);
        dispatch_after(when, mainqueue,
          ^{  NSError *error;
            if (![[NSFileManager defaultManager] removeItemAtPath:filePath error:&error]) {
              NSLog(@"error removing %@ %@", filePath, error);
            }
          });
      }
 
      // done with the image destination
      CFRelease(destination);
    }
 
  }
}


История версии документа


ДатаПримечания
05.08.2014

Новый документ, объясняющий, как использовать перетаскивание с IKImageView.