web-dev-qa-db-ja.com

Interface BuilderのWKWebView

XCode 6ベータ版のIBオブジェクトテンプレートは、まだ古いスタイルのオブジェクト(iOSのUIWebViewとOSXのWebView)を作成しているようです。 Appleが最新のWebKit用に更新されることを願っていますが、それまでは、Interface BuilderでWKWebViewを作成する最良の方法は何ですか?基本ビュー(UIViewまたはNSView)を作成し、そのタイプをWKWebViewに割り当てる必要がありますか?私がオンラインで見つけたほとんどの例では、プログラムでコンテナビューに追加しています。何らかの理由でそれは良いですか?

93
Adam Fox

あなたは正しいです-それは動作していないようです。ヘッダーを見ると、以下が表示されます:

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

これは、ペン先からインスタンスを作成できないことを意味します。

ViewDidLoadまたはloadViewで手動で行う必要があります。

69
EricS

一部の人が指摘したように、Xcode 6.4現在、WKWebViewはInterface Builderではまだ利用できません。ただし、コードを使用して追加するのは非常に簡単です。

ViewControllerでこれを使用しています。 Interface Builderをスキップしています

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)
        }
    }
}
65
Johan

Info.plist

info.plistトランスポートセキュリティ設定を追加します

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

Xcode 9.1+

インターフェースビルダーを使用する

WKWebView要素は、オブジェクトライブラリにあります。

enter image description here

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)
    }
}
28

Xcode 8ではこれが可能になりましたが、それを達成する手段は控えめに言っても少しハッキーです。でも、作業ソリューションは作業ソリューションですよね?説明させてください。

WKWebViewのinitWithCoder:には「NS_UNAVAILABLE」という注釈が付けられなくなりました。以下のようになります。

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

WKWebViewをサブクラス化して開始し、initWithCoderをオーバーライドします。スーパーinitWithCoderを呼び出す代わりに、initWithFrame:configuration:などの別のinitメソッドを使用する必要があります。以下の簡単な例。

- (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;
}

ストーリーボードで、UIViewを使用して、新しいサブクラスのカスタムクラスを指定します。残りは通常のビジネスです(自動レイアウト制約の設定、ビューをコントローラーのアウトレットにリンクするなど)。

最後に、WKWebViewはUIWebViewとは異なる方法でコンテンツをスケーリングします。多くの人は WKWebViewがコンテンツのスケーリングを抑制してUIWebViewと同じ倍率でレンダリングする の簡単なアドバイスに従うことで、WKWebViewがこの点でUIWebViewの動作をより厳密に追跡できるようになるでしょう。

19
crx_au

crx_aの優れた答えに基づいた、シンプルな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をカスタムクラスとして割り当てます。

Utilities -> Identity Inspector Tab[1]

17
Gamma

これは明らかにXcode 9b4で修正されました。リリースノートには、「WKWebViewはiOSオブジェクトライブラリで利用可能です」と書かれています。

IOS 11を必要とするのか、下位互換性があるのか​​を確認するために、まだ詳しく調べたことがありません。

4
EricS

Xcodeの最新バージョン(v9.2以降)でこの問題にまだ直面している場合は、ViewkitにWebkitをインポートするだけです:

#import <WebKit/WebKit.h>
  1. 修正前: enter image description here

  2. 修正後:

enter image description here

2
MrDEV

Xcode 9以降、コードで実行する必要がないため、IBでWKWebViewをインスタンス化および設定できます。 enter image description here

ただし、展開ターゲットはiOS 10よりも高くする必要があります。そうしないと、コンパイル時エラーが発生します。

enter image description here

1
atineoSE

WebKitをリンクしましたが、今は機能しています!

example

0
daybreak zhou

XCodeバージョン9.0.1では、Interface BuilderでWKWebViewを使用できます。

0
ManuelMB