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?
-
3This is still an open bug: https://lists.webkit.org/pipermail/webkit-unassigned/2014-September/640090.html – David H Oct 31 '14 at 15:32
-
4I'm using Xcode 7.2, I don't see WKWebView in the object library. Is it still not available? – user3731622 Jan 11 '16 at 06:26
-
10Still not present in Xcode 8. – Ryan Ballantyne Sep 22 '16 at 17:39
-
2Xcode 9.0.1 now supports WKWebView in IB. All of the answers here are now deprecated. – SmileBot Nov 09 '17 at 18:24
-
1@smileBot The new version of Xcode does have WKWebView but it requires you to target iOS 11+. crx_au answer works the best -> https://stackoverflow.com/a/40118654/757503 – mikemike396 Mar 01 '18 at 15:19
12 Answers
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.

- 9,650
- 2
- 38
- 34
-
Hopefully they will change that at some point, but I suppose it's not a big deal. Johan pointed me back to the WWDC video, and even they are instantiating in code. – Adam Fox Jun 20 '14 at 19:48
-
3On the plus side, doing it in code will let you use UIWebView in iOS 7 and WKWebView in iOS 8. – EricS Jun 20 '14 at 23:22
-
Well after this answer, I think you can override this method in a subclass of WKWebView and then use it in interface builder.. but without super.initWithCoder.. let's test ! :) – zarghol Mar 09 '15 at 22:23
-
1After a personal test : you can't... "Cannot override 'init' which has been marked unavailable" too bad... – zarghol Mar 09 '15 at 23:24
-
2One reasonable thing to do might be to create a UIView subview called MyWebView that has either a WKWebView or a UIWebView as a subview, determined at runtime in initWithCoder. Then you can create MyWebView views in IB. If you are using Swift, you can even add properties that can be edited in IB using the IBInspectable keyword. – EricS Mar 10 '15 at 04:13
-
This is now possible in Interface Builder, by subclassing WKWebView. See answer from crx_au to this question. :) – Duncan Babbage Jan 09 '17 at 09:05
-
This is now apparently fixed in Xcode 9b4. The release notes say "WKWebView is available in the iOS object library.". – EricS Jul 24 '17 at 18:58
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.
I'm just using this in my ViewController. Skipping 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)
}
}
}

- 16,895
- 8
- 63
- 114

- 1,951
- 1
- 18
- 22
-
13This question is specifically about Interface Builder, so this answer isn't very helpful. – Steve Landey Jun 19 '14 at 01:43
-
5You are right. I should have started the answer with “You can't create WKWebView from IB" :) But I watch the session video “Introducing the Modern WebKit API" from WWDC and they are using Xcode so I guess that this is just something that isn’t available to us at the moment. – Johan Jun 19 '14 at 07:57
-
1Just checked out the video again, and they are instantiating their WKWebView in code. It's around the 17:20 mark in the video. – Adam Fox Jun 20 '14 at 19:46
-
1Note from UIViewController loadView: "Your custom implementation of this method should not call super." Otherwise thanks for this post. – David H Oct 31 '14 at 15:31
-
Adding a new view in the loadView method will create an infinite loop. Not recommended. Just add it as a subview in viewDidLoad. – Lee Probert Jan 14 '16 at 11:27
-
3How will it create an infinite loop? This is from description of loadView in the iOS documentation. "The view controller calls this method when its view property is requested but is currently nil." – Johan Jan 27 '16 at 09:22
-
1For Swift3: if let url = URL(string:"https://google.com") { let req = URLRequest(url:url) webView!.load(req) } – Ryan Heitner Jun 27 '16 at 10:11
-
2**_Referencing_** `self.view` inside `loadView()` is what leads to infinite recursion. **_Setting_** the view, on the other hand, is not only allowed but indeed **required** (manually, or by chaining to `super`. Otherwise it will keep being called as long as the view is `nil`). – Nicolas Miari Jul 11 '16 at 07:41
-
Setting the web view as the view controller's main view (as opposed to adding it as a subview) has the added benefit that you don't need to specify any autoresizing masks or auto-layout constraints in order for it to fit the whole screen (or the view of the parent view controller). – Nicolas Miari Jul 11 '16 at 07:44
Info.plist
add in your Info.plist transport security setting
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Xcode 9.1+
Using interface builder
You can find WKWebView element in the Object library.
Add view programmatically with 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)
}
}

- 24,482
- 9
- 132
- 127
-
It's not a good suggestion to allocate a new view in the initializer for `WebView`. crx_au's response is superior – Ilias Karim Mar 28 '17 at 18:02
-
I dont found any other thing that works!! So... as ILI4S said maybe it's not a good suggestion, i dont know if it's or not, but works properly! Thanks man, you saved my day!!:) – Jorge Cordero Mar 06 '18 at 16:58
Here's a simple Swift 3 version 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 constraints, and assign it WKWebView_IBWrapper
as a custom class, like so:

- 1,347
- 11
- 18
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.
WKWebView's initWithCoder: is no longer annotated as "NS_UNAVAILABLE". It now looks as shown below.
- (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.
- (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).
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 does to make WKWebView more closely follow the UIWebView behaviour in this regard.
-
2it should read `self = [super initWithFrame:myFrame configuration:myConfiguration];` also if you use constraints, don't forget to set `self.translatesAutoresizingMaskIntoConstraints = NO;` – Mojo66 Dec 27 '16 at 17:09
-
Rather than using the main screen's bounds as a placeholder frame, you may also us CGRectZero and save yourself some code. – Ilias Karim Mar 28 '17 at 18:03
-
-
Works flawlessly! Nice fix for not having to Target iOS 11 to get WKWebView constraints in the storyboard. – mikemike396 Mar 01 '18 at 15:17
If you still face this issue in recent versions of Xcode, i.e. v9.2+, simply import Webkit to your ViewController:
#import <WebKit/WebKit.h>

- 3,490
- 1
- 19
- 20
This is now apparently fixed in Xcode 9b4. The release notes say "WKWebView is available in the iOS object library."
I haven't looked deeper to see if it requires iOS 11 or is backward compatible yet.

- 9,650
- 2
- 38
- 34
-
I can confirm that this works! Hooray! It also works in macOS storyboards (at least for apps targeting macOS 10.13+). – Clifton Labrum Nov 21 '17 at 20:59
You can instantiate and configure a WKWebView in IB since Xcode 9, no need to do it in code.
Note that your deployment target has to be higher than iOS 10 though or you will get a compile-time error.

- 3,597
- 4
- 27
- 31
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...
I've worked on 4 WKWebView MacOS projects now and the WebView has worked properly in each project.

- 1
This worked for me in Xcode 7.2...
First add the web view as a UIWebView outlet in the storyboard / IB. This will give you a property like this:
@property (weak, nonatomic) IBOutlet UIWebView *webView;
Then just edit your code to change it to a WKWebView.
@property (weak, nonatomic) IBOutlet WKWebView *webView;
You should also change the custom class to WKWebView in the Identity inspector.

- 706
- 5
- 7
-
I tried this with an OS X project - that doesn't work, so it must be special case for iOS. – henrikstroem Dec 14 '15 at 17:01
-
2What you do is just like type-cast. It can NOT change the webView's type at all. – DawnSong Mar 04 '16 at 04:29