vulgur
vulgur

Reputation: 61

Where should I put AutoLayout code?

I'm using PureLayout to implement AutoLayout of subviews in a UIView. But I don't know the best practice of organizing the code.

Should I put the AutoLayout related code in the init of the UIView, or the overridden methods such as updateConstraints and layoutSubviews?

Upvotes: 2

Views: 426

Answers (3)

Mert Buran
Mert Buran

Reputation: 3017

You should add constraints when you are sure that view has been added to its superview. Basically, you should do it in superview's class any point after addSubview: is called.

To answer your questions:

1- in init methods, can you be sure of that view has been added as subview to a superview? it wouldn't be safe to assume that. maybe you can add constraints in init method of superview

2- layoutSubviews is in where autolayout code actually works. you can't add constraints in layoutSubviews. already playing with autolayout constraints are not cheap, therefore you should add/remove them as few as possible, doing so in a method that is called multiple times (i.e. layoutSubviews) is not the best practice.

Mechanism of autolayout is going to inner view from outer view, so subviews do not actually concern about constraints. it is superview's responsibility

Upvotes: 1

PhilCai
PhilCai

Reputation: 115

For example, I want to create a subclass of UIView called PHView, and for any phview, there is a subview called centerView, it is always at the center of phview, and width/height is 0.3*phview's width/height. https://www.dropbox.com/s/jaljggnymxliu1e/IMG_3178.jpg

 #import "PHView.h"
 #import "Masonry.h"
@interface PHView()
@property (nonatomic, assign) BOOL didUpdateConstraints;
@property (nonatomic, strong) UIView *centerView;
@end
@implementation PHView
- (instancetype)init {
    self = [super init];
    if (self) {
        self.backgroundColor = [UIColor redColor];
        self.translatesAutoresizingMaskIntoConstraints = NO;
    }
    return self;
}
 - (UIView *)centerView {
    if (!_centerView) {
        _centerView = [UIView new];
        _centerView.backgroundColor = [UIColor yellowColor];
        [self addSubview:_centerView];
    }
    return _centerView;
}

 -(void)updateConstraints {
    if (!_didUpdateConstraints) {
        _didUpdateConstraints = YES;
        [self.centerView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.centerX.equalTo(self.mas_centerX);
            make.centerY.equalTo(self.mas_centerY);
            make.width.equalTo(self.mas_width).multipliedBy(0.3);
            make.height.equalTo(self.mas_height).multipliedBy(0.3);
        }];
    }
    [super updateConstraints];
}
@end

'didUpdateConstraints' aims to indicate you have added constraints, so you will only add constraints once.

in UIViewController:make phview top bottom left right 20 to the margin.

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor greenColor];
    PHView *myView = [PHView new];
    [self.view addSubview:myView];
    [myView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(20, 20, 20, 20));
    }];

}

Upvotes: 1

soumya
soumya

Reputation: 3811

Hope this helps you by understanding controller’s view hierarchy How View Controllers Participate in the View Layout Process

  1. The view controller’s view is resized to the new size.
  2. If autolayout is not in use, the views are resized according to their autoresizing masks.
  3. The view controller’s viewWillLayoutSubviews method is called.
  4. The view’s layoutSubviews method is called. If autolayout is used to configure the view hierarchy, it updates the layout constraints by executing the following steps:

    a.The view controller’s updateViewConstraints method is called.

    b.The UIViewController class’s implementation of the updateViewConstraints method calls the view’s updateConstraints method.

    c. After the layout constraints are updated, a new layout is calculated and the views are repositioned.

  5. The view controller’s viewDidLayoutSubviews method is called.

Please refer this for more details

Upvotes: 0

Related Questions