문제

나는 Uitableview 위에 핀치 인/아웃을 구현하려고합니다. 나는 이것을 포함하여 몇 가지 방법을 살펴 보았습니다.

비슷한 질문

그러나 내가 만들 수는 있지만 UIViewTouch 객체와 오버레이를 내 uitableview에 오버레이하고, 스크롤 이벤트가 내 uitableview로 전달되지 않고, 셀을 선택할 수 있으며, 새로운 뷰 콘트롤러 객체로의 전환을 트리거하여 올바르게 응답합니다. 그러나 Touchesbegan을 통과하고 터치가 발생했으며 터치 된 이벤트에도 불구하고 Uitableview를 스크롤 할 수 없습니다.

도움이 되었습니까?

해결책

이것은 고전적인 문제인 것 같습니다. 제 경우에는 서브 클래스 등을 할 수없는 uiwebview를 통해 일부 이벤트를 가로 채고 싶었습니다.

가장 좋은 방법은 UIWindow를 사용하여 이벤트를 가로 채는 것입니다.

EventInterceptWindow.h

@protocol EventInterceptWindowDelegate
- (BOOL)interceptEvent:(UIEvent *)event; // return YES if event handled
@end


@interface EventInterceptWindow : UIWindow {
    // It would appear that using the variable name 'delegate' in any UI Kit
    // subclass is a really bad idea because it can occlude the same name in a
    // superclass and silently break things like autorotation.
    id <EventInterceptWindowDelegate> eventInterceptDelegate;
}

@property(nonatomic, assign)
    id <EventInterceptWindowDelegate> eventInterceptDelegate;

@end

EventInterceptsWindow.m :

#import "EventInterceptWindow.h"

@implementation EventInterceptWindow

@synthesize eventInterceptDelegate;

- (void)sendEvent:(UIEvent *)event {
    if ([eventInterceptDelegate interceptEvent:event] == NO)
        [super sendEvent:event];
}

@end

해당 클래스를 만들고 MainWindow.xib의 UI -Window 클래스를 EventInterceptWindow로 변경 한 다음 어딘가에 이벤트 interceptDelegate를 이벤트를 가로 채려는 뷰 컨트롤러로 설정하십시오. 더블 탭을 가로 채는 예 :

- (BOOL)interceptEvent:(UIEvent *)event {
    NSSet *touches = [event allTouches];
    UITouch *oneTouch = [touches anyObject];
    UIView *touchView = [oneTouch view];
    //  NSLog(@"tap count = %d", [oneTouch tapCount]);
    // check for taps on the web view which really end up being dispatched to
    // a scroll view
    if (touchView && [touchView isDescendantOfView:webView]
            && touches && oneTouch.phase == UITouchPhaseBegan) {
        if ([oneTouch tapCount] == 2) {
            [self toggleScreenDecorations];
            return YES;
        }
    }   
    return NO;
}

여기와 관련 정보 :http://iphoneincubator.com/blog/windows-views/360idev-iphone-developers-conference-presentation

다른 팁

Nimrod는 다음과 같이 썼습니다.

어딘가에 이벤트 interceptDelegate를 이벤트를 가로채는 뷰 컨트롤러로 설정했습니다.

나는이 진술을 즉시 이해하지 못했습니다. 나와 같은 문제를 겪은 다른 사람의 이익을 위해, 내가 한 방식은 터치를 감지 해야하는 Uiview 서브 클래스에 다음 코드를 추가하는 것이 었습니다.

- (void) viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    // Register to receive touch events
    MyApplicationAppDelegate *appDelegate = (MyApplicationAppDelegate *) [[UIApplication sharedApplication] delegate];
    EventInterceptWindow *window = (EventInterceptWindow *) appDelegate.window;
    window.eventInterceptDelegate = self;
}


- (void) viewWillDisappear:(BOOL) animated
{
    // Deregister from receiving touch events
    MyApplicationAppDelegate *appDelegate = (MyApplicationAppDelegate *) [[UIApplication sharedApplication] delegate];
    EventInterceptWindow *window = (EventInterceptWindow *) appDelegate.window;
    window.eventInterceptDelegate = nil;

    [super viewWillDisappear:animated];
}


- (BOOL) interceptEvent:(UIEvent *) event
{
    NSLog(@"interceptEvent is being called...");
    return NO;
}


이 버전의 interceptEvent: 핀치-Zoom 감지의 간단한 구현입니다. NB. 일부 코드는 Apress의 iPhone 3 개발에서 시작되었습니다.

CGFloat initialDistance;

- (BOOL) interceptEvent:(UIEvent *) event
{
    NSSet *touches = [event allTouches];

    // Give up if user wasn't using two fingers
    if([touches count] != 2) return NO;

    UITouchPhase phase = ((UITouch *) [touches anyObject]).phase;
    CGPoint firstPoint = [[[touches allObjects] objectAtIndex:0] locationInView:self.view];
    CGPoint secondPoint = [[[touches allObjects] objectAtIndex:1] locationInView:self.view];

    CGFloat deltaX = secondPoint.x - firstPoint.x;
    CGFloat deltaY = secondPoint.y - firstPoint.y;
    CGFloat distance = sqrt(deltaX*deltaX + deltaY*deltaY);

    if(phase == UITouchPhaseBegan)
    {
        initialDistance = distance;
    }
    else if(phase == UITouchPhaseMoved)
    {
        CGFloat currentDistance = distance;
        if(initialDistance == 0) initialDistance = currentDistance;
        else if(currentDistance - initialDistance > kMinimumPinchDelta) NSLog(@"Zoom in");
        else if(initialDistance - currentDistance > kMinimumPinchDelta) NSLog(@"Zoom out");
    }
    else if(phase == UITouchPhaseEnded)
    {
        initialDistance = 0;
    }

    return YES;
}


편집 :이 코드는 iPhone 시뮬레이터에서 100% 잘 작동하는 동안 iPhone 장치에서 실행했을 때 테이블 스크롤과 관련된 이상한 버그가 발생했습니다. 이것이 당신에게도 발생하면 interceptEvent: 모든 경우에 반환하는 방법. 이것은 슈퍼 클래스가 터치 이벤트를 처리 할 것이지만 다행히도 내 코드를 깨뜨리지는 않았다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top