WKWebView dans Interface Builder

Il semble que les templates d'object IB dans XCode 6 beta créent toujours des objects de style ancien (UIWebView pour iOS et WebView pour OSX). Espérons qu'Apple les mettra à jour pour le WebKit moderne, mais jusque-là, quelle est la meilleure façon de créer WKWebViews dans Interface Builder? Dois-je créer une vue de base (UIView ou NSView) et affecter son type à WKWebView? La plupart des exemples que je trouve en ligne l'ajoutent à une vue de conteneur par programmation; est-ce mieux pour une raison quelconque?

Vous avez raison – cela ne semble pas fonctionner. Si vous regardez dans les en-têtes, vous verrez:

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

ce qui implique que vous ne pouvez pas instancier un d'une plume.

Vous devrez le faire à la main dans viewDidLoad ou loadView.

Comme mentionné par certains, à partir de Xcode 6.4, WKWebView n'est toujours pas disponible sur Interface Builder. Cependant, il est très facile de les append via le code.

Je l'utilise juste dans mon ViewController. Sauter l'interface de constructor

 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(ssortingng: "https://google.com") { let req = URLRequest(url: url) webView?.load(req) } } } 

xCode 9.1

Vous pouvez find l'élément WKWebView dans la bibliothèque d'objects.

entrez la description de l'image ici

Swift 3 et xCode 8

en utilisant StoryBoard

ViewController.swift

 import UIKit import WebKit // Add WKWebView in StoryBoard class ViewController: UIViewController { @IBOutlet var webView: WebView! override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) webView.loadUrl(ssortingng: "http://apple.com") } } class WebView: WKWebView { required init?(coder: NSCoder) { if let _view = UIView(coder: coder) { super.init(frame: _view.frame, configuration: WKWebViewConfiguration()) autoresizingMask = _view.autoresizingMask } else { return nil } } func loadUrl(ssortingng: Ssortingng) { if let url = URL(ssortingng: ssortingng) { load(URLRequest(url: url)) } } } 

Main.storyboard

 <?xml version="1.0" encoding="UTF-8"?> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11542" systemVersion="16B2555" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r"> <device id="retina4_7" orientation="portrait"> <adaptation id="fullscreen"/> </device> <dependencies> <deployment identifier="iOS"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11524"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> <scenes> <!--View Controller--> <scene sceneID="tne-QT-ifu"> <objects> <viewController id="BYZ-38-t0r" customClass="ViewController" customModule="stackoverflow_24167812" customModuleProvider="target" sceneMemberID="viewController"> <layoutGuides> <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/> <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/> </layoutGuides> <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC"> <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0zg-ri-o6Y" customClass="WebView" customModule="stackoverflow_24167812" customModuleProvider="target"> <rect key="frame" x="0.0" y="20" width="375" height="647"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> </view> </subviews> <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> </view> <connections> <outlet property="webView" destination="0zg-ri-o6Y" id="G0g-bh-eej"/> </connections> </viewController> <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/> </objects> <point key="canvasLocation" x="140" y="138.98050974512745"/> </scene> </scenes> </document> 

par programme

 import UIKit import WebKit // Add WKWebView programmatically class ViewController: UIViewController { var webView: WKWebView? override func viewDidLoad() { super.viewDidLoad() // init webView webView = WKWebView(frame: view.bounds) view.addSubview(webView!) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // load url webView?.loadUrl(ssortingng: "http://apple.com") } } extension WKWebView { func loadUrl(ssortingng: Ssortingng) { if let url = URL(ssortingng: ssortingng) { load(URLRequest(url: url)) } } } 

Avec Xcode 8, c'est maintenant possible, mais les moyens d'y parvenir sont un peu hacky, c'est le less qu'on puisse dire. Mais bon, une solution de travail est une solution de travail, non? Laisse-moi expliquer.

InitWithCoder de WKWebView: n'est plus annoté comme "NS_UNAVAILABLE". Il ressemble maintenant comme montré ci-dessous.

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

Commencez par sous-classr WKWebView et surchargez initWithCoder. Au lieu d'appeler super initWithCoder, vous devrez utiliser une méthode init différente, telle que initWithFrame: configuration :. Exemple rapide ci-dessous.

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

Dans votre Storyboard, utilisez un UIView et donnez-lui une class personnalisée de votre nouvelle sous-class. Le rest est comme d'habitude (réglage des contraintes de layout automatique, reliant la vue à une prise dans un controller, etc.).

Enfin, WKWebView redimensionne le contenu différemment à UIWebView. Beaucoup de gens vont probablement vouloir suivre le conseil simple dans Suppress WKWebView de mise à l'échelle du contenu pour rendre le même grossissement que UIWebView pour faire WKWebView suivre de plus près le comportement UIWebView à cet égard.

Voici une version simple de Swift 3 basée sur l'excellente réponse de crx_au .

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

Créez un UIView dans Interface Builder, affectez vos contraintes et affectez-lui WKWebView_IBWrapper tant que class personnalisée, comme WKWebView_IBWrapper :

Utilitaires -> Onglet Inspecteur d'identité [1]

Ceci est maintenant apparemment fixé dans Xcode 9b4. Les notes de publication indiquent "WKWebView est disponible dans la bibliothèque d'objects iOS".

Je n'ai pas regardé plus en profondeur pour voir si elle nécessite iOS 11 ou est déjà rétrocompatible.

Dans XCode version 9.0.1 WKWebView est disponible sur Interface Builder.

Cela a fonctionné pour moi dans Xcode 7.2 …

Ajoutez d'abord la vue Web en tant que prise de vue UIWebView dans le storyboard / IB. Cela vous donnera une propriété comme ceci:

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

Ensuite, il suffit de modifier votre code pour le changer en WKWebView.

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

Vous devez également replace la class personnalisée par WKWebView dans l'inspecteur d'identité.