2012-02-03 6 views
5

사용자가 화면에서 maskPreview에 포함 된 그림을 이동할 수 있도록 내 imageView (아래 코드의 maskPreview)에 이동 기능을 만들려고합니다. 터치 시작 및 터치 이동 코드는 다음과 같습니다.Touch를 사용하여 UIImageView를 움직이는 방법

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

하지만 앱에서 이상한 반응이 나타납니다. 이미지 뷰가 얼마나 멀리 이동할 수 있는지, 즉 화면 밖으로 나가는 것을 방지하기 위해 제한을 두지는 않았지만, 작은 움직임 인 경우에도 내 이미지 뷰는 자연스럽고 사라집니다. 많이 등등 touchesBegan 및 구현 모든 도움

답변

9

에 미리

덕분에이 현대 세계에서 진행 과잉이다. 자신을 혼란스럽게하는 것 뿐이므로 코드를 빨리 이해하거나 유지할 수 없게됩니다. UIPanGestureRecognizer를 사용하십시오. 그것이 바로 그 때문입니다. UIPanGestureRecognizer로 드래그 할 수있는 뷰를 만드는 것은 쉽지 않습니다. 코드 두 가지 문제가 있습니다

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

굉장한 매트, 너는 천재 야 !! 당신의 대답을 평가했을까요?하지만 나는 충분한 평판이 없습니다 !! 내 인생을 훨씬 쉽게 만들어 줬어 !! – Septronic

+0

그냥 참고하시기 바랍니다. 그 코드는 제 책에서 곧바로 나옵니다. http://shop.oreilly.com/product/0636920023562.do - 어디에서 왔는지 자세히 ... – matt

+0

끝내 주겠다 :) 감사합니다 – Septronic

2

: 여기에 드래그 뷰를 만드는 UIPanGestureRecognizer에 대한 작업 처리기입니다. 첫째,이 라인이 잘못된 :이 있어야한다

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

: 정말

CGPoint lastTouch = [touch previousLocationInView:maskPreview]; 

, 당신도 previousLocationInView:를 사용해서는 안된다. 당신은 다음과 같은 locationInView:를 사용한다 :

CGPoint lastTouch = [touch locationInView:maskPreview]; 

둘째, 당신은 movedDistanceXmovedDistanceY 잘못의 흔적을 얻고있다. 이로 변경 : 대한

는 (일반적인 사용 패턴) super를 호출하지 않고이 메소드를 오버라이드 (override)하는 경우, 당신은 또한 오버라이드 (override) 할 필요가 다른 방법 :

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

또한, touchesBegan:withEvent: 설명서에이 말한다 스텁 (empy) 구현으로서 만 터치 이벤트를 처리합니다.

따라서 touchesEnded:withEvent:touchesCancelled:withEvent:도 무시해야합니다.

어쨌든이 작업을 조금 더 간단하게 수행 할 수 있습니다. 한 가지 방법은 touchesBegan:withEvent:을 비우고 touchesMoved:withEvent:의 모든 작업을 previousLocationInView:locationInView:을 모두 사용하고 maskPreview.frame 대신 maskPreview.center으로 업데이트하는 것입니다.

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

이 작업을 수행하는 또 다른 방법은 UIPanGestureRecognizer을 사용하는 것입니다 : 당신도 originalOrigin 인스턴스 변수를 필요로하지 않습니다. 저는 이것을 독자를위한 운동으로 남겨 둡니다.

+0

안녕 Rob, 답변 주셔서 감사 드리며 실수로 코드를 깨달았습니다 !! 나는 UIPanGestureRecognizer를위한 Matt의 튜토리얼을 사용했고, 그것은 대우를 받았다. 그러나 모든 터치 이벤트를 무시하는 것에 대한 큰 도움은 큰 도움이었습니다. 나는 몰랐고 그렇게해야한다고 생각하지 않았습니다. – Septronic

관련 문제