【问题标题】:WKWebView displays content wrong after orientation changeWKWebView 在方向更改后显示内容错误
【发布时间】:2025-11-30 15:50:02
【问题描述】:

我是 iOS 开发的新手,我正在使用 WKWebView 来显示一个使用 Vimeo Player 播放视频的页面。当应用程序启动时,它会正确显示视图,无论它当前处于什么方向。但是,一旦我改变方向,视图要么看起来被放大,要么在视频下方有空白。

令人讨厌的是,它并不一致。有时视图显示正确,有时则不正确。如果我在使用应用程序时尝试放大或缩小视图或尝试滚动,它通常会自行纠正,但即使这样似乎也不是 100% 可靠。

一些截图(在 iPad 2 上测试):

横向(正确):

纵向(正确):

横向(不正确):

纵向(不正确):

以及用于产生此结果的代码:

import Foundation
import UIKit
import WebKit

class VideoViewController : UIViewController, WKScriptMessageHandler {

@IBOutlet var containerView : UIView! = nil
var webView: WKWebView?

override func loadView() {
    super.loadView()
    self.webView = WKWebView()
    let contentController = WKUserContentController();
    let scaleToFit = WKUserScript(source: "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width, initial-scale=1.0'); document.getElementsByTagName('head')[0].appendChild(meta);", injectionTime: WKUserScriptInjectionTime.AtDocumentStart, forMainFrameOnly: true)
    contentController.addUserScript(scaleToFit)
    contentController.addScriptMessageHandler(self, name: "callbackHandler")
    self.view = webView!
}

override func viewDidLoad() {
    super.viewDidLoad()
    refreshUI()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func refreshUI() {
    let url = NSURL(string: "https://photofactsacademy.nl/api/vp.asp?id=152839850")
    let requestObj = NSURLRequest(URL: url!)
    webView!.loadRequest(requestObj)
}

func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
    if(message.name == "callbackHandler") {
        print("JavaScript is sending a message \(message.body)")
    }
}
}

我查看了 SO 以了解 WKWebView 和方向变化,但没有找到任何对我有帮助的东西。

感谢您的帮助。

【问题讨论】:

  • 也许设置设备旋转的框架: override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) { //设置 webview 的框架??? }
  • 不幸的是,这不起作用。我最终得到了相同的结果。
  • 我遇到了同样的问题。您的解决方案确实有效。尽管 JavaScript 调用被调用和执行之间有一点延迟。猜猜我们将不得不忍受它。
  • 您找到解决方案了吗?

标签: ios swift wkwebview


【解决方案1】:

你可以试试这个

wkWebView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

【讨论】:

  • 我也遇到了这个问题,但是对于objective-c。添加 self.webView.translatesAutoresizingMaskIntoConstraints = NO; self.webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
【解决方案2】:

我能够通过注入这样的 javascript reload 调用来解决这个问题:

斯威夫特:

 func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animateAlongsideTransition(nil, completion: {
     //Reset Frame of Webview
     webView.evaluateJavaScript("location.reload();", completionHandler: nil)
}

目标 C:

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    //Reset Frame of Webview
    [_webView evaluateJavaScript:@"location.reload();" completionHandler:^(id _Nullable obj, NSError * _Nullable error) {
        NSLog(@"error:%@", error);
    }];
}

【讨论】:

  • 更新为包含两者,希望没问题。
  • 这会重新加载整个页面...假设您已经导航到更深的链接...调用它会将您带到基本链接...。
  • 我把这个答案与来自 Abdul Yasin 的答案结合在了 *.com/a/57164217/1244883 下面,它就像一个魅力。本质上是在viewWillTransitionToSize 内部调用webView.reloadInputViews
【解决方案3】:

您无需重新加载整个网页。您只需要重新加载其输入视图。确保您已正确设置 Web 视图的约束,然后在更改方向时添加以下代码。

   // Reload inputs so that webview can adjust its content according to orientation
     [self.webView reloadInputViews];

【讨论】:

  • “同时改变方向”,如何?
  • @DanielSpringer:有一些方法,在方向改变时调用。例如。 didRotateFromInterfaceOrientation()。但对我来说,这对我的情况没有帮助......
  • 那你在改变方向的同时运行代码是怎么做的?
  • 请参阅下面的@andre 评论。本质上在 viewWillTransitionToSize 中调用 webView.reloadInputViews
【解决方案4】:

经过几个小时的挣扎,这对我有用:

<header><meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, shrink-to-fit=no'></header><body style='margin: 0px; padding: 0px; width:100%; height:100%;'>...

将正文和视频元素的宽度和高度设置为 100%,并禁止用户通过标题标签进行缩放。

【讨论】:

  • 对于任何网站来说都不是一个好主意...只有在您控制一个网站时才有效。
  • 好吧,我还没有测试过这个,但是 - 你可以在你的 webview 中输入一个自定义的 html,同时在 body 中也有一个 iframe 可以加载任何网站。也许问题也可以这样解决。
  • 这是一种解决方法,但最好的办法是让网站自己选择它的设置。