2012-02-03 9 views
5

Sto cercando di creare funzionalità di spostamento per il mio imageView (maskPreview nel codice qui sotto), in modo che gli utenti possano spostare un'immagine, che è contenuta in maskPreview, attorno allo schermo. Ecco il mio codice per iniziare e toccare tocco:Come spostare un UIImageView con Touch

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
if ([touches count]==1) { 
    UITouch *touch= [touches anyObject]; 
    originalOrigin = [touch locationInView:maskPreview]; 
} 
} 
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
if ([touches count]==1) { 
    UITouch *touch = [touches anyObject]; 
    CGPoint lastTouch = [touch previousLocationInView:self.view]; 
    CGFloat movedDistanceX = originalOrigin.x-lastTouch.x; 
    CGFloat movedDistanceY = originalOrigin.y-lastTouch.y; 
    [maskPreview setFrame:CGRectMake(maskPreview.frame.origin.x+movedDistanceX, maskPreview.frame.origin.y + movedDistanceY, maskPreview.frame.size.width, maskPreview.frame.size.height)]; 
} 
} 

ma ricevo alcune risposte strane dall'app. Non ho messo delle restrizioni su quanto lontano possa essere spostato l'imageview, per evitare che vada fuori dallo schermo, ma anche se si tratta di una piccola mossa, la mia visione d'immagine si scatena e scompare.

Grazie mille in anticipo per tutto l'aiuto

risposta

9

Implementazione touchesBegan e così via è il modo eccessivo in questo mondo moderno. Stai solo confondendo te stesso e il tuo codice diventerà presto impossibile da capire o mantenere. Utilizzare un UIPanGestureRecognizer; questo è quello che è per Rendere una vista trascinabile con un UIPanGestureRecognizer è banale. Ecco il gestore di azione per un UIPanGestureRecognizer che rende la vista trascinabile:

- (void) dragging: (UIPanGestureRecognizer*) p { 
    UIView* vv = p.view; 
    if (p.state == UIGestureRecognizerStateBegan || 
     p.state == UIGestureRecognizerStateChanged) { 
     CGPoint delta = [p translationInView: vv.superview]; 
     CGPoint c = vv.center; 
     c.x += delta.x; c.y += delta.y; 
     vv.center = c; 
     [p setTranslation: CGPointZero inView: vv.superview]; 
    } 
} 
+0

Impressionante Matt, sei un genio assoluto !! Avresti valutato la tua risposta ma non ho abbastanza reputazione !! reso la mia vita molto più facile !! – Septronic

+0

Proprio per questo, quel codice è uscito direttamente dal mio libro: http://shop.oreilly.com/product/0636920023562.do - Molto altro da dove viene ... – matt

+0

fantastico, ci guarderò :) grazie – Septronic

2

Ci sono due problemi con il vostro codice. In primo luogo, questa linea è sbagliata:

CGPoint lastTouch = [touch previousLocationInView:self.view]; 

Dovrebbe essere questo:

CGPoint lastTouch = [touch previousLocationInView:maskPreview]; 

Davvero, non si dovrebbe nemmeno utilizzare previousLocationInView:. Si dovrebbe solo utilizzare locationInView: come questo:

CGPoint lastTouch = [touch locationInView:maskPreview]; 

In secondo luogo, si stanno ottenendo i segni di movedDistanceX e movedDistanceY sbagliato. cambiarli a questo:

CGFloat movedDistanceX = lastTouch.x - originalOrigin.x; 
CGFloat movedDistanceY = lastTouch.y - originalOrigin.y; 

Inoltre, la documentazione per touchesBegan:withEvent: dice questo:

In caso di superamento di questo metodo senza chiamare super (un modello di uso comune), è necessario anche sovrascrivere gli altri metodi per gestire gli eventi touch, se non altro come implementazioni di stub (empy).

Quindi assicurarsi che si sta anche l'override touchesEnded:withEvent: e touchesCancelled:withEvent:.

In ogni caso, è possibile farlo un po 'più semplicemente. Un modo è rendere vuoto touchesBegan:withEvent: e fare tutto il lavoro in touchesMoved:withEvent: utilizzando sia previousLocationInView: e locationInView:, sia aggiornando maskPreview.center anziché maskPreview.frame. Non sarà nemmeno bisogno della variabile originalOrigin esempio:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
} 

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    if ([touches count]==1) { 
     UITouch *touch = [touches anyObject]; 
     CGPoint p0 = [touch previousLocationInView:maskPreview]; 
     CGPoint p1 = [touch locationInView:maskPreview]; 
     CGPoint center = maskPreview.center; 
     center.x += p1.x - p0.x; 
     center.y += p1.y - p0.y; 
     maskPreview.center = center; 
    } 
} 

Un altro modo per farlo è quello di utilizzare un UIPanGestureRecognizer. Lo lascio come esercizio per il lettore.

+0

Ciao Rob, grazie per la risposta, e ho realizzato gli errori nel mio codice !! Ho usato il tutorial di Matt per UIPanGestureRecognizer, e ha funzionato a meraviglia. Ma il fatto di aver superato tutti gli eventi touch è stato di grande aiuto, non lo sapevo e non pensavo che dovremmo farlo. – Septronic

Problemi correlati