如何配置 WKWebView 来填充 NSWindow?

How to configure a WKWebView to fill an NSWindow?

我在 Swift 中使用 XCode 7.2 开发了一个小型原型应用程序。该应用程序创建为 Cocoa 基于文档的应用程序,带有故事板。因此,该项目包含 AppDelegate.swiftDocument.swiftMain.storyboard,所有这些都与 XCode 生成的内容没有变化,而 ViewController.swift 包含以下内容:

import Cocoa
import WebKit

class ViewController: NSViewController {

    var webView: WKWebView {
        return view as! WKWebView
    }

    override func loadView() {
        view = WKWebView(/*frame: CGRect(x: 0, y: 0, width: 200, height: 200)*/)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        webView.loadHTMLString("<html><body><p>Hello, World!</p></body></html>", baseURL: nil)
    }
}

我已经覆盖loadView()直接创建一个WKWebView并将其分配给ViewControllerview属性作为根视图,而不是而不是加载情节提要中定义的视图。

请注意,WKWebViewframe 参数可能会被注释掉或被注释掉,以展示作为该问题根源的不同行为。

期望的行为

一个WKWebView实例应该填充每个文档对应的window,新文档windows的初始大小和位置应该是为NSWindow定义的在故事板中(在 (196, 240) 处为 480x270)。 WKWebView 应使用封闭的 window.

调整大小

观察到的行为

没有 frame 参数

没有 frame 参数,运行 应用程序时不会显示文档 window,即使 Window菜单显示已创建 'Untitled' 文档。使用 File > New.

创建更多文档(Untitled 2 等)时,也不会显示文档 windows

但是,如果使用 View > Enter Full Screen 全屏显示文档,WKWebView 及其问候语会按预期显示。

使用 frame 参数

使用 frame 参数,包含 WKWebView 及其问候语的文档 windows 显示在给定的大小和位置CGRect.

问题

我不明白为什么,当 WKWebView 的 frame 没有指定时,视图在全屏模式下被强制为容器(屏幕)的大小,但在 windowed 模式似乎发生了相反的情况:window 被强制为视图的(退化?)大小,因此变得不可见。我期待新视图采用情节提要中定义的 window 的大小。

在我的 ViewController 中,如何配置我的 WKWebView 实例来填充 NSWindow 文档框架生成的对应于每个 NSDocument 的实例?或者,也许我的方法是错误的,我应该接受通过 ViewController.loadView()?

中的视图大小配置初始 window 大小

所以我的第一反应是:为什么不直接将 WKWebView 添加到故事板中呢?这样,您可以调整它的大小,使其成为封闭 window 的大小。原来你不能将 WKWebView 添加到 Interface Builder 中(这就是为什么我认为你必须走这条路)。

loadView,默认情况下,将实例化视图从 nib 连接到视图控制器的视图 属性。覆盖 loadView 然后分配 self.view 的问题在于它破坏了 window 内容与您的 ViewController 的故事板关系。

所以解决方法是等待self.view从故事板中加载出来,然后添加WKWebView作为子视图:

- (void)viewDidLoad {
    WKWebView *wb = [[WKWebView alloc] initWithFrame:self.view.frame];
    [wb loadHTMLString:@"<html><body><p>Hello, World!</p></body></html>" baseURL:nil];
    [self.view addSubview:wb];
}

我只有Objective-C。抱歉还没有学会 Swift。

试试这个方法。您应该先调用 super.loadView() 。这将为您提供从故事板加载的视图的初始大小。然后使用原始视图的框架将视图本身更改为 Web 视图。希望这能解决您的问题。

override func loadView() {
    super.loadView()
    view = WKWebView(frame:self.view.frame)
}

您也可以尝试设置 Web 视图的背景颜色以查看其是否有效。

webView.loadHTMLString("<html><body bgcolor=red><p>Hello, World!</p></body></html>", baseURL: nil)