2011-08-25 15 views
9

Possiedo un NSView che sto aggiungendo come subview di un altro NSView. Voglio essere in grado di trascinare il primo NSView attorno alla vista principale. Ho del codice parzialmente funzionante ma c'è un problema con l'NSView che si muove nella direzione opposta sull'asse Y dal mio trascinamento del mouse. (ad esempio, trascino verso il basso, si alza e l'inverso di quello).NSView: trascinamento della vista

Ecco il mio codice:

// -------------------- MOUSE EVENTS ------------------- \\ 

- (BOOL) acceptsFirstMouse:(NSEvent *)e { 
return YES; 
} 

- (void)mouseDown:(NSEvent *) e { 

//get the mouse point 
lastDragLocation = [e locationInWindow]; 

} 

- (void)mouseDragged:(NSEvent *)theEvent { 

NSPoint newDragLocation = [theEvent locationInWindow]; 
NSPoint thisOrigin = [self frame].origin; 
thisOrigin.x += (-lastDragLocation.x + newDragLocation.x); 
thisOrigin.y += (-lastDragLocation.y + newDragLocation.y); 
[self setFrameOrigin:thisOrigin]; 
lastDragLocation = newDragLocation; 
} 

la vista è ruotato, anche se ho cambiato che torna al default e non mi sembra di fare la differenza. Che cosa sto facendo di sbagliato?

risposta

13

Il modo migliore per affrontare questo problema è iniziare con una solida conoscenza degli spazi delle coordinate.

Innanzitutto, è fondamentale comprendere che quando si parla del "frame" di una finestra, è nello spazio di coordinate della suprema . Ciò significa che la regolazione della capovolgimento della vista non farà realmente la differenza, perché non abbiamo cambiato nulla all'interno della vista stessa.

Ma la tua intuizione che il capovolgimento sia importante qui è corretta.

Per impostazione predefinita, il codice, come digitato, sembra funzionare; forse il tuo superview è stato capovolto (o non capovolto), ed è in uno spazio di coordinate diverso da quello che ti aspetti.

Piuttosto che semplicemente capovolgere e sgranare le viste a caso, è meglio convertire i punti con cui si ha a che fare in uno spazio di coordinate noto.

Ho modificato il codice precedente per convertirlo sempre nello spazio delle coordinate della superview, perché stiamo lavorando con l'origine del frame. Questo funzionerà se la tua vista trascinabile è posizionata su una superview capovolta o non capovolta.

// -------------------- MOUSE EVENTS ------------------- \\ 

- (BOOL) acceptsFirstMouse:(NSEvent *)e { 
    return YES; 
} 

- (void)mouseDown:(NSEvent *) e { 

    // Convert to superview's coordinate space 
    self.lastDragLocation = [[self superview] convertPoint:[e locationInWindow] fromView:nil]; 

} 

- (void)mouseDragged:(NSEvent *)theEvent { 

    // We're working only in the superview's coordinate space, so we always convert. 
    NSPoint newDragLocation = [[self superview] convertPoint:[theEvent locationInWindow] fromView:nil]; 
    NSPoint thisOrigin = [self frame].origin; 
    thisOrigin.x += (-self.lastDragLocation.x + newDragLocation.x); 
    thisOrigin.y += (-self.lastDragLocation.y + newDragLocation.y); 
    [self setFrameOrigin:thisOrigin]; 
    self.lastDragLocation = newDragLocation; 
} 

Inoltre, io consiglierei di refactoring il codice a che fare semplicemente con la posizione originale del mouse verso il basso, e la posizione corrente del puntatore, piuttosto che affrontare i delta tra gli eventi mouseDragged. Ciò potrebbe portare a risultati imprevisti su tutta la linea.

Invece, è sufficiente memorizzare l'offset tra l'origine della vista trascinata e il puntatore del mouse (dove il puntatore del mouse si trova all'interno della vista) e impostare l'origine del fotogramma nella posizione del puntatore del mouse, meno l'offset.

Ecco qualche lettura supplementare:

Cocoa Drawing Guide

Cocoa Event Handling Guide

0

Credo che si dovrebbe calcolare in base alla posizione del mouse, causare secondo la mia prova, diventa più smooth.Because Il modo come di seguito solo fornire la posizione all'interno del sistema di coordinate della finestra dell'applicazione:

[[self superview] convertPoint:[theEvent locationInWindow] fromView:nil]; 

W cappello che sto suggerendo è qualcosa di simile:

lastDrag = [NSEvent mouseLocation]; 

altri codici sono uguali.

Problemi correlati