UIWebView without Copy/Paste and selection rectangle when showing documents
Asked Answered
R

2

6

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,

Rationalism answered 1/4, 2011 at 15:32 Comment(3)
Unless you are 100% sure nobody else provides the same (or similar) content, this "feature" only serves to drive people away from your app.Seem
@Franci Penov: I can think of many cases where a user would not want the selection pointer to appear. In fact, it often screws up with my user experience when reading something and scrolling slowly (holding finger down, reading, dragging, end up selecting but wanted scrolling).Recalcitrant
@Franci: I'm 100% sure nobody else will provide such content. The App is being created to show content that is restricted to certain public. This "feature" is a customer's requirement (otherwise I'd certainly don't bother with that.) @Kalle: I totally agree with you opinion.Rationalism
L
14

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.

Lupulin answered 1/4, 2011 at 16:15 Comment(11)
I appreciate your answer, this seems to work when showing HTML pages in the UIWebView. I think that I wasn't clear enough in my question (I'll edit it). The contents being showed in the UIWebView are PDF, DOC, PPT, XLS files (I just make a URLRequest to be loaded from a file.)Rationalism
Well another method you /might/ be able to try is getting the size of the content view the UIWebView has, setting the webViews size to that disabling userInteraction on the webView, and adding it to a UIScrollView with it's contentSize set to the webViews size, I'll write another answer with more detail on that if you want.Lupulin
this looks like the solution for my problem. I could manage to write that, but if you could, I would like to see your implementation and accept it as an answer. Thanks.Rationalism
@eduardo-coelho I updated the post with the main bits of code needed and an example project you can download.Lupulin
Updated the answer with a better solution that should (untested) fix the pixelation problem, if you ever update the app you might want to consider switching over.Lupulin
The second solution worked well.It disables user interaction and allows to scroll through view thats what i was not able to do Thanx... But in my application i want to show some urls if the user interaction is disabled user can't use those urls..IS there any way so that cut copy and magnifier controls can be disabled but still user can interact with the web viewTrevatrevah
If you want to disable interaction on HTML documents you can use the Javascript method I posted at the top of my answer. @Nilesh-TupeLupulin
The second EASIER solution is really MUCH BETTER :)Mardis
The second solution fixed my issue. I also subclass my UIWebView and inserted the code into awakeFromNib method.Twirp
@Eduardo Coelho: It looks like this solution is accessing private API. Does anyone know this will be rejected by Apple?Twirp
@Twirp as far as I know both methods are AppStore compatible. Also neither method is accessing private API's but rather looking through a views subviews. Also in iOS 6 there is a method to get the UIWebView's scrollView so those for loops aren't needed anymore (just for backwards compatibility).Lupulin
G
0

I found an answer on here by Johnny Rockex and it worked like a champ. It works for documents (including .pdf files) displayed in a UIWebView. UIWebView without Copy/Paste when displaying PDF files

Gerrard answered 1/1, 2014 at 22:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.