BananaNeil
BananaNeil

Reputation: 10762

UIWebView with height less than 101px not selectable?

I am working on an app that loads small chunks of HTML into several webviews. I want this HTML to be selectable by the user, so they can copy and paste portions of it. This is working totally fine, but only when the content is greater than 100px tall. For some reason, if it is any shorter, the content can not be selected by the user.

Steps to reproduce:

  1. Create a UIWebView with a width of 322, and a height of 100 and add it to a view
  2. Call loadHTMLString: "W " * 64, baseURL: nil on the webview. (on my screen this is 4 complete rows of "W"s)
  3. Click and hold on one of the "W", note that the copy/paste menu does not appear
  4. Call loadHTMLString: "W " * 65, baseURL: nil on the webview. (on my screen the last "W" is on the 5th row)
  5. Click and hold on one of the "W", note that the copy/paste menu does appear

I've tried a number of thing, to understand what is happening here. I you follow the same steps, but start with a height of 101 instead of 100, it works perfectly find with only 4 rows.

I think this might be a bug in iOS? Maybe?

I'm running iOS 9.2, with Xcode 7.2.1

Does anyone here know why this might be happening, or if there is any sort of work around that I can use to fix this?

Upvotes: 9

Views: 298

Answers (3)

Pradeep K
Pradeep K

Reputation: 3661

Setting the scalesPageToFit to true for the web view seems to solve the problem but only if the height is 100. If its 99 or less then same problem persists. But its strange to see the relation between scalesPageToFit and this feature and for a height of 100. Looking at the heights of 101,100,99 it seems like some kind of floating point calculation issue going on here. Definitely a bug.

Upon more investigation I found that if you set the height to 100.5 then the content is selectable. Seems like some kind of rounding off issue in the web view implementation.

When I looked at the web view's scroll view's contentSize it seems like when the scrollview contentSize goes beyond 100 the selection works. So if you handle webviewDidFinishLoad and there you check if the contentSize is < 100 then you can reload the string by appending <br>. As long as its less than 100 you keep on loading adding a <br> every time to the loaded string. This should work for you.

func webViewDidFinishLoad(webView: UIWebView) {
    print(webview.scrollView.contentSize)
    var content = webview.stringByEvaluatingJavaScriptFromString("document.body.innerHTML")
    if content != nil && webview.scrollView.contentSize.height <= 100 {
        content! += "<br>"
        webview.loadHTMLString(content!, baseURL: nil)
    }
}

Upvotes: 0

Terence
Terence

Reputation: 443

Well, webview suppose to load html code, but not pure string, that might confuse it. If you add <!DOCTYPE HTML> in front, it can be selected no matter how short the string is.

Upvotes: 1

Sheamus
Sheamus

Reputation: 6606

I've tried a few workarounds, to no avail.

The only workaround I've found: use WKWebView-- it does not have this issue.

Currently, as of iOS 9, you cannot add WKWebView through Interface Builder. This is because it is not supported. You won't be able to include it in IB, as long as WKWebView header declares it as NS_UNAVAILABLE:

- (instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE;

Instead, you can declare it as a property, and instantiate it in your viewDidLoad implementation, like so:

self.webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 200, 320, 100)];

Upvotes: 3

Related Questions