Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIWebView without Copy/Paste and selection rectangle when showing documents

In my App I want to disable the Copy/Paste/Cut of contents that are showed by a UIWebView object. To achieve this, I created a UIWebView subclass and overrode the - (BOOL)canPerformAction:(SEL)action withSender:(id)sender method:

#pragma mark - UIResponderStandardEditActions 

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {    
    if (action == @selector(copy:) ||
        action == @selector(paste:)||
        action == @selector(cut:)) {
        return _copyCutAndPasteEnabled;
    }

    return [super canPerformAction:action withSender:sender];
}

Now the user no longer can make such operations, however the UIWebView still shows the "selection rectangle", as you can see in the following screenshot:

Selection rectangle

NOTE: The content being showed in the UIWebView is not HTML pages. I'm showing document files (PDF, DOC, PPT), loaded from a file using:

NSURL *fileURL = [NSURL fileURLWithPath:<document file path..>];
NSURLRequest *fileRequest = [NSURLRequest requestWithURL:fileURL];
[<uiwebView> loadRequest:fileRequest];

Is there any way to disable/hide this selection rectangle feature too?

[]s,

like image 267
Eduardo Coelho Avatar asked Apr 01 '11 15:04

Eduardo Coelho


1 Answers

You can try injecting javascript into the webView. This code works on the iPhone too but only when the page is fully loaded. http://www.javascriptsource.com/page-details/disable-text-selection.html or http://solidlystated.com/scripting/proper-way-to-disable-text-selection-and-highlighting/

To get it to work properly when the page is only half loaded or still loading you'll proably have to use a setup similar to this one where you inject the disabling javascript just as it would start selecting. http://www.icab.de/blog/2010/07/11/customize-the-contextual-menu-of-uiwebview/

One last thing I can think of that might work, have you tested adding the selector @selector(select:) to the list of disabled selectors?

EDIT: Ok as you what to display a PDF rather then a html page you can try this.

Setup

Put the webView in a scrollView;

Set the ScrollView's: delegate to self; min zoom to 1.0 and max zoom to whatever you want;

After the weView has finished loading. Scan for the first UIScrollView in the webView, (we are scanning for it so this shouldn't break on later iOS versions). Set the UIWebViews frame to it's scrollViews size. And set the scrollView's contentSize to the webViews contentSize (or by now, it's frame).

-(void)setup{
    //Get the webView's first scrollView (the one all the content is in).
    UIScrollView *webViewContentView;
    for (UIView *checkView in [webView subviews] ) {
        if ([checkView isKindOfClass:[UIScrollView class]]) {
            webViewContentView = (UIScrollView*)checkView;
            break;
        }
    }

    webView.frame = CGRectMake(0, 0, webViewContentView.contentSize.width, webViewContentView.contentSize.height);
    scrollView.contentSize = webViewContentView.contentSize;
    scrollView.delegate = self;
}

To enable zooming you'll need to add an extra method from the scrollViews delegate.

-(UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return webView;
}

And you can download a sample project http://www.multiupload.com/P8SOZ4NW6C (It's an xcode 4 project).

NOTES: The zooming pixelates the webView's content if you zoom in to much because the webView doesn't know to re-render things, and of cause you can't click links (but in a PDF that shouldn't be a problem).

EDIT 2: Better method

Since writing this I have realised a MUCH simpler and easier method, which should also solve the pixelation problem.

-(void)removeInput{
    UIScrollView *webViewContentView;
    for (UIView *checkView in [webView subviews] ) {
    if ([checkView isKindOfClass:[UIScrollView class]]) {
        webViewContentView = (UIScrollView*)checkView;
            break;
        }
    }

    for (UIView *checkView in [webViewContentView subviews] ) {
        checkView.userInteractionEnabled = NO;
    }
}

Now you should only be able to interact with the UIScrollView itself, meaning zooming, scrolling, ect.. should still work (and the page should re-render rather the pixelating when you zoom) but you can't select any text, or type anything in.

Also something about this method is that based on this list of UIWebView subViews it might be possible to set this before the page starts loading rather then after it has finished loading the page.

like image 103
Kyle Howells Avatar answered Jan 23 '23 21:01

Kyle Howells