ios 界面生成器中的 WKWebView

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24167812/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 00:49:42  来源:igfitidea点击:

WKWebView in Interface Builder

iosxcodemacosuiwebviewwkwebview

提问by Adam Fox

It seems that the IB object templates in XCode 6 beta are still creating old-style objects (UIWebView for iOS and WebView for OSX). Hopefully Apple will update them for the modern WebKit, but until then, what is the best way to create WKWebViews in Interface Builder? Should I create a basic view (UIView or NSView) and assign its type to WKWebView? Most of the examples I find online add it to a container view programmatically; is that better for some reason?

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

采纳答案by EricS

You are correct - it doesn't seem to work. If you look in the headers, you'll see:

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

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

which implies that you can't instantiate one from a nib.

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

You'll have to do it by hand in viewDidLoad or loadView.

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

回答by Johan

As pointed out by some, as of Xcode 6.4, WKWebView is still not available on Interface Builder. However, it is very easy to add them via code.

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

I'm just using this in my ViewController. Skipping 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)
        }
    }
}

回答by Vasily Bodnarchuk

Info.plist

信息表

add in your Info.plist transport security setting

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

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

Xcode 9.1+

Xcode 9.1+

Using interface builder

使用界面构建器

You can find WKWebView element in the Object library.

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

enter image description here

在此处输入图片说明

Add view programmatically with Swift 5

使用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

Add view programmatically with Swift 5(full sample)

使用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)
    }
}

回答by crx_au

With Xcode 8 this is now possible, but the means of achieving it is a little hacky to say the least. But hey, a working solution is a working solution, right? Let me explain.

使用 Xcode 8 现在可以做到这一点,但至少可以说实现它的方法有点困难。但是,嘿,有效的解决方案就是有效的解决方案,对吗?让我解释。

WKWebView's initWithCoder: is no longer annotated as "NS_UNAVAILABLE". It now looks as shown below.

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

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

Start by subclassing WKWebView and override initWithCoder. Instead of calling super initWithCoder, you'll need to use a different init method, such as initWithFrame:configuration:. Quick example below.

首先继承 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;
}

Over in your Storyboard, use a UIView and give it a custom class of your new subclass. The rest is business as usual (setting auto-layout constraints, linking the view to an outlet in a controller, etc).

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

Finally, WKWebView scales content differently to UIWebView. Many people are likely going to want to follow the simple advice in Suppress WKWebView from scaling content to render at same magnification as UIWebView doesto make WKWebView more closely follow the UIWebView behaviour in this regard.

最后,WKWebView 以与 UIWebView 不同的方式缩放内容。许多人可能希望遵循Suppress WKWebView 中的简单建议,从缩放内容到以与 UIWebView 相同的放大倍率呈现,以使 WKWebView 在这方面更紧密地遵循 UIWebView 行为。

回答by Gamma

Here's a simple Swift 3 version based on crx_au's excellent answer.

这是一个基于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
    }
}

Create a UIView in Interface Builder, assign your constraints, and assign it WKWebView_IBWrapperas a custom class, like so:

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

Utilities ->Identity Inspector Tab[1]

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

回答by MrDEV

If you still face this issue in recent versions of Xcode, i.e. v9.2+, simply import Webkit to your ViewController:

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

#import <WebKit/WebKit.h>
  1. Before the fix: enter image description here

  2. After the fix:

  1. 修复前: 在此处输入图片说明

  2. 修复后:

enter image description here

在此处输入图片说明

回答by EricS

This is now apparently fixed in Xcode 9b4. The release notes say "WKWebView is available in the iOS object library."

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

I haven't looked deeper to see if it requires iOS 11 or is backward compatible yet.

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

回答by atineoSE

You can instantiate and configure a WKWebView in IB since Xcode 9, no need to do it in code. enter image description here

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

Note that your deployment target has to be higher than iOS 10 though or you will get a compile-time error.

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

enter image description here

在此处输入图片说明

回答by daybreak zhou

I've linked WebKit, now it's working!

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

example

例子

回答by ranTrek

Not sure if this helps but I solved the problem for me by including the WebKit framework for the target. Don't embed it just link the reference. I still use the WebView object in IB and drop it on the ViewController I'm embedding it in and I've never had a problem...

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

I've worked on 4 WKWebView MacOS projects now and the WebView has worked properly in each project.

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