2012-10-05 24 views
5

Estoy usando un WebView en modo de edición. He implementado este método de WebUIDelegate procotol:Arrastrar y soltar desde el buscador a WebView

- (void)webView:(WebView *)sender willPerformDragDestinationAction:(WebDragDestinationAction)action forDraggingInfo:(id <NSDraggingInfo>)draggingInfo 

y lo utilizan para recoger las gotas de elementos en mi vista Web. Cuando detecto un archivo que se arrastra desde fuera de mi aplicación, y que contiene una imagen, construyo en este método el elemento img DOM y lo agrego a mi documento.

Esto funciona bien, pero como el nombre del método lo implica, solo se me informa que el arrastre ocurrirá, y no tengo control sobre él.

Como el Finder siempre realiza la operación de arrastre de archivos, lo que normalmente sucede cuando se suelta un archivo en un WebView en modo de edición es que la vista web muestra la ruta del archivo.

Termino teniendo la cadena de ruta de archivo agregada a mi vista web, y la imagen también, pero me gustaría evitar que el texto se agregue.

¿Hay alguna manera de configurar esto sin subclasificar webview?

Lo probé y mientras funciona, se rompe muchas otras cosas como caret moverse por la gota y tal.

Respuesta

10

¡Respondiendo a esto yo mismo para variar!

- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender 
{ 

    if ([sender draggingSource] == nil) 
    { 

     NSPasteboard *pboard = [sender draggingPasteboard]; 

     if ([[pboard types] containsObject:NSFilenamesPboardType]) { 
      NSURL* fileURL; 
      fileURL=[NSURL URLFromPasteboard: [sender draggingPasteboard]]; 

      NSArray *dragTypes = [NSArray arrayWithObject:NSFileContentsPboardType]; 
      [[sender draggingPasteboard] declareTypes:dragTypes owner:nil]; 

      NSImage *content = [[NSImage alloc] initWithContentsOfURL:fileURL]; 
      [[sender draggingPasteboard] setData:[content TIFFRepresentation] forType:NSPasteboardTypeTIFF]; 
     } 
    } 

    return [super performDragOperation:sender]; 


} 

En realidad, lo que hice fue hecho a subclase el WebView e interceptar el performDragOperation a cambiar el contenido de la mesa de trabajo arrastrando, si la fuente arrastrando está fuera de mi aplicación y no contiene ya una imagen, pero sólo un nombre de archivo

3

Me encontré con el mismo problema.

Lo que encontré es que la creación de subclases de la vista es el mejor lugar para que esto inserte los datos de la imagen en la mesa de trabajo. Así es como lo estoy haciendo para múltiples archivos:

- (BOOL) performDragOperation:(id<NSDraggingInfo>)sender { 

    if ([sender draggingSource] == nil) { 

     NSPasteboard *pboard = [sender draggingPasteboard]; 

     NSArray *classes = @[ [NSURL class] ]; 
     NSDictionary *options = @{ NSPasteboardURLReadingFileURLsOnlyKey: [NSNumber numberWithBool:YES], 
            NSPasteboardURLReadingContentsConformToTypesKey: [NSImage imageTypes] }; 

     NSArray *fileURLs = [pboard readObjectsForClasses:classes options:options]; 

     if (fileURLs) { 

      NSMutableArray *images = [NSMutableArray arrayWithCapacity:[fileURLs count]]; 

      for (NSURL *fileURL in fileURLs) 
       [images addObject:[[NSImage alloc] initWithContentsOfURL:fileURL]]; 

      [pboard declareTypes:[NSImage imageTypes] owner:nil]; 
      [pboard clearContents]; [pboard writeObjects:images];   
     } 

    } return [super performDragOperation:sender]; 
} 

Lo que noté es la siguiente secuencia: 1.
WebView captura operación de arrastre.
2. WebCore interno creado fragmento de documento se inserta
3. Nodo en un DOMRange
4. La edición de Delegado se llama
5. Por último interfaz de usuario delegado se llama donde es demasiado tarde para hacer algo

Además, sugiero establecer lo siguiente a través de la interfaz de usuario Delegado:

- (NSUInteger) webView:(WebView *)webView dragDestinationActionMaskForDraggingInfo:(id <NSDraggingInfo>)draggingInfo { 

    return WebDragDestinationActionEdit; 
} 

Ok, ahora el problema que estoy corriendo en y realmente espero que pueda tener una respuesta para mí. Cuando selecciono un archivo, no hay problema. Cuando selecciono varios archivos, los obtengo y los agrego a todos correctamente en el portapapeles. Incluso cuando llego a (5) para el UIDelegate e inspecciono la tabla de arrastre para su conteo, obtengo lo que se espera. Pero desafortunadamente el fragmento de documento solo se crea una vez y, de la misma manera, solo se inserta un nodo.

¿Alguna idea de cómo crear múltiples fragmentos para que se puedan insertar?

Gracias de antemano.

0

Versión fija para las respuestas anteriores, este código funciona para múltiples imágenes arrastradas en la vista web.

- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender 
{ 
    if ([sender draggingSource] == nil) 
    { 
     NSPasteboard *pboard = [sender draggingPasteboard]; 
     NSArray *classes = @[ [NSURL class] ]; 
     NSDictionary *options = @{ NSPasteboardURLReadingFileURLsOnlyKey: [NSNumber numberWithBool:YES], 
            NSPasteboardURLReadingContentsConformToTypesKey: [NSImage imageTypes] }; 
     NSArray *fileURLs = [pboard readObjectsForClasses:classes options:options]; 

     if(fileURLs) 
     { 
      NSArray* filenames = [pboard propertyListForType: NSFilenamesPboardType]; 
      NSMutableString* html = [NSMutableString string]; 

      for(NSString* filename in filenames) { 
       [html appendFormat: @"<img src=\"%@\"/>", [[[NSURL alloc] initFileURLWithPath: filename] absoluteString]]; 
      } 

      [pboard declareTypes: [NSArray arrayWithObject: NSHTMLPboardType] owner: self]; 
      [pboard setString: html forType: NSHTMLPboardType]; 
     } 

    } return [super performDragOperation:sender]; 
}