2012-02-03 17 views
5

Próbuję utworzyć funkcję przenoszenia do mojego imageView (maskPreview w poniższym kodzie), tak aby użytkownicy mogli przenieść obraz, który jest zawarty w maskPreview, wokół ekranu. Oto mój kod dotyku rozpocząć i dotyk przeniesione:Jak przenieść UIImageView za pomocą 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)]; 
} 
} 

ale dostaję dziwne odpowiedzi od aplikacji. Nie wprowadziłem ograniczeń co do tego, jak daleko obraz może się poruszyć, tj. Aby zapobiec wychodzeniu z ekranu, ale nawet jeśli jest to mały ruch, mój widok obrazu szaleje i znika.

Bardzo dziękuję z góry za wszelką pomoc

Odpowiedz

9

Realizacja touchesBegan i tak dalej jest droga przesada w tym nowoczesnym świecie. Po prostu mylicie się z samym sobą, a wasz kod szybko stanie się niemożliwy do zrozumienia lub utrzymania. Użyj narzędzia UIPanGestureRecognizer; po to jest to. Tworzenie widoku przeciągalnego za pomocą narzędzia UIPanGestureRecognizer jest banalne. Oto obsługi akcja dla UIPanGestureRecognizer sprawia, że ​​pogląd Draggable:

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

Awesome Matt, jesteś absolutnym geniuszem !! Oceniłbym twoją odpowiedź, ale nie mam wystarczającej reputacji !! moje życie stało się o wiele łatwiejsze !! – Septronic

+0

Po prostu FYI, kod ten pochodzi prosto z mojej książki: http://shop.oreilly.com/product/0636920023562.do - Wiele więcej, skąd pochodzi ... – matt

+0

niesamowite, zajrzę do niego :) dzięki – Septronic

2

Istnieją dwa problemy z Twojego kodu. Po pierwsze, ta linia jest źle:

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

To powinno być tak:

CGPoint lastTouch = [touch previousLocationInView:maskPreview]; 

Naprawdę, nie powinien być nawet używając previousLocationInView:. Należy po prostu używać locationInView: tak:

CGPoint lastTouch = [touch locationInView:maskPreview]; 

drugie, są coraz oznaki movedDistanceX i movedDistanceY złym. Zmienić je tak:

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

Również dokumentacja touchesBegan:withEvent: mówi tak:

Jeśli zastąpić tę metodę bez wywoływania super (powszechne stosowanie wzorca), należy również zastąpić inne metody obsługa zdarzeń dotykowych, choćby jako implementacja stubów (empy).

Więc upewnij się, że również nadrzędne touchesEnded:withEvent: i touchesCancelled:withEvent:.

W każdym razie możesz zrobić to całkiem prosto. Jednym ze sposobów jest pozbycie się touchesBegan:withEvent: i wykonanie całej pracy w touchesMoved:withEvent: przy użyciu zarówno previousLocationInView: i locationInView:, jak i aktualizacji maskPreview.center zamiast maskPreview.frame. Nawet nie potrzebują originalOrigin instancji zmiennej:

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

Innym sposobem na to jest za pomocą UIPanGestureRecognizer. Zostawiam to jako ćwiczenie dla czytelnika.

+0

Cześć Rob, dzięki za odpowiedź, i zdałem sobie sprawę z błędów w moim kodzie !! Użyłem tutoriala Matta dla UIPanGestureRecognizer, i to działało. Ale odrobina nadmiernego kierowania wszystkimi wydarzeniami dotykowymi była wielką pomocą, nie wiedziałem i nie sądziłem, że powinniśmy to zrobić. – Septronic

Powiązane problemy