views:

415

answers:

3

Is it possible to disable all user interaction with a WebView, apart from scrolling? I want the user to be able to see the page (and possibly select things), but not click links/right click/refresh/focus form fields/trigger UI DOM events (onclick etc).

I see on this question I can disable right click and selection, but that doesn't help with the form elements and navigation sending DOM events.

A: 

Hey coob,

One option (not really the best...) would be to wrap the WebView inside a ScrollView that you create yourself, and then disable all user interaction with the web view entirely. I imagine you would adjust the web view's frame so that the entire page was visible, and then make it the content view of a scroll view.

You may also be able to subclass WebView and intercept clicks to reject certain actions, but I don't have any experience with this, and I imagine it would be difficult to differentiate some actions, such as selection, from others (especially the contextual menu).

Hope that helps - good luck!

Ben Gotow
A: 

You could probably do this via javascript (iterate through all links, forms, etc) on the page and deactivate them, using -[UIWebView stringByEvaluatingJavaScriptFromString:].

Ben Gottlieb
Unfortunately this isn't viable for me as I am following links, but through the Webkit Obj-C DOM interface not user interaction.
coob
well, you could set the userInteractionEnabled to false while it's loading, then, once it's loaded, run a script to disable everything and set its userinteraction to on.
Ben Gottlieb
+2  A: 

You could subclass NSWindow and set your subclass as the window of the WebView. You can then control which events are sent to the WebView by detecting what sort of control is being affected by the mouse event.

This is pretty brute force but will totally disable any mouse events, including rollovers etc:

@interface WebViewEventKillingWindow : NSWindow 
{
    IBOutlet WebView* myWebView;
}
@end

@implementation WebViewEventKillingWindow
- (void)sendEvent:(NSEvent*)event
{
    NSView* hitView;
    switch([event type])
    {
        case NSScrollWheel:
        case NSLeftMouseDown:
        case NSLeftMouseUp:
        case NSLeftMouseDragged:
        case NSMouseMoved:
        case NSRightMouseDown:
        case NSRightMouseUp:
        case NSRightMouseDragged:
            hitView = [myWebView hitTest:[event locationInWindow]];
            if([hitView isDescendantOf:myWebView] && 
                         !([hitView isKindOfClass:[NSScroller class]] || 
                             [hitView isKindOfClass:[NSScrollView class]]))
            {
                return;
            }
            break;
        default:
            break;
    }
    [super sendEvent:event];
}
@end
Rob Keniger
I think this may work. I'll give it a go.
coob
Yep this is it. I left out NSScrollWheel so the user can still scroll on the page, which introduces some strange behaviour with changing the cursor, but otherwise this does just what I need. Many thanks!
coob
You could always just add a `[[NSCursor arrowCursor] set];` just before the `return;` statement so that as soon as the mouse moves the cursor is reset.
Rob Keniger