96

XCode 6 beta 中的 IB 对象模板似乎仍在创建旧式对象(iOS 的 UIWebView 和 OSX 的 WebView)。希望 Apple 会为现代 WebKit 更新它们,但在那之前,在 Interface Builder 中创建 WKWebViews 的最佳方法是什么?我应该创建一个基本视图(UIView 或 NSView)并将其类型分配给 WKWebView 吗?我在网上找到的大多数示例都以编程方式将其添加到容器视图中;出于某种原因,这更好吗?

4

12 回答 12

72

你是对的 - 它似乎不起作用。如果您查看标题,您会看到:

- (instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE;

这意味着您不能从笔尖实例化一个。

您必须在 viewDidLoad 或 loadView 中手动完成。

于 2014-06-19T03:37:37.927 回答
66

正如一些人指出的那样,从 Xcode 6.4 开始,WKWebView 在 Interface Builder 上仍然不可用。但是,通过代码添加它们非常容易。

我只是在我的 ViewController 中使用它。跳过界面构建​​器

import UIKit
import WebKit

class ViewController: UIViewController {

    private var webView: WKWebView?

    override func loadView() {
        webView = WKWebView()

        //If you want to implement the delegate
        //webView?.navigationDelegate = self

        view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        if let url = URL(string: "https://google.com") {
            let req = URLRequest(url: url)
            webView?.load(req)
        }
    }
}
于 2014-06-16T11:54:40.937 回答
30

信息列表

添加您的 Info.plist 传输安全设置

 <key>NSAppTransportSecurity</key>
 <dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
 </dict>

Xcode 9.1+

使用界面构建器

您可以在对象库中找到 WKWebView 元素。

在此处输入图像描述

使用Swift 5以编程方式添加视图

let webView = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
view.addSubview(webView)
webView.translatesAutoresizingMaskIntoConstraints = false
webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
webView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor).isActive = true
webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
webView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true

使用Swift 5以编程方式添加视图(完整示例)

import UIKit
import WebKit

class ViewController: UIViewController {

    private weak var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        initWebView()
        webView.loadPage(address: "http://apple.com")
    }

    private func initWebView() {
        let webView = WKWebView(frame: .zero, configuration: WKWebViewConfiguration())
        view.addSubview(webView)
        self.webView = webView
        webView.translatesAutoresizingMaskIntoConstraints = false
        webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
        webView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor).isActive = true
        webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
        webView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor).isActive = true
    }
}

extension WKWebView {
    func loadPage(address url: URL) { load(URLRequest(url: url)) }
    func loadPage(address urlString: String) {
        guard let url = URL(string: urlString) else { return }
        loadPage(address: url)
    }
}
于 2016-11-25T21:30:37.750 回答
20

使用 Xcode 8,这现在是可能的,但至少可以说实现它的方法有点笨拙。但是,嘿,一个可行的解决方案就是一个可行的解决方案,对吧?让我解释。

WKWebView 的 initWithCoder: 不再注释为“NS_UNAVAILABLE”。它现在看起来如下所示。

- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;

首先继承 WKWebView 并覆盖 initWithCoder。您需要使用不同的 init 方法,例如 initWithFrame:configuration:,而不是调用 super initWithCoder。下面的快速示例。

- (instancetype)initWithCoder:(NSCoder *)coder
{
    // An initial frame for initialization must be set, but it will be overridden 
    // below by the autolayout constraints set in interface builder. 
    CGRect frame = [[UIScreen mainScreen] bounds];
    WKWebViewConfiguration *myConfiguration = [WKWebViewConfiguration new];

    // Set any configuration parameters here, e.g.
    // myConfiguration.dataDetectorTypes = WKDataDetectorTypeAll; 

    self = [super initWithFrame:frame configuration:myConfiguration];

    // Apply constraints from interface builder.
    self.translatesAutoresizingMaskIntoConstraints = NO;

    return self;
}

在您的 Storyboard 中,使用 UIView 并为其提供新子类的自定义类。其余的一切照旧(设置自动布局约束,将视图链接到控制器中的插座等)。

最后,WKWebView 对内容的缩放与 UIWebView 不同。许多人可能会想要遵循Suppress WKWebView 中的简单建议,从缩放内容到以与 UIWebView 相同的放大率进行渲染,以使 WKWebView 在这方面更接近 UIWebView 行为。

于 2016-10-18T21:47:10.257 回答
20

这是一个基于crx_au出色答案的简单 Swift 3 版本。

import WebKit

class WKWebView_IBWrapper: WKWebView {
    required convenience init?(coder: NSCoder) {
        let config = WKWebViewConfiguration()
        //config.suppressesIncrementalRendering = true //any custom config you want to add
        self.init(frame: .zero, configuration: config)
        self.translatesAutoresizingMaskIntoConstraints = false
    }
}

在 Interface Builder 中创建一个 UIView,分配您的约束,并将其分配WKWebView_IBWrapper为自定义类,如下所示:

实用程序 -> 身份检查器选项卡[1]

于 2017-07-17T11:14:14.663 回答
6

如果你在最新版本的 Xcode 中仍然遇到这个问题,即 v9.2+,只需将 Webkit 导入你的 ViewController:

#import <WebKit/WebKit.h>
  1. 修复前: 在此处输入图像描述

  2. 修复后:

在此处输入图像描述

于 2018-02-22T17:33:40.593 回答
4

这现在显然已在 Xcode 9b4 中修复。发行说明说“WKWebView 在 iOS 对象库中可用”。

我还没有深入了解它是否需要 iOS 11 或向后兼容。

于 2017-07-24T18:59:28.377 回答
1

从 Xcode 9 开始,您可以在 IB 中实例化和配置 WKWebView,无需在代码中进行。 在此处输入图像描述

请注意,您的部署目标必须高于 iOS 10,否则您将收到编译时错误。

在此处输入图像描述

于 2018-05-03T14:42:48.297 回答
0

在 XCode 版本 9.0.1 中,WKWebView 在 Interface Builder 上可用。

于 2017-10-26T14:38:58.387 回答
0

我已经链接了 WebKit,现在它可以工作了!

例子

于 2019-06-26T07:54:01.277 回答
0

不确定这是否有帮助,但我通过包含目标的 WebKit 框架为我解决了这个问题。不要嵌入它只是链接参考。我仍然在 IB 中使用 WebView 对象并将其放在要嵌入它的 ViewController 上,而且我从来没有遇到过问题......

我现在已经处理了 4 个 WKWebView MacOS 项目,并且 WebView 在每个项目中都能正常工作。

于 2019-12-06T19:16:58.993 回答
-15

这在 Xcode 7.2 中对我有用...

首先将 web 视图添加为故事板/IB 中的 UIWebView 插座。这将为您提供如下属性:

@property (weak, nonatomic) IBOutlet UIWebView *webView;

然后只需编辑您的代码以将其更改为 WKWebView。

@property (weak, nonatomic) IBOutlet WKWebView *webView;

您还应该在身份检查器中将自定义类更改为 WKWebView。

于 2015-12-13T19:26:46.073 回答