2011-01-08 11 views
5

Hasta el día de hoy, nunca he tenido la oportunidad de utilizar otra cosa que no sea una NSWindow en sí misma como NSDraggingDestination. Cuando se usa una ventana como destino de arrastre para todos los tamaños, NSWindow pasará esos mensajes a su delegado, lo que le permite manejar caídas sin subclases de NSWindow.Cocoa NSTextField Arrastrar y soltar Requiere subclase ... ¿De verdad?

El docs dicen:

Aunque NSDraggingDestination es declarado como un protocolo informal, los NSWindow y NSView subclases que crea para adoptar el protocolo sólo necesitan implementar los métodos que son pertinente. (Las clases NSWindow y NSView proporcionan implementaciones privadas para todos los métodos ). Ya sea un objeto ventana o su delegado puede implementar estos métodos ; sin embargo, la implementación del delegado tiene prioridad si hay implementaciones en ambos lugares .

Hoy, tenía una ventana con dos NSTextFields, y quería que tuvieran diferentes comportamientos de caída, y no quería permitir que cayeran en ningún otro lado de la ventana. La forma en que interpreto los documentos, parece que o bien tengo que subclase NSTextField, o bien hago algunos gestores de caída condicionales de spaghetti gigantes en el delegado de la ventana que comprueba el arrastreLocation en cada vista para seleccionar los diferentes comportamientos de área de colocación para cada campo

El enfoque centralizado del manejador de gotas basado en NSWindow-delegate parece ser oneroso en cualquier caso en el que haya tenido más de un pequeño puñado de vistas de destino. Del mismo modo, el enfoque de subclases parece oneroso sin importar el caso, porque ahora el código de manejo de caída vive en una clase de vista, por lo que una vez que aceptas la caída tienes que encontrar la manera de ordenar los datos caídos al modelo. El bindings docs le advierte que intente enrutar las unidades configurando el valor de la interfaz de usuario de forma programática. Así que ahora estás atrapado trabajando en eso también.

Así que mi pregunta es: "¿En serio? ¿Son esas las únicas opciones disponibles o me estoy perdiendo algo sencillo aquí?"

Gracias.

+0

Debe corregir el error tipográfico en el título de su pregunta (NSTextView! = NSTextField). – NSGod

Respuesta

6

Después de investigar un poco más, parece que "Sí, de verdad, sus dos opciones son la subclase NSTextField o usar su NSWindowDelegate para controlar las caídas". Iré más allá y haré la afirmación de que la mejor manera de las dos, para casos de variedad de jardín de "Quiero múltiples zonas de colocación en una sola ventana", es usar el método NSWindowDelegate con controles de visitas, ya que evita el problema de teniendo su código de manejo de entrega en el lado de la vista. Terminé con este draggingUpdated: método en mi ventana de la clase delegada:

- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender 
{ 
    NSPasteboard *pboard = [sender draggingPasteboard]; 
    NSDragOperation sourceDragMask = [sender draggingSourceOperationMask]; 

    if ([pboard.types containsObject: NSFilenamesPboardType] && (sourceDragMask & NSDragOperationCopy)) 
    { 
     NSView* hitView = [sender.draggingDestinationWindow.contentView hitTest: sender.draggingLocation]; 
     if (hitView && (hitView == mSourceTextField || hitView == mDestTextField)) 
     { 
      return NSDragOperationCopy;    
     } 
    } 

    return NSDragOperationNone; 
} 

Obviamente hay más en toda la imagen, pero esto hitTest: enfoque basado me ha funcionado hasta ahora. Sospecho que esto sería un poco más complejo si uno estuviera trabajando con un control basado en NSCell múltiple como un NSTableView o NSOutlineView, pero como era de esperar, esos tienen sus propios métodos de manejo de arrastre.

Espero que esto ayude a alguien más.