initialization - what initializers should a MKAnnotationView subclass have in Swift? -
i'm creating subclass of mkannotationview
in project. needs have 2 properties storing subviews need initialize somewhere @ beginning.
mkannotationview
has 1 initializer listed in documentation, initwithannotation:reuseidentifier:
, figured i'd 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 causes runtime exception:
fatal error: use of unimplemented initializer 'init(frame:)' class 'pulsatingdotmarker'
ok, guess initwithannotation:reuseidentifier:
internally calls initwithframe:
, it's 1 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 causes compile error when creating annotation view object:
extra argument 'reuseidentifier' in call
hmm, if implement (required) initializer initwithframe:
, loses default initializer initwithannotation:reuseidentifier:
?
maybe if added override of initwithannotation:reuseidentifier:
calls super
available again, 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 - compile error:
property 'self.innercircle' not initialized @ super.init call
ok, if had initwithframe:
, initialized subviews in initwithannotation:reuseidentifier:
? (but if 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 telling me:
property 'self.innercircle' not initialized @ super.init call
(this time in initwithframe:
).
so supposed do? can't create subviews both here , 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, works - though i'm assigning constant property twice in same object (!).
does have idea how should done properly?
(note: class included required initwithcoder:
initializer calls fatalerror
first example, object never created storyboard.)
unfortunately mkannotationview
forces implement init(frame: cgrect)
means have initialise instance variables in method well.
this article explains bit more
for variables can initialised passed in values have make variables optional , set them nil in init(frame: cgrect)
.
the reason suspect mkannotationview calling self.initwithframe: rect
in objective-c init method. if subclass overrides initwithframe:(cgrect) rect
called. however, causes problem in swift because if declare custom designated initialiser not inherit initialisers of superclass. therefore have implement init(frame: cgrect)
in subclass.
i have had same problem uitableveiwcontroller
. header looks follow same pattern. i.e 2 faliable designated initialisers.
it makes me sad. can do.