I'm creating a subclass of MKAnnotationView
in my project. It needs to have two properties for storing subviews which I need to initialize somewhere at the beginning.
MKAnnotationView
has one initializer listed in its documentation, initWithAnnotation:reuseIdentifier:
, so I figured I'd simply override that:
class PulsatingDotMarker: MKAnnotationView {
let innerCircle: UIView
let outerCircle: UIView
override init!(annotation: MKAnnotation!, reuseIdentifier: String!) {
innerCircle = ...
outerCircle = ...
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
}
...
}
But this causes a runtime exception:
fatal error: use of unimplemented initializer 'init(frame:)' for class 'PulsatingDotMarker'
Ok, so I guess initWithAnnotation:reuseIdentifier:
internally calls initWithFrame:
, so it's probably that one that I should override instead. Let's try that:
class PulsatingDotMarker: MKAnnotationView {
let innerCircle: UIView
let outerCircle: UIView
override init(frame: CGRect) {
innerCircle = ...
outerCircle = ...
super.init(frame: frame)
}
...
}
This however causes a compile error when creating the annotation view object:
Extra argument 'reuseIdentifier' in call
Hmm, so if I implement the (required) initializer initWithFrame:
, it now loses the default initializer initWithAnnotation:reuseIdentifier:
?
Maybe if I added an override of initWithAnnotation:reuseIdentifier:
that just calls super
it will be available again, will that work?
class PulsatingDotMarker: MKAnnotationView {
let innerCircle: UIView
let outerCircle: UIView
init!(annotation: MKAnnotation!, reuseIdentifier: String!) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
}
override init(frame: CGRect) {
innerCircle = ...
outerCircle = ...
super.init(frame: frame)
}
...
}
Nope, still not good - compile error:
Property 'self.innerCircle' not initialized at super.init call
Ok, what if I had an initWithFrame:
, but initialized the subviews in initWithAnnotation:reuseIdentifier:
? (But then what if someone just calls initWithFrame:
directly?...)
class PulsatingDotMarker: MKAnnotationView {
let innerCircle: UIView
let outerCircle: UIView
init!(annotation: MKAnnotation!, reuseIdentifier: String!) {
innerCircle = ...
outerCircle = ...
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
...
}
Not surprisingly, Swift protects me from that by telling me:
Property 'self.innerCircle' not initialized at super.init call
(this time in initWithFrame:
).
So what am I supposed to do? I can't create the subviews both here and there, right?
class PulsatingDotMarker: MKAnnotationView {
let innerCircle: UIView
let outerCircle: UIView
init!(annotation: MKAnnotation!, reuseIdentifier: String!) {
innerCircle = ...
outerCircle = ...
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
}
override init(frame: CGRect) {
innerCircle = ...
outerCircle = ...
super.init(frame: frame)
}
...
}
Wrong again, this actually works - even though I'm assigning a constant property twice in the same object (!).
How should this be done properly?
(Note: the class also included a required initWithCoder:
initializer that just calls fatalError
from the first example, but the object is never created from a storyboard.)
var innerCircle: UIView!
? That may avoid the "required init(xxx)" errors. – Manual[self initWith...]
method in its publicinit
method), but unfortunately no solutions as yet - #31161643 – Earthenware