XCode 6 beta 中的 IB 对象模板似乎仍在创建旧式对象(iOS 的 UIWebView 和 OSX 的 WebView)。希望 Apple 会为现代 WebKit 更新它们,但在那之前,在 Interface Builder 中创建 WKWebViews 的最佳方法是什么?我应该创建一个基本视图(UIView 或 NSView)并将其类型分配给 WKWebView 吗?我在网上找到的大多数示例都以编程方式将其添加到容器视图中;出于某种原因,这更好吗?
12 回答
你是对的 - 它似乎不起作用。如果您查看标题,您会看到:
- (instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE;
这意味着您不能从笔尖实例化一个。
您必须在 viewDidLoad 或 loadView 中手动完成。
正如一些人指出的那样,从 Xcode 6.4 开始,WKWebView 在 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)
}
}
}
信息列表
添加您的 Info.plist 传输安全设置
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Xcode 9.1+
使用界面构建器
您可以在对象库中找到 WKWebView 元素。
使用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)
}
}
使用 Xcode 8,这现在是可能的,但至少可以说实现它的方法有点笨拙。但是,嘿,一个可行的解决方案就是一个可行的解决方案,对吧?让我解释。
WKWebView 的 initWithCoder: 不再注释为“NS_UNAVAILABLE”。它现在看起来如下所示。
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
首先继承 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;
}
在您的 Storyboard 中,使用 UIView 并为其提供新子类的自定义类。其余的一切照旧(设置自动布局约束,将视图链接到控制器中的插座等)。
最后,WKWebView 对内容的缩放与 UIWebView 不同。许多人可能会想要遵循Suppress WKWebView 中的简单建议,从缩放内容到以与 UIWebView 相同的放大率进行渲染,以使 WKWebView 在这方面更接近 UIWebView 行为。
这是一个基于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
}
}
在 Interface Builder 中创建一个 UIView,分配您的约束,并将其分配WKWebView_IBWrapper
为自定义类,如下所示:
这现在显然已在 Xcode 9b4 中修复。发行说明说“WKWebView 在 iOS 对象库中可用”。
我还没有深入了解它是否需要 iOS 11 或向后兼容。
在 XCode 版本 9.0.1 中,WKWebView 在 Interface Builder 上可用。
不确定这是否有帮助,但我通过包含目标的 WebKit 框架为我解决了这个问题。不要嵌入它只是链接参考。我仍然在 IB 中使用 WebView 对象并将其放在要嵌入它的 ViewController 上,而且我从来没有遇到过问题......
我现在已经处理了 4 个 WKWebView MacOS 项目,并且 WebView 在每个项目中都能正常工作。
这在 Xcode 7.2 中对我有用...
首先将 web 视图添加为故事板/IB 中的 UIWebView 插座。这将为您提供如下属性:
@property (weak, nonatomic) IBOutlet UIWebView *webView;
然后只需编辑您的代码以将其更改为 WKWebView。
@property (weak, nonatomic) IBOutlet WKWebView *webView;
您还应该在身份检查器中将自定义类更改为 WKWebView。