2012-04-05 4 views
7

touchesBegan을받은 순간에 removeFromSuperview을 터치하고 addSuperview을 새로운 부모보기로 보내고 계속해서 터치를 받길 원합니다. 그러나 나는 때때로 이것이 작동하지 않는다는 것을 알고 있습니다. 특히 touchesMovedtouchesEnded은 호출되지 않습니다.iOS : 터치하는 동안 UIView의 소유권을 이전 하시겠습니까?

이 작업을 올바르게 수행하기위한 트릭이 있습니까? 이는 드래그 앤 드롭 동작을 구현하기위한 것으로, 뷰는 처음에는 스크롤 뷰 내부에 있습니다.

감사합니다.

답변

0

전환하려는보기 대신 슈퍼보기에서 터치를 처리해야합니다. 이렇게하면 터치 이벤트를 잃지 않고 뷰를 전환 할 수 있습니다. 이 작업을 수행 할 때 전환하려는 특정 하위보기에서 터치가 발생하는지 직접 테스트해야합니다. 이것은 여러 가지 일을 할 수 있지만, 여기에 당신이 시작하는 몇 가지 방법은 다음과 같습니다

다른보기로의 구형/포인트 변환 : 여기

[view convertRect:rect toView:subview]; 
[view convertPoint:point toView:subview]; 

가 포인트가 뷰에있는 경우 테스트하는 몇 가지 방법이 있습니다는 :

[subView hitTest:point withEvent:nil]; 
CGRectContainsPoint(subview.frame, point); //No point conversion needed 
[subView pointInside:point withEvent:nil]; 

일반적으로 UIGestureRecognizers를 사용하는 것이 좋습니다. 예를 들어 UIPanGestureRecognizer를 사용하는 경우 제스처 인식기에서 호출 할 수있는 메서드를 만들고이 메서드에서 작업을 수행합니다. 예를 들어 :

다음
- (void) viewPanned:(UIPanGestureRecognizer *)pan{ 
    if (pan.state == UIGestureRecognizerStateBegan){ 
     CGRect rect = subView.frame; 
     newView = [[UIView alloc] initWithFrame:rect]; 
     [subView removeFromSuperview]; 
     [self addSubview:newView]; 
    } else if (pan.state == UIGestureRecognizerStateChanged){ 
     CGPoint point = [pan locationInView:self]; 
     newView.center = point; 
    } else { 
     //Do cleanup or final view placement 
    } 
} 

당신이 인식기를 초기화하기 목표 (일반적으로 자기)에 할당 및 추가 :

[self addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewPanned:)]]; 

지금 자기가 (이 파단의 관리하는 수퍼 될 것이다) 응답 모션을 팬하는 것.

+0

그 이유는 확실하지 않습니다. 코드를 게시 할 수 있습니까? 왜 UIGestureRecognizer를 사용하지 못하게합니까? 거의 모든 경우에 Touches 사용을 고려해 보았습니다. 기존 UIGestureRecognizer 또는 UIGestureRecognizer를 서브 클래 싱하는 것이 더 잘 작동한다는 것을 알았습니다 (재사용 할 수 있음). –

+0

주식 UIPanGestureRecognizer를 사용하는 경우 'touchesBegan'이 코드에 없어야합니다. '- (void) viewPanned : (UIPanGestureRecognizer) pan'과 같은 대상 메서드를 설정해야합니다. 인식기를 초기화하면 타겟을 설정합니다 :'[[UIPanGestureRecognizer alloc] initWithTarget : 자기 액션 : @selector (viewPanned :)]'.이 메소드는 반복적으로 호출 될 것이고 상태를 점검하고 적절한 액션을 수행 할 수 있습니다 : If (pan.state == UIGestureRecognizerStateBegan) {.......}'If if (pan.state == UIGestureRecognizerStateChanged {. ....}'등 ... –

+0

이것을 반영하기 위해 내 대답이 확장되었습니다. –

7

대신에 : 만

[transferView removeFromSuperView]; 
[newParentView addSubview:transferView]; 

사용 :이 적혀 문서 내에서

[newParentView addSubview:transferView]; 

"뷰는 하나의 수퍼있을 수 있습니다보기가 벌써 퍼뷰을 가지고있는 경우. 보기가 수신기가 아닌 경우이 메서드는 수신기를 새 수퍼 뷰로 만들기 전에 이전 수퍼 뷰를 제거합니다. "

따라서 addSubview에서 처리하므로 removeFromSuperView를 사용할 필요가 없습니다. removeFromSuperView가 touchesEnded를 호출하지 않고 현재 터치를 끝내는 것으로 나타났습니다. addSubview 만 사용하면 접촉이 중단되지 않습니다.

+1

OP의 목표를 달성하기 위해 수퍼 뷰에서 드래그를 관리 할 필요가 없으므로 허용 된 대답이어야합니다. ** removeFromSuperView ** 트릭을. 감사합니다 ** walapu **. – walkingbrad

+0

위대한 대답, 이것은 매우 도움이되었다! – Max