UIWebView content not adjusted to new frame after

2019-02-27 10:46发布

问题:

I have an e-mail application,
which shows the content in an UIWebView inside an UISplitViewController.
Everything works fine until i rotate the device, when already zoomed in/out in the UIWebView. When rotating the device, i adjust the frame of the UIWebView in

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

The problem is, when i zoomed in/out in the UIWebViewand then rotate the device.
The content isn't resized to it's new frame, which leads to a gray/black border in the content, or the content can be scrolled horizontal.

Addional information: The UIWebViewis a subview on a UIScrollView which can be scrolled. When the UIWebViewis totally visible the scrollEnabledof the UIScrollViewis disabled and the UIWebView can be scrolled.

Above picture shows the UIWebViewin landscape when selecting an email.
This is the state before rotating in both cases.



[Not zoomed before rotating]Above picture shows that the UIWebView is correctly resizing the content to it's new frame.



[Zoomed before rotating]Above picture shows the UIWebView after zooming in landscape and then rotating to portrait -> content isn't correctly shown

Information of the UIWebView.scrollView in
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation:

<_UIWebViewScrollView: 0xb1322a0; frame = (0 0; 768 960); clipsToBounds = YES; autoresize = H; gestureRecognizers = <NSArray: 0xb1321d0>; layer = <CALayer: 0xb132270>; contentOffset: {0, 0}> frame is correct!

Edit: Solution!!
i managed to solve it by updating the viewport width after rotating the device

CGFloat fll_width = self.view.frame.size.width; NSString* adsl_javascript_string = [NSString stringWithFormat:@"var setViewPortScript = document.createElement('meta');\ setViewPortScript.setAttribute('name', 'viewport');\ setViewPortScript.setAttribute('content', 'width = %f');\ document.getElementsByTagName('head')[0].appendChild(setViewPortScript);", fll_width]; [adsc_webview stringByEvaluatingJavaScriptFromString:adsl_javascript_string];

回答1:

i managed to solve it by updating the viewport width after rotating the device

CGFloat fll_width = self.view.frame.size.width;
NSString* adsl_javascript_string = [NSString stringWithFormat:@"var setViewPortScript = document.createElement('meta');\
     setViewPortScript.setAttribute('name', 'viewport');\
     setViewPortScript.setAttribute('content', 'width = %f');\
     document.getElementsByTagName('head')[0].appendChild(setViewPortScript);", fll_width];
[adsc_webview stringByEvaluatingJavaScriptFromString:adsl_javascript_string];


回答2:

This seems to be a bug also in iOS 7 and iOS 8. A fix would be this:

First resize the frame on layout changes:

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    _webView.frame = self.view.bounds;
}

Then on the rotation callback reset the zoomScale to 0. Yes, 0!

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    // Allow the animation to complete
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [_webView.scrollView setZoomScale:0 animated:YES];
    });
}

You can also use the new function

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    // Allow the animation to complete
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [_webView.scrollView setZoomScale:0 animated:YES];
    });
}