ORStudios ORStudios - 3 months ago 25
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);
break;
case UIRectEdgeBottom:
border.frame = CGRectMake(0, CGRectGetHeight(self.frame) - thickness, CGRectGetWidth(self.frame), thickness);
break;
case UIRectEdgeLeft:
border.frame = CGRectMake(0, 0, thickness, CGRectGetHeight(self.frame));
break;
case UIRectEdgeRight:
border.frame = CGRectMake(CGRectGetWidth(self.frame) - thickness, 0, thickness, CGRectGetHeight(self.frame));
break;
default:
break;
}

border.backgroundColor = color.CGColor;

[self.layer addSublayer:border];

return border;
}

Answer

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.