似乎XCode 6 beta中的IB对象模板仍在创建旧式对象(iOS的UIWebView和OSX的WebView)。希望苹果公司能够为现代WebKit更新它们,但是在那之前,在Interface Builder中创建WKWebViews的最佳方法是什么?我应该创建一个基本视图(UIView或NSView)并将其类型分配给WKWebView吗?我在网上找到的大多数示例都以编程方式将其添加到容器视图中。出于某种原因更好吗?
似乎XCode 6 beta中的IB对象模板仍在创建旧式对象(iOS的UIWebView和OSX的WebView)。希望苹果公司能够为现代WebKit更新它们,但是在那之前,在Interface Builder中创建WKWebViews的最佳方法是什么?我应该创建一个基本视图(UIView或NSView)并将其类型分配给WKWebView吗?我在网上找到的大多数示例都以编程方式将其添加到容器视图中。出于某种原因更好吗?
Answers:
您是正确的-似乎没有用。如果您查看标题,将会看到:
- (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)
}
}
}
self.view
内部loadView()
是导致无限递归的原因。另一方面,设置视图不仅是允许的,而且确实是必需的(手动或通过链接到super
。否则,只要视图为,它将一直被调用nil
)。
信息清单
添加您的Info.plist传输安全设置
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
使用界面构建器
您可以在对象库中找到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)
}
}
WebView
。crx_au的反应非常出色
借助Xcode 8,现在可以实现这一点,但是至少可以说,实现它的方法有些棘手。但是,嘿,一个可行的解决方案就是一个可行的解决方案,对吗?让我解释。
WKWebView的initWithCoder:不再注释为“ NS_UNAVAILABLE”。现在看起来如下图所示。
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
首先子类化WKWebView并覆盖initWithCoder。无需调用超级initWithCoder,您需要使用其他init方法,例如initWithFrame:configuration:。下面的快速示例。
- (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不同。许多人可能希望遵循Suppress WKWebView中的简单建议,即缩放内容以与UIWebView相同的放大率进行渲染,以使WKWebView在这方面更紧密地遵循UIWebView行为。
self = [super initWithFrame:myFrame configuration:myConfiguration];
如果您使用约束,它也应该阅读,别忘了设置self.translatesAutoresizingMaskIntoConstraints = NO;
这是一个基于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 7.2中对我有用...
首先在情节提要/ IB中将Web视图添加为UIWebView出口。这将为您提供如下属性:
@property (weak, nonatomic) IBOutlet UIWebView *webView;
然后,只需编辑代码即可将其更改为WKWebView。
@property (weak, nonatomic) IBOutlet WKWebView *webView;
您还应该在身份检查器中将自定义类更改为WKWebView。