问题
I am trying to subclass WKWebView. When I implement my own initializer, I got this error:
'required' initializer 'init(coder:)' must be provided by subclass of 'WKWebView'
Ok, that is well known that we have to implement it for subclasses of UIView. For a direct subclass of UIView it works just implementing it, but with WKWebView it does not seem so simple. I followed the Fix-it hint, and this snippet is added to the code:
required @availability(*, unavailable) convenience init!(coder: NSCoder!) {
fatalError("init(coder:) has not been implemented")
}
So I get a class like the following:
import WebKit
class TSWebView : WKWebView {
let s: String
let i: Int
init(s: String, i: Int) {
self.s = s
self.i = i
super.init(frame: CGRectZero, configuration: WKWebViewConfiguration())
}
required @availability(*, unavailable) convenience init!(coder: NSCoder!) {
fatalError("init(coder:) has not been implemented")
}
}
However, when I do this I get these four other errors:
expected declaration
required @availability(*, unavailable) convenience init!(coder: NSCoder!) {
consecutive declarations on a line must be separated by ';'
required @availability(*, unavailable) convenience init!(coder: NSCoder!) {
cannot override 'init' which has been marked unavailable
required @availability(*, unavailable) convenience init!(coder: NSCoder!) {
'required' modifier must be present on all overrides of a required initializer
required @availability(*, unavailable) convenience init!(coder: NSCoder!) {
Any ideas? My Xcode Version is 6.1.1 (6A2008a). Thanks a lot.
回答1:
This is totes possible. You must only use convenience initializers and properties with default values set:
import WebKit
class MPWebView : WKWebView {
var transparent: Bool = false
convenience init(config: WKWebViewConfiguration = WKWebViewConfiguration()) {
let prefs = WKPreferences()
prefs.plugInsEnabled = true // NPAPI for Flash, Java, Hangouts
prefs.minimumFontSize = 14
prefs.javaScriptCanOpenWindowsAutomatically = true;
config.preferences = prefs
config.suppressesIncrementalRendering = false
self.init(frame: CGRectZero, configuration: config)
}
convenience required init(url: NSURL) {
self.init(config: nil)
loadRequest(NSURLRequest(URL: url))
}
}
回答2:
Try taking out the extra decorations:
import WebKit
class TSWebView : WKWebView {
let s: String
let i: Int
init(s: String, i: Int) {
self.s = s
self.i = i
super.init(frame: CGRectZero, configuration: WKWebViewConfiguration())
}
convenience init!(coder: NSCoder!) {
super.init(coder:coder)
}
}
Although I'm guessing the whole point of the "availablity(*, unavailable)" is to make it so that you can't invoke the initializer (and hence can't effectively subclass WKWebView.
回答3:
Just override the regular initialization like this. This worked for me, Swift 5.
override init(frame: CGRect, configuration: WKWebViewConfiguration) {
super.init(frame: frame, configuration: configuration)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
来源:https://stackoverflow.com/questions/27487821/cannot-subclass-wkwebview