nburk
nburk

Reputation: 22731

Get property from NSCoder in required init(coder aDecoder: NSCoder)

I am implementing a Circle class (subclass of UIView) in Swift that sets its radius in its initializer according to the frame that is passed in init(frame: CGRect) like so:

override init(frame: CGRect)
{
    radius = frame.width/2.0
    super.init(frame: frame)
}

I also want to ensure for the case when the circle is instantiated from Interface Builder, so I also implement 'required init(coder aDecoder: NSCoder)` (which I am forced to do by Xcode anyway).

How can I retrieve the frame property of the view that is somehow contained in aDecoder. What I want to achieve basically would look like this:

required init(coder aDecoder: NSCoder)
{
   var theFrame = aDecoder.someHowRetrieveTheFramePropertyOfTheView // how can I achieve this?
   radius = theFrame.width/2.0
   super.init(coder: aDecoder)
}

Upvotes: 1

Views: 4089

Answers (2)

Duncan C
Duncan C

Reputation: 131426

Martin's answer is the correct one. (Voted). You might be able to find the way that the base class encodes the frame value and extract it, but that is fragile. (It relies on private details of the implementation of the base class, which might change and break your app in the future.) Don't develop code that depends on non-public implementation details of another class, or of your base class. That's a future bug just waiting to happen.

The pattern in initWithCoder is to first call super to get the values for the ancestor class, then extract the values for your custom class.

When you do it that way, the ancestor class will have already set up your view's frame for you, and you can just use that.

Upvotes: 3

Martin R
Martin R

Reputation: 539815

You could compute the radius after the frame has been set by super.init():

required init(coder aDecoder: NSCoder)
{
    radius = 0 // Must be initialized before calling super.init()
    super.init(coder: aDecoder)
    radius = frame.width/2.0
}

Upvotes: 8

Related Questions