WKWebView在iPad上旋转后显示裁剪的背景和空白区域

时间:2015-02-12 23:29:52

标签: ios ipad background web wkwebview

我正在将我的应用程序从UIWebView迁移到适用于iOS8.x的WKWebView(维护对iOS7.x的支持),并且我正在使用我正在显示的网站遇到问题,因为在旋转iPad后,它会显示内容,但背景似乎以某种方式裁剪,因此在bg之后有一个空格。

然而一旦我开始滚动网站,它就会自动修复。当我从横向传递到纵向时,也会发生这种空白效果,这会使网站的右侧留下空白背景。

以下是我尝试解决问题的方法:

(void)willRotateToInterfaceOrientation:
(UIInterfaceOrientation)toInterfaceOrientation duration (NSTimeInterval)duration
{
    [self.view setNeedsUpdateConstraints];
    [_webView setNeedsUpdateConstraints];
}

(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [self.view setNeedsUpdateConstraints];
    [_webView setNeedsUpdateConstraints];
}

我尝试了很多东西(通过JS重新加载后台,处理如上所示的willRotateToInterfaceOrientation和didRotateFromInterfaceOrientation方法)但是还没能解决问题,而只有在使用WKWebView时才会发生,如果我切换回到UIWebView,网站正确呈现

我还在Safari上测试了同一台设备(带有iOS 8.1.3的iPad2)的网站,无论我旋转多少次iPad都没有显示错误,所以我确信它可以要解决=)。有人可以帮帮我吗?

5 个答案:

答案 0 :(得分:2)

这是WKWebKit中的一个错误,它通常由应用了position: fixed的HTML元素触发。我发现的唯一解决方法是在window.scrollTo()事件后几百毫秒内使用resize将页面滚动一个像素。

答案 1 :(得分:2)

这拯救了我的生命:

self.wkWebView.evaluateJavaScript("window.scrollBy(1, 1);window.scrollBy(-1, -1);", completionHandler: nil)

在wkwebview上添加此行,完成导航事件!!

答案 2 :(得分:1)

我花了一段时间,但我把它用于没有卷轴的页面:

window.addEventListener('resize', function(){
            setTimeout(function () {
                var vp = document.getElementsByName("viewport")[0],
                    vpContent = vp.content,
                    vpHack = ((window.innerHeight > window.innerWidth) ? window.screen.availHeight  / window.innerHeight : window.screen.availWidth / window.innerWidth) + 0.0001;
                vp.content = "user-scalable=no, initial-scale="+vpHack+", maximum-scale="+vpHack+", minimum-scale="+vpHack+",width=device-width";
                setTimeout(function(){vp.content=vpContent;},10);
            }, 500);
        }, true);

假设您使用视口。它将视口更改为0.0001,持续10毫秒

我实现了这样:

-(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
NSLog(@"###### FINISH");
[self.webView evaluateJavaScript:[NSString stringWithFormat:@"if (document.readyState==='complete'){ window.addEventListener('resize', function(){setTimeout(function () {var vp = document.getElementsByName('viewport')[0],vpContent = vp.content,vpHack = ((window.innerHeight > window.innerWidth) ? window.screen.availHeight  / window.innerHeight : window.screen.availWidth / window.innerWidth) + 0.0001; vp.content = 'user-scalable=no, initial-scale='+vpHack+', maximum-scale='+vpHack+', minimum-scale='+vpHack+',width=device-width';setTimeout(function(){vp.content=vpContent;},10);}, 500);}, true); } else { window.addEventListener('load', function(){window.addEventListener('resize', function(){setTimeout(function () {var vp = document.getElementsByName('viewport')[0],vpContent = vp.content,vpHack = ((window.innerHeight > window.innerWidth) ? window.screen.availHeight  / window.innerHeight : window.screen.availWidth / window.innerWidth) + 0.0001; vp.content = 'user-scalable=no, initial-scale='+vpHack+', maximum-scale='+vpHack+', minimum-scale='+vpHack+',width=device-width';setTimeout(function(){vp.content=vpContent;},10);}, 500);}, true);}, false );}"] completionHandler:nil];

}

答案 3 :(得分:0)

我使用document.head.appendChild(document.createElement('style')).remove(); 在调整大小/旋转后,将我的WKWebViews重新绘制。

答案 4 :(得分:0)

以下解决方法对我有用,但不幸的是仅在模拟器上:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];

    // Workaround for WKWebView iOS 8 Rotation Bug
    // Official Fix (iOS 9): http://trac.webkit.org/changeset/169625
    if ([[[UIDevice currentDevice] systemVersion] integerValue] == 8) {
        CGRect frame = self.view.frame;
        frame.size.width += 1;
        self.view.frame = frame;
        frame.size.width -= 1;
        self.view.frame = frame;
    }
}

经过一些实验后,我还可以使用以下步骤在设备上工作:

  • 保留两组AutoLayout约束,第一个用于您实际想要的行为,第二个用于较小的更改(例如,1磅大小差异)
  • 每当方向发生变化时,将第二组应用于视图,然后在1秒后应用第一个约束集。

虽然这个解决方案远非理想,但它是我在网站上操作Javascript时唯一找到的解决方案。我试图降低延迟,但在我的测试中我不得不等待至少0.8秒。