2012-10-05 23 views
5

Sto usando una WebView in modalità di modifica. Ho implementato questo metodo da WebUIDelegate Procotol:Drag and drop dal finder a WebView

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

e utilizzarlo per catturare le gocce di elementi sul mio WebView. Quando rilevo un file che viene trascinato dall'esterno della mia app e che contiene un'immagine, costruisco in questo metodo l'elemento DOM img e lo aggiungo al mio documento.

Questo funziona bene, ma come suggerisce il nome del metodo, mi viene solo comunicato che il trascinamento avverrà e non ho alcun controllo su di esso.

Poiché il Finder esegue sempre un'operazione di trascinamento dei file, ciò che normalmente accade quando si rilascia un file in una WebView in modalità di modifica è la vista Web che visualizza il percorso del file.

Finisco per avere la stringa del percorso del file aggiunta alla mia webview, e anche l'immagine, ma vorrei impedire l'aggiunta del testo.

C'è un modo per configurarlo senza creare una sottoclasse di Webview?

Ho provato e mentre funziona, si rompe un sacco di altre cose come il movimento mobile per la goccia e così via.

risposta

10

Rispondendo a me stesso per un cambiamento!

- (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]; 


} 

In realtà, quello che ho fatto è stato infatti quello di creare una sottoclasse del WebView e intercettare il performDragOperation di modificare il contenuto del tavolo di montaggio trascinamento, se la sorgente di trascinamento è al di fuori della mia applicazione e non contiene già un'immagine, ma solo un nome di file.

3

Mi sono imbattuto nello stesso problema.

Quello che ho trovato è che la sottoclasse della vista è il posto migliore per inserire i dati dell'immagine nel tavolo di montaggio. Ecco come lo faccio per più file:

- (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]; 
} 

Quello che ho notato è la seguente sequenza:
1. WebView cattura operazione di trascinamento.
2. WebCore interno creato frammento di documento
3. Il nodo è inserito in un DOMRange
4. Modifica delegato è chiamato
5. Infine UI delegato si chiama in cui è troppo tardi per fare qualcosa

Inoltre, suggerisco impostando la seguente tramite l'interfaccia utente delegato:

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

    return WebDragDestinationActionEdit; 
} 

Ok, ora il problema che sono in esecuzione in e spero davvero che si potrebbe avere una risposta per me. Quando seleziono un file nessun problema. Quando seleziono più file, li ottengo e li aggiungo tutti correttamente nel pasteboard. Anche quando arrivo a (5) per l'UIDelegate e ispeziono il draggingPasteboard per il suo conteggio, ottengo ciò che è previsto. Ma sfortunatamente il frammento del documento viene creato una sola volta e allo stesso modo viene inserito solo un nodo.

Qualche idea su come creare più frammenti in modo che possano essere inseriti tutti?

Grazie in anticipo.

0

Versione fissa per le risposte precedenti, questo codice funziona per più immagini trascinate nella visualizzazione 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]; 
}