2012-04-21 13 views
0

화면에 표시되는 하위보기 이미지 격자가 있습니다. 이것은 기본적으로 체커 보드 방식으로 화면에 배치 된 일련의 이미지입니다. 사용자가 이미지 하위 뷰 중 하나를 터치 할 때 좌표, 태그 등 하위 뷰를 검색 할 수 있도록 제스처 인식기를 추가해야합니다. 내 뷰 계층 구조는 다음과 같습니다.제스처 인식기를 일련의 하위보기에 추가하려면 어떻게해야합니까?

  1. 슈퍼 볼
  2. gridContainer보기
  3. 및 각 서브 뷰 - 이미지

와 사과 문서를보고 후에 내가 gridContainer보기로 제스처 인식기를 추가 할 수 있어야 것처럼 보인다 그리고 각각의 하위 뷰 - im 연령 - 제스처 인식기를 상속해야합니다. 지금까지 내가 시도한 것은 이것입니다. getter에서 격자 컨테이너보기를 alloc'ed init'ed했습니다. 또한 getter에서 제스처 인식기를 gridContainer 뷰에 추가해야하는 createGesture 메서드를 호출했습니다. 그러나 런타임에 내 action handleSingleTap 메서드를 가리키는 오류가 발생했습니다. EXC_BAD_EXCESS를 읽습니다. gridContainer 뷰 외부의 뷰가 모든 터치 이벤트에 응답하는 것을 원하지 않는다는 점도 유의해야합니다. 모든 도움을 미리 감사드립니다. 당신이 이해하기 위해 대한 추가 코드를 볼 필요가 있으면 알려 주시기 바랍니다

- (UIView *)gridContainerView 
{ 
    if (!_gridContainerView)_gridContainerView = [[UIView alloc] init]; 
    [self createGesture]; 
    return _gridContainerView; 
} 
- (void)createGesture 
{ 
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] 
             initWithTarget:self.gridContainerView 
             action:@selector(handleSingleTap:)]; 
    singleTap.numberOfTapsRequired = 1; 

    [self.gridContainerView addGestureRecognizer:singleTap]; 
} 

: 여기

내가 구현하기 위해 노력하고있어 코드입니다.

편집 : handleSingleTap 방법을 포함 :

- (IBAction)handleSingleTap:(id)sender 
{ 
    CGPoint tapPoint = [sender locationInView:sender]; 
    NSLog(@"sender = %@",sender); 
    NSLog(@"tappoint = %@", tapPoint); 
} 

답변

4

당신은 당신의 gridContainerView에 대한 일반 UIView를 초기화된다. 그런 다음 해당 뷰 인스턴스를 대상으로 사용하여 제스처 인식기를 연결합니다. UIView 일반하지만 handleSingleTap:을 구현하지 않으므로 예외가 발생합니다.

제스처가 트리거해야하는 선택기를 구현하는 (사용자 정의 UIView 파생 된) 클래스를 만들어야합니다.

+0

그래서 UIView의 하위보기 인 맞춤 클래스를 만들어야합니까? 이 사용자 정의 클래스에 내 gridContainerView를 푸시하고 액세스가 필요할 때 내 컨트롤러에서 호출해야합니까? – Scott

+0

하위보기가 아니라 하위 클래스입니다. – Till

0

박쥐 바로 옆에 몇 가지 문제가 있습니다 (제스처를 다루지 않고도).

gridContainerView에 액세스 할 때마다 createGesture가 호출됩니다. 보기를 만들 때만 이러한 상황이 발생하기를 원할 것입니다. 당신이 createGesture 보면 또한, 그것은

- (UIView *)gridContainerView 
{ 
    if (!_gridContainerView) { 
     _gridContainerView = [[UIView alloc] init]; 
     [self createGesture]; 
    } 
    return _gridContainerView; 
} 

다음 ...

당신은 아마 같은 자세한 내용을 원하는 등, 다시 다시 다시 gridContainerView로 호출 createGesture로 호출 gridContainerView로 호출 뷰에서 handleSingleTap을 호출하려고합니다. 컨트롤러의 initWithTarget : self를 원할 수도 있습니다.

- (void)createGesture 
{ 
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] 
             initWithTarget:self 
             action:@selector(handleSingleTap:)]; 
    singleTap.numberOfTapsRequired = 1; 

    [self.gridContainerView addGestureRecognizer:singleTap]; 
} 

이와 같이 서로를 직접 참조하는 두 가지 방법이 있다는 지혜를 되찾고 싶을 것입니다. 그러나 적어도 접근 자에 대한 변경 사항이 있으면 확인해야합니다. 접근 자에 더 많은 코드를 추가하면 createGesture를 호출하기 전에보기가 완전히 설정되어 있어야한다는 것을 알고 있습니다.

+0

그건 좋은 지적이지만, handleSingleTap 메서드는 터치 이벤트에 응답하지 않는 것 같습니다. 위의 코드를 편집하여 단일 탭 메서드를 처리했습니다. 어떤 아이디어가 응답하지 않는 이유는 무엇입니까? – Scott

0

몇 가지. 먼저 gridContainerView를 표준 UIView로 인스턴스화 한 다음 handleSingleTap :이라는 메시지를 보내면 가장 확실하게 응답하지 않습니다. gridContainerView가 메시지에 응답하게하려면 UIView의 하위 클래스를 만들고 적절한 메서드를 만들고 gridContainerView를 하위 클래스로 인스턴스화해야합니다.

둘째, 전반적인 접근 방식으로 gridContainerView에 대한 하위 클래스를 만들고 (어쩌면이 호출이라고도 함) 제스처를 처리 할 메서드를 만듭니다. 이 메서드에서는 UIGestureRecognizer 메서드 locationInView:을 사용하여 접촉하거나 탭 한 지점에 액세스 할 수 있습니다. 이 지점을 사용하여 gridContainerView의 하위 뷰가 탭되었는지 확인하고 적절한 작업을 수행합니다. 어떤 하위 뷰를 탭했는지 확인하려면 하위 뷰를 반복하고 각 뷰를 검사하여 어떤 점에 탭이 찍힌 점이 있는지 확인합니다. 여러 가지 방법으로 UIView가이 작업을 수행하는 데 사용할 수 있습니다 있습니다 hitTest:withEvent:

pointInside:withEvent:, 당신은 이벤트에 대한 nil를 전달할 수 있습니다. 위의 두 가지는 약간 다른 것들을합니다. 점이 뷰에 있는지 여부를 테스트하는 중이면 pointInside:withEvent을 사용하면 BOOL을 반환하므로 점을 테스트하는 것입니다. hitTest:withEvent 메서드는 뷰가 모든 하위 뷰를 검색하여 그 자체 또는 하위 뷰 중 하나를 반환합니다 (또는 해당 점이 경계 외부에 있으면 nil). hitTest:withEvent 조금 더 프로세서 집약적 일 수 있습니다. 또한 CGRectContainsPoint()을 사용해도 테스트 할 수 있습니다.

관련 문제