2012-06-19 12 views
5

Posiadam podklasę UIWebView, dzięki czemu mogę otrzymywać zdarzenia dotykowe, a także zaimplementować tę poręczną metodę. Jestem ciekawy, czy to zadziała na rzeczywistym urządzeniu z iOS. Nie jestem w biurze, więc nie wiem, czy to prawda. Wydaje się działać w symulatorze.tapAtPoint na podklasie UIWebView

- (void) tapAtPoint:(CGPoint)point 
{ 
    id /*UIWebBrowserView*/ webBrowserView = nil; 
    id webViewInternal = nil; 
    object_getInstanceVariable(self, "_internal", (void **)&webViewInternal); 
    object_getInstanceVariable(webViewInternal, "browserView", (void **)&webBrowserView); 

    if (webBrowserView) { 
     [webBrowserView tapInteractionWithLocation:point]; 
    } 
} 

Czy ktoś próbował czegoś takiego? Ja na pewno dowiedzieć się rano, lol.

+0

Czy nie jest to ' "_internal"' nieudokumentowane? Czy zostanie zatwierdzony przez Apple? –

Odpowiedz

0

Proszę spróbować tego kodu, tutaj działa dobrze.

/* TapDetectingWindow.m */ 

#import "TapDetectingWindow.h" 
@implementation TapDetectingWindow 
@synthesize viewToObserve; 
@synthesize controllerThatObserves; 
- (id)initWithViewToObserver:(UIView *)view andDelegate:(id)delegate { 
    if(self == [super init]) { 
     self.viewToObserve = view; 
     self.controllerThatObserves = delegate; 
    } 
    return self; 
} 
- (void)dealloc { 
    [viewToObserve release]; 
    [super dealloc]; 
} 
- (void)forwardTap:(id)touch { 
    [controllerThatObserves userDidTapWebView:touch]; 
} 
- (void)sendEvent:(UIEvent *)event { 
    [super sendEvent:event]; 
    if (viewToObserve == nil || controllerThatObserves == nil) 
     return; 
    NSSet *touches = [event allTouches]; 
    if (touches.count != 1) 
     return; 
    UITouch *touch = touches.anyObject; 
    if (touch.phase != UITouchPhaseEnded) 
     return; 
    if ([touch.view isDescendantOfView:viewToObserve] == NO) 
     return; 
    CGPoint tapPoint = [touch locationInView:viewToObserve]; 
    NSLog(@"TapPoint = %f, %f", tapPoint.x, tapPoint.y); 
    NSArray *pointArray = [NSArray arrayWithObjects:[NSString stringWithFormat:@"%f", tapPoint.x], 
    [NSString stringWithFormat:@"%f", tapPoint.y], nil]; 
    if (touch.tapCount == 1) { 
     [self performSelector:@selector(forwardTapwithObject:pointArray afterDelay:0.5]; 
    } 
    else if (touch.tapCount > 1) { 
     [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(forwardTap  object:pointArray]; 
    } 
} 
@end 


/* WebViewController.h */ 

@interface WebViewController : UIViewController<TapDetectingWindowDelegate> { 
    IBOutlet UIWebView *mHtmlViewer; 
    TapDetectingWindow *mWindow; 
} 

/* WebViewController.m */ 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    mWindow = (TapDetectingWindow *)[[UIApplication sharedApplication].windows objectAtIndex:0]; 
    mWindow.viewToObserve = mHtmlViewer; 
    mWindow.controllerThatObserves = self; 
} 

- (void)userDidTapWebView:(id)tapPoint 
{ 
    NSLog(@"TapPoint = %f, %f", tapPoint.x, tapPoint.y); 
} 

Dzięki, daj mi znać, jeśli napotkasz jakiekolwiek problemy.

+0

Czy można użyć podwójnego kliknięcia? Myślę, że istnieje funkcja (tapinterakcja ze zwrotem akcji), gdy używam performselector i wysyłam CGPoint, punkt nie jest używany. – OMGPOP

+0

touch.tapCount == 2 i odpowiednio wykonaj selektor – sagarcool89

0

krótka odpowiedź: Tak, próbowałem czegoś podobnego w ten sam sposób i działa również na prawdziwych urządzeniach (testowane z iOS 6).

ARC wersja metodę:

- (void) tapAtPoint:(CGPoint)point 
{ 
    Ivar internalWebViewIvar = class_getInstanceVariable([self class], "_internal"); 
    id internalWebView = object_getIvar(self, internalWebViewIvar); 

    Ivar browserViewIvar = class_getInstanceVariable(object_getClass(internalWebView), "browserView"); 
    id browserView = object_getIvar(internalWebView, browserViewIvar); 

    if (browserView) { 
     [browserView performSelector:@selector(tapInteractionWithLocation:) withObject:[NSValue valueWithCGPoint:point]]; 
    } 
} 
Powiązane problemy