5

I have something like this in a UIView subclass:

override var bounds : CGRect {
  didSet {
    somelayer.frame = bounds
  }
}

In the corresponding somelayer, I have this:

override var bounds: CGRect {
  didSet {
    someFunction()
  }
}

Now if the view is initialized using super.init(frame: someFrame), the first block is not called. This appears to indicate that the bounds property is not set alongside frame.

If I change the first block to override var frame, then it will be called by super.init(frame: someFrame), and it will set the frame of somelayer. Interestingly, when that happens, the second block is called, suggesting that bounds and frame are set at the same time (which is what I'd expect, too).

Am I missing anything here?

danqing
  • 3,348
  • 2
  • 27
  • 43

1 Answers1

6

Property Observers are not called during initialization.

willSet and didSet observers are not called when a property is first initialized. They are only called when the property’s value is set outside of an initialization context.

Perhaps the way the view is being constructed internally, the frame is set post initialization but the bounds are not.

Then later, when setting the frame of the layer, the bounds are also updated by the internal method.

drewag
  • 93,393
  • 28
  • 139
  • 128
  • 1
    Thanks! I should have RTFM more carefully. – danqing Jun 12 '14 at 04:51
  • Using Swift 2 / iOS9 I am seeing willSet / didSet get called in an initialization context, in my case when subclassing UIView I'm seeing them get called from inside super.init(coder: aDecoder) in init?(coder aDecoder: NSCoder). Actually I'm having the opposite problem where the observer on the `frame` property doesn't seem to be called **after** initialisation even though the value changes. – sleep Oct 12 '15 at 01:49
  • @JarrodSmith I'm facing the same - did you find a solution for this? – swalkner Aug 19 '16 at 13:37
  • @swalkner no I ended up having to use a different approach. – sleep Nov 04 '16 at 05:00