WKWebView高度变小后, body底部出现空白的解决办法

3,992 阅读1分钟

不清楚是不是所有的iOS版本都有这个bug, 我这目前是iOS 15.0.2. 当通过改变frame height, 或者修改高度约束减小webview的高度后, webview中HTML body的最下面额外出现了一块空白区域.
如下图所示. 这个额外的空白区域不在WKScrollView的contentSize之内, 但是却可以滑动, 并显示出来... 一开始想的是如何将这块区域给删掉, 但技术有限, 没删掉...

WX20211231-160137@2x.png

最后是通过UIScrollView的scrollViewDidScroll监听当前的contentOffset是否超过了正常范围, 当超过正常范围后, 重置contentOffset来解决的. 虽然解决了, 但是滑动到底部时的反弹效果却没了... 如果有大佬有更好的解决办法的话, 欢迎指教. 代码如下:

/// 当滑动范围超过webview的HTML body底部时, 强制重新设置contentOffset到webview底部.
extension YourWebviewVC: UIScrollViewDelegate{
    internal func scrollViewDidScroll(_ scrollView: UIScrollView) {
        self.adjustWebviewOffsetFor(scrollView);
    }
    
    private func adjustWebviewOffsetFor(_ scrollView: UIScrollView, animated: Bool = false){
        let currentY = scrollView.contentOffset.y + scrollView.frame.height;
        if currentY > scrollView.contentSize.height{
            let maxOffset = scrollView.contentSize.height - scrollView.frame.height;
            scrollView.setContentOffset(CGPoint(x: 0, y: maxOffset), animated: animated);
        }
    }
}

另外修改高度之后, webview里的内容有时候会出现往上移动的情况(概率大概30%吧, 原因未知), 可以在修改完高度之后, 将contentOffset设置为修改高度之前的contentOffset来解决, 示例如下:

/// Change webview frame when keyboard appear.
NotificationCenter.default.rx
.notification(UIApplication.keyboardDidShowNotification)
.subscribe(onNext: { [weak self] keyboardConfig in
    if let userInfo = keyboardConfig.userInfo, let this = self {
        let keyboardBounds = (userInfo["UIKeyboardFrameEndUserInfoKey"] as! NSValue).cgRectValue;
        this.webView.snp.remakeConstraints({ make in
            make.left.right.top.equalToSuperview();
            /// remake from screen height to below height.
            make.height.equalTo(UIScreen.main.bounds.size.height - keyboardBounds.size.height);
        });
        let originalOffset = this.webView.scrollView.contentOffset;
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
            /// 关键的地方!!! 不加延时的话会有点问题. 具体可以自己踩坑😂
            this.webView.scrollView.contentOffset = originalOffset;
        }
    }
});