ORStudios ORStudios -4 years ago 160
iOS Question

initWithCoder Not Taking Into Account Autolayout

Im using the following code to subclass a UIView and add some borders to it. The problem is that it doesn't take into account the autolayout constraints. I'd like it so that autolayout is taken into account and then the UIView has a border drawn on it. Any help would be great thanks.

- (instancetype)initWithCoder:(NSCoder *)coder
self = [super initWithCoder:coder];
if (self) {
[self setupView];
return self;

- (void)setupView {

[self prefix_addUpperBorder:UIRectEdgeTop color:[UIColor flatWhiteColorDark] thickness:0.5];


- (CALayer *)prefix_addUpperBorder:(UIRectEdge)edge color:(UIColor *)color thickness:(CGFloat)thickness
CALayer *border = [CALayer layer];

switch (edge) {
case UIRectEdgeTop:
border.frame = CGRectMake(0, 0, CGRectGetWidth(self.frame), thickness);
case UIRectEdgeBottom:
border.frame = CGRectMake(0, CGRectGetHeight(self.frame) - thickness, CGRectGetWidth(self.frame), thickness);
case UIRectEdgeLeft:
border.frame = CGRectMake(0, 0, thickness, CGRectGetHeight(self.frame));
case UIRectEdgeRight:
border.frame = CGRectMake(CGRectGetWidth(self.frame) - thickness, 0, thickness, CGRectGetHeight(self.frame));

border.backgroundColor = color.CGColor;

[self.layer addSublayer:border];

return border;

Answer Source

Your view object's init methods fire before the view is installed in the view hierarchy. That is not the place to do math on the view's layout.

If you override the view's layoutSubviews method you can put code there that updates your view. Note that you should add your layer's sublayer in init (and save it to a property so you can find it later.) Then in layoutSubviews you'd call [super layoutSubviews] and then adjust your custom layer as needed.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download