WKWebView in the Builder interface

It seems that IB object templates in Xcode 6 beta still create old-style objects (UIWebView for iOS and WebView for OSX). I hope Apple updates them for modern WebKit, but until then, what's the best way to create WKWebViews in Interface Builder? Should I create a base view (UIView or NSView) and assign it a type of WKWebView? Most of the examples that I find on the Internet are added to the container view programmatically; is somehow better?

+94
ios xcode uiwebview wkwebview macos
Jun 11 '14 at 16:16
source share
11 answers

You are right - it does not work. If you look in the headlines, you will see:

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

which means you cannot create an instance of one of the nibs.

You will have to do this manually in viewDidLoad or loadView.

+69
Jun 19 '14 at 3:37
source share

As pointed out by some, with Xcode 6.4, WKWebView is still not available in Interface Builder. However, they are very easy to add through code.

I just use this in my ViewController. Builder Interface Skip

 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
Jun 16 '14 at 11:54 on
source share

Info.plist

add Info.plist to the transport security settings

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

Xcode 9.1+

Using Interface Constructor

You can find the WKWebView element in the object library.

enter image description here

Add a view programmatically using 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)

 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
Nov 25 '16 at 21:30
source share

With Xcode 8, this is now possible, but the means to achieve this is a little less hacked. But hey, a working solution is a working solution, right? Let me explain.

WKWebView initWithCoder: no longer annotated as "NS_UNAVAILABLE". Now it looks like below.

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

Start by subclassing WKWebView and override initWithCoder. Instead of calling super initWithCoder, you will need to use another init method, such as initWithFrame: configuration :. A quick example below.

 - (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, eg // myConfiguration.dataDetectorTypes = WKDataDetectorTypeAll; self = [super initWithFrame:frame configuration:myConfiguration]; // Apply constraints from interface builder. self.translatesAutoresizingMaskIntoConstraints = NO; return self; } 

In your storyboard, use UIView and give it your own class in your new subclass. The rest is a common thing (setting automatic layout restrictions, binding the view to a socket in the controller, etc.).

Finally, WKWebView scales content differently for UIWebView. Many people will probably want to follow the simple tips in Suppress WKWebView from scaling content for rendering with the same magnification as UIWebView , so that WKWebView closely follows the behavior of UIWebView in this regard.

+19
Oct 18 '16 at 21:47
source share

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

 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 restrictions and assign it WKWebView_IBWrapper as a custom class, for example:

Utilities -> Identity Inspector Tab [1]

+17
Jul 17 '17 at 11:14
source share

Now this seems to be fixed in Xcode 9b4. The release notes say: "WKWebView is available in the iOS object library."

I have not looked deeper to find out if it requires iOS 11 or is backward compatible.

+4
Jul 24 '17 at 18:59
source share

If you are still experiencing this issue in recent versions of Xcode, i.e. v9. 2+, just import Webkit into your ViewController:

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

  2. After correction:

enter image description here

+2
Feb 22 '18 at 17:33
source share

You can create and configure WKWebView in IB starting with Xcode 9, there is no need to do this in code. enter image description here

Please note that your deployment goal should be higher than iOS 10, otherwise you will get an error during compilation.

enter image description here

+1
May 03 '18 at 14:42
source share

In Xcode version 9.0.1, WKWebView is available in Interface Builder.

0
Oct 26 '17 at 2:38 on
source share

I linked WebKit, now it works!

example

0
Jun 26 '19 at 7:54
source share

This worked for me in Xcode 7.2 ...

First add the web view as a UIWebView output to the / IB storyboard. This will give you the following property:

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

Then just change your code to change it to WKWebView.

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

You must also change the custom class to WKWebView in the identity inspector.

-12
Dec 13 '15 at 19:26
source share



All Articles