이미지 표시 및 핸들링을 위한 UIImageView Class 의 드래그 기능을 구현하기 위한 방법에는, UIImageView 를 Subclass 하여 Touch Event 를 Overriding 하는 방법과 Gesture Recognizer 를 이용하는 방법이 있다. Apple Document 에 의하면, Touch Event 를 Overriding 하기보다는 Gesture Recognizer 를 해당 Object 에 구현하기를 권고하고 있다. 우선 Touch event Overriding 에 대해서 간략히 알아보고, Pan Gesture Recognizer 와 함께 Storyboards 를 이용하여 귀찮은 코딩작업 없이 최소한의 코딩으로 드래그 가능한 이미지 구현에 대해 알아보자.

Using Touch event Overriding

Subclass UIImageView

@interface panImage : UIImageView {
    CGPoint startPt; // 터치 이벤트 발생 지점 저장
} 
@end 

Override touch event

- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
    CGPoint pt = [[touches anyObject] locationInView:self]; 
    startPt = pt; 
    [[self superview] bringSubviewToFront:self]; 
} 

- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event { 
    CGPoint pt = [[touches anyObject] locationInView:self]; 
    CGRect frame = [self frame]; 
    frame.origin.x += pt.x - startPt.x; 
    frame.origin.y += pt.y - startPt.y; 
    [self setFrame:frame]; 
}  
REFERENCE : iPhone SDK Examples

Using Storyboards with Pan Gesture Recognizer

1. Single View Application Project 를 생성하고, UIImageView Object 하나를 UIViewController 에 올린다. 번들 리소스에 등록한 이미지 파일을 해당 UIImageView 에 설정해 준다. 이때, Attributes Inspector Pane 에서 User Interaction Enabled 항목을 체크 해 주어야 한다. 그렇지 않으면 해당 View 에서 이벤트 핸들링을 하지 못한다.

2. Object Library 에서 Pan Gesture Recognizer 를 앞서 추가한 UIImageView 이미지에 드래그 앤 드랍.

3. Pan Gesture Recognizer 포커스 후(빨간 화살표 참고), Connections Inspector 에서 delegate 를 ViewController 로 연결.

4. Assistant Editor 를 이용하여, ViewController.h 파일을 추가 Pane 에 오픈한 후 UIImageVIew 이미지를 코드내에 드래그 앤 드랍.


5. 팝업된 창의 Name 필드에 해당 UIImageView 이미지 이름을 입력.


6. 헤더파일내에 UIImageView 이미지 프라퍼티 코드가 생성된 모습.


7. Pan Gesture Recognizer 포커스 후, Connections Inspector Pane 의 selector 항목을 코드내에 드래그 앤 드랍.


8. 구현할 Pan Gesture Recognizer selector 이름을 입력. 디폴트인 Type 필드의 id 를 선택할 경우 메써드 내에서 UIPanGestureRecognizer 로 타입캐스팅해주고, 또는 UIPanGestureRecognizer 타입을 명시해 줄 수도 있다.


Type 명시


9. 이제 스토리보드에서의 작업은 완료되었고, 몇번의 드래그 앤 드랍으로 생성된 코드들을 ViewController.h/.m 에서 확인해 보자.

ViewController.h

@interface ViewController : UIViewController 

@property (weak, nonatomic) IBOutlet UIImageView *panImageView;
- (IBAction)panned:(id)sender; 

@end 

ViewController.m

@synthesize panImageView; 

- (void)viewDidUnload 
{ 
    [self setPanImageView:nil]; 
    [super viewDidUnload]; 
    // Release any retained subviews of the main view. 
    // e.g. self.myOutlet = nil; 
}

- (IBAction)panned:(id)sender { 

}
10. 정상적으로 코드가 생성되었다면, Pan Gesture 이벤트가 발생했을 때의 동작을 구현.
- (IBAction)panned:(id)sender { 
    UIPanGestureRecognizer *panRecognizer = (UIPanGestureRecognizer *)sender; 

    // Pan Gesture 가 발생한 view 취득 (panImageView)
    UIView *view = [panRecognizer view]; 
    if(panRecognizer.state == UIGestureRecognizerStateBegan || panRecognizer.state == UIGestureRecognizerStateChanged) { 
        // view.superview (ViewController) 좌표체계에 근거하여 계산된 이동 포인트 취득
        CGPoint delta = [panRecognizer translationInView:view.superview]; 

        // panImageView 의 포인트 취득하여, 계산된 이동 포인트를 다시 설정
        CGPoint pt = [view center]; 
        pt.x += delta.x; 
        pt.y += delta.y; 
        view.center = pt; 

        // 포인트 초기화
        [panRecognizer setTranslation:CGPointZero inView:view.superview]; 
    }
} 

빌드 후 확인.


REFERENCE : Intel AppUp Developer Program

CONCLUSION

매우 간단한 구현 예제로, 추가적으로 해당 이미지가 화면을 벗어나지 않는 처리와 다른 오브젝트와 겹치지 않게 Collision 알고리즘등을 적용하여 실제 프로젝트에 적용해 볼 수 있겠다.
댓글
댓글쓰기 폼