2012-06-19 9 views
5

He sublimitado UIWebView para que pueda obtener eventos táctiles y también implemente este práctico método. Tengo curiosidad, si esto funcionará en un dispositivo iOS real. No estoy en la oficina, así que no sé si lo hace. Parece que funciona en el simulador.tapAtPoint en la subclase 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]; 
    } 
} 

¿Alguien ha intentado algo como esto? De seguro lo averiguaré en la mañana, jajaja.

+0

No es que ' "_internal"' indocumentado? ¿Será aprobado por Apple? –

Respuesta

0

Por favor, pruebe este código, Aquí está funcionando bien.

/* 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); 
} 

Gracias, Avíseme si tiene algún problema.

+0

¿es posible usar doble clic? Creo que hay una función (interactuar con la acción), cuando uso el selector de rendimiento, y envío de CGPoint, el punto no se usa. – OMGPOP

+0

touch.tapCount == 2 y performselector en consecuencia – sagarcool89

0

Respuesta corta: Sí, intenté algo así de la misma manera y también funciona en los dispositivos reales (probado con iOS 6).

versión ARC de su método:

- (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]]; 
    } 
}