scalesPageToFit broken on UIWebView after keyboard

2019-05-04 14:57发布

I have this meta tag:

<meta name="viewport" content="width=768, minimum-scale=1.0, user-scalable=no" />

And I am setting scalesPageToFit:

webView.scalesPageToFit = YES;

At first this works correctly. When I go from portrait to landscape it zooms in so the width of the device is always 768px. I can go back and forth with no issues (portrait <-> landscape).

As soon as I activate the virtual keyboard, whether it be through a contentEditable or text area, it stops working completely, even after I dismiss the keyboard.

Is this a bug in the UIWebView? Is there anything else I need to do to make this work? Is there a work-around I can use? The width, no matter the orientation, has to be 768px.

标签: ios uiwebview
2条回答
Emotional °昔
2楼-- · 2019-05-04 15:39

Seems to be a bug with Apple's private class UIDocumentView. For what ever reason viewportConfigurationsDidChange gets stuck on a zoom scale after the keyboard is activated, which is set by calling _setDocumentScale. When it's supposed to change to 1.333, for example, it gets stuck on 1.0.

It's "fixable" by writing a category for UIWebDocumentView, which is a subclass of UIDocumentView that doesn't implement these methods (so you can call the super's).

Despite my best efforts I couldn't find a way to fix this using the public API. I tried messing with the UIScrollView's zoom level, but I could never get that to work correctly. The content would get shifted, and other weird things would happen. Even tried doing it with JavaScript.

So the only way to fix it is through category on private classes.

This would never be approved in the app store.

So until Apple fixes this, SOL.

查看更多
▲ chillily
3楼-- · 2019-05-04 15:52

WARNING: this solution uses private APIs. Any app that uses this code might be rejected from the app store. I am posting it so people at least have a working solution.

@interface UIWebDocumentView : UIView
- (void)_setDocumentScale:(float)scale;
@end

@interface UIWebView (DocumentView)
- (UIWebDocumentView *)_documentView;
@end

- (void)resetScale:(UIWebView *)webView
{
    UIWebDocumentView *webDocumentView = [webView _documentView];
    CGFloat contentWidth = [[webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollWidth;"] floatValue];
    CGSize viewSize = webView.bounds.size;
    float scale = viewSize.width / contentWidth;
    [webDocumentView _setDocumentScale:scale];
}

Call resetScale after the bounds of the web view change.

查看更多
登录 后发表回答