Skip to content

Instantly share code, notes, and snippets.

@mackuba
Last active August 17, 2016 12:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mackuba/4c897c9d0fd33647f2e9 to your computer and use it in GitHub Desktop.
Save mackuba/4c897c9d0fd33647f2e9 to your computer and use it in GitHub Desktop.
Swift MKAnnotationView WTF
/*
MKAnnotationView has one init listed in its documentation, initWithAnnotation:reuseIdentifier:, so let's override that.
But this causes a runtime exception:
fatal error: use of unimplemented initializer 'init(frame:)' for class 'PulsatingDotMarker'
*/
class PulsatingDotMarker: MKAnnotationView {
let innerCircle: UIView
let outerCircle: UIView
override init!(annotation: MKAnnotation!, reuseIdentifier: String!) {
innerCircle = ...
outerCircle = ...
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
}
...
}
/*
Ok, I guess initWithAnnotation:reuseIdentifier: internally calls initWithFrame:, so it's probably that one that I should
override instead. So let's do that.
Nice try - compile error: "Extra argument 'reuseIdentifier' in call" when creating the object... So if I implement the (required)
initializer initWithFrame:, it now loses the default initializer initWithAnnotation:reuseIdentifier:, wtf?
*/
class PulsatingDotMarker: MKAnnotationView {
let innerCircle: UIView
let outerCircle: UIView
override init(frame: CGRect) {
innerCircle = ...
outerCircle = ...
super.init(frame: frame)
}
...
}
/*
Maybe if I added an override of initWithAnnotation:reuseIdentifier: that just calls super it will be available again?
Nope, still not good - compile error: "Property 'self.innerCircle' not initialized at super.init call". Well, duh, it isn't,
because it's only set in initWithFrame: which you told me to implement...
*/
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)
}
...
}
/*
What if I had an initWithFrame:, but initialized the subviews in initWithAnnotation:reuseIdentifier:? But then what if someone
just calls initWithFrame: directly, which they can do since I explicitly made that initializer available (because I had to)?
Yeah, of course, Swift protects me from that too by telling me "Property 'self.innerCircle' not initialized at super.init call"
again, 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) {
super.init(frame: frame)
}
...
}
/*
And surprise surprise, this works - even though I'm assigning a constant property twice in the same object (?!?!).
*/
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)
}
...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment