sirve qué que para izquierdo informática hacer funcion doble derecho como clic boton activar objective-c macos cocoa nswindow appkit

objective c - qué - ¿Permitir hacer clic y arrastrar una vista para arrastrar la ventana?



que es doble clic (7)

¿Ha intentado anular el método mouseDownCanMoveWindow para devolver YES ?

Estoy usando una ventana con textura que tiene una barra de pestañas en la parte superior, justo debajo de la barra de título.

He usado -setContentBorderThickness:forEdge: en la ventana para que el degradado se vea bien y para que las hojas se salgan de la posición correcta.

Lo que no funciona, sin embargo, es arrastrar la ventana. Funciona si hago clic y arrastro el área que en realidad es la barra de título, pero como el gradiente de la barra de título se derrama en una barra de pestañas (potencialmente / a menudo vacía), es muy fácil hacer clic en un nivel demasiado bajo y se siente realmente frustrante cuando intenta arrastrar Y darse cuenta que la ventana no se está moviendo.

NSToolbar , mientras ocupa aproximadamente la misma cantidad de espacio debajo de la barra de título, permite que la ventana se arrastre cuando el cursor está sobre ella. ¿Cómo se implementa esto?

Gracias.


A partir de macOS 10.11, la forma más sencilla de hacerlo es utilizar el nuevo -[NSWindow performWindowDragWithEvent:] :

@interface MyView () { BOOL movingWindow; } @end @implementation MyView ... - (BOOL)mouseDownCanMoveWindow { return NO; } - (void)mouseDown:(NSEvent *)event { movingWindow = NO; CGPoint point = [self convertPoint:event.locationInWindow fromView:nil]; // The area in your view where you want the window to move: CGRect movableRect = CGRectMake(0, 0, 100, 100); if (self.window.movableByWindowBackground && CGRectContainsPoint(movableRect, point)) { [self.window performWindowDragWithEvent:event]; movingWindow = YES; return; } // Handle the -mouseDown: as usual } - (void)mouseDragged:(NSEvent *)event { if (movingWindow) return; // Handle the -mouseDragged: as usual } @end

Aquí, -performWindowDragWithEvent: manejará el comportamiento correcto de no superponerse a la barra de menú, y también se ajustará a los bordes en macOS 10.12 y posteriores. Asegúrese de incluir una variable de instancia BOOL movingWindow con la interfaz privada de su vista para que pueda evitar los eventos -mouseDragged: una vez que haya determinado que no desea procesarlos.

Aquí, también estamos verificando que -[NSWindow movableByWindowBackground] esté configurado en YES para que esta vista se pueda usar en ventanas de fondo no movible por ventana, pero eso es opcional.


Encontré esto here :

-(void)mouseDown:(NSEvent *)theEvent { NSRect windowFrame = [[self window] frame]; initialLocation = [NSEvent mouseLocation]; initialLocation.x -= windowFrame.origin.x; initialLocation.y -= windowFrame.origin.y; } - (void)mouseDragged:(NSEvent *)theEvent { NSPoint currentLocation; NSPoint newOrigin; NSRect screenFrame = [[NSScreen mainScreen] frame]; NSRect windowFrame = [self frame]; currentLocation = [NSEvent mouseLocation]; newOrigin.x = currentLocation.x - initialLocation.x; newOrigin.y = currentLocation.y - initialLocation.y; // Don''t let window get dragged up under the menu bar if( (newOrigin.y+windowFrame.size.height) > (screenFrame.origin.y+screenFrame.size.height) ){ newOrigin.y=screenFrame.origin.y + (screenFrame.size.height-windowFrame.size.height); } //go ahead and move the window to the new location [[self window] setFrameOrigin:newOrigin]; }

Funciona bien, aunque no estoy 100% seguro de hacerlo correctamente. Hay un error que he encontrado hasta ahora, y eso es si el arrastre comienza dentro de una subvista (una pestaña en sí) y luego ingresa la vista de supervisión (la barra de pestañas). La ventana salta alrededor. Algún -hitTest: magic, o posiblemente incluso invalidando initialLocation en mouseUp probablemente debería solucionarlo.


Es bastante fácil:

anular la propiedad mouseDownCanMoveWindow

override var mouseDownCanMoveWindow:Bool { return false }


Funciona para mí después de DOS pasos:

  1. Subclase NSView, anule el mouseDownCanMoveWindow para devolver SÍ.
  2. Subclase NSWindow, invalide isMovableByWindowBackground para devolver YES.

Si tiene un NSTableView en su ventana, con la selección habilitada , la anulación de la propiedad mouseDownCanMoveWindow no funcionará.

En su lugar, necesita crear una subclase NSTableView y anular los siguientes eventos del mouse (y usar el performWindowDragWithEvent: mencionado en la respuesta de Dimitri ):

@interface WindowDraggableTableView : NSTableView @end @implementation WindowDraggableTableView { BOOL _draggingWindow; NSEvent *_mouseDownEvent; } - (void)mouseDown:(NSEvent *)event { if (self.window.movableByWindowBackground == NO) { [super mouseDown:event]; // Normal behavior. return; } _draggingWindow = NO; _mouseDownEvent = event; } - (void)mouseDragged:(NSEvent *)event { if (self.window.movableByWindowBackground == NO) { [super mouseDragged:event]; // Normal behavior. return; } assert(_mouseDownEvent); _draggingWindow = YES; [self.window performWindowDragWithEvent:_mouseDownEvent]; } - (void)mouseUp:(NSEvent *)event { if (self.window.movableByWindowBackground == NO) { [super mouseUp:event]; // Normal behavior. return; } if (_draggingWindow == YES) { _draggingWindow = NO; return; // Event already handled by `performWindowDragWithEvent`. } // Triggers regular table selection. NSPoint locationInWindow = event.locationInWindow; NSPoint locationInTable = [self convertPoint:locationInWindow fromView:nil]; NSInteger row = [self rowAtPoint:locationInTable]; if (row >= 0 && [self.delegate tableView:self shouldSelectRow:row]) { NSIndexSet *rowIndex = [NSIndexSet indexSetWithIndex:row]; [self selectRowIndexes:rowIndex byExtendingSelection:NO]; } } @end

Tampoco olvide establecer la ventana correspondiente de la propiedad movableByWindowBackground también:

self.window.movableByWindowBackground = YES;


mouseDownCanMoveWindow solución mouseDownCanMoveWindow ( https://.com/a/4564146/901641 ) pero no me funcionó. Me deshice de ese método y en su lugar lo agregué a mi subclase de ventana:

- (BOOL)isMovableByWindowBackground { return YES; }

que funcionó a la perfección.