displaying Wiki mobile page in UIWebView within UIPopoverController

廉价感情. 提交于 2019-11-29 08:45:48

This is an enhanced version of auco answer, where if the viewport meta tag is not present it will be added:

- (void)webViewDidFinishLoad:(UIWebView*)webView
{
    int webviewWidth = (NSUInteger)webView.frame.size.width;

    if (!webView.loading) {

        NSString *jsCmd = [NSString stringWithFormat:@"try {var viewport = document.querySelector('meta[name=viewport]');if (viewport != null) {viewport.setAttribute('content','width=%ipx, initial-scale=1.0, user-scalable=1');} else {var viewPortTag=document.createElement('meta');viewPortTag.id='viewport';viewPortTag.name = 'viewport';viewPortTag.content = 'width=%ipx, initial-scale=1.0, user-scalable=1';document.getElementsByTagName('head')[0].appendChild(viewPortTag);}} catch (e) {/*alert(e);*/}", webviewWidth, webviewWidth];

        [webView stringByEvaluatingJavaScriptFromString:jsCmd];
    }
}

Here is the Javascript pretty formatted code we are injecting in the WebView with a width of 320px

try {
    var viewport = document.querySelector('meta[name=viewport]');
    if (viewport != null) {
        viewport.setAttribute('content',
                'width=320px, initial-scale=1.0, user-scalable=1');
    } else {
        var viewPortTag = document.createElement('meta');
        viewPortTag.id = 'viewport';
        viewPortTag.name = 'viewport';
        viewPortTag.content = 'width=320px,initial-scale=1.0, user-scalable=1';
        document.getElementsByTagName('head')[0].appendChild(viewPortTag);
    }
} catch (e) {
    /*alert(e);*/
} 

you can remove the try/catch if you want.

oh, i found in another QA that sometimes if html got a line "width=device-width", and you load a webview from popover controller, this popover controller will automatically send out device-width, not the view width you specified, and make your view ugly and funky. in that post it is a jQuery issue, and it solved with a jQuery way. In my problem, it is just a html issue in wiki mobile version. so I try another way, but similar.

I simple add a code in webViewdidload delegate method, first get URL html into a NSString, then use NSString instance method to search for "device-width" in loaded html, and replace it with my view width to make it a new NSString, then load this page with this new NSString. that's it.

- (void) webViewDidFinishLoad:(UIWebView *)webView
{
if (!alreadyReload) 
{
    NSString *webHTML = [NSString stringWithContentsOfURL:webView.request.URL encoding:NSUTF8StringEncoding error:NULL];
    NSRange range = [webHTML rangeOfString:@"device-width"];
    if ((range.location!=NSNotFound)&&(range.length != 0)) 
    {
        webHTML = [webHTML stringByReplacingOccurrencesOfString:@"device-width" withString:@"whatever width you need" options:0 range:range];
        [webView loadHTMLString:webHTML baseURL:wikiWebView.request.URL];
        alreadyReload = YES;
    }
}
}

something like this.

by the way, since I only use this on wiki mobile version, the html is simple and this kind of compare and replace is pretty easy. if you wanna use it in a more general case, you might use other way.

It would be much more efficient to manipulate the device-width via JavaScript rather than altering the html after it has fully loaded and then reloading the full page with modified html again.

This should work (and also consider if it's even necessary to change the viewport width):

- (void)webViewDidFinishLoad:(UIWebView *)aWebView {
    if(aWebView.frame.size.width < aWebView.window.frame.size.width) {
        // width=device-width results in a wrong viewport dimension for webpages displayed in a popover
        NSString *jsCmd = @"var viewport = document.querySelector('meta[name=viewport]');";
        jsCmd = [jsCmd stringByAppendingFormat:@"viewport.setAttribute('content', 'width=%i, initial-scale=1.0, user-scalable=1');", (NSUInteger)aWebView.frame.size.width];
        [aWebView stringByEvaluatingJavaScriptFromString:jsCmd];
    }
    // stop network indicator
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!