2

I use Masonry to create autolayout constraints in code.

This is what I have so far:

top

Using the following code:

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.view setBackgroundColor:[UIColor whiteColor]];

    UIView *container = [[UIView alloc] init];
    [self.view addSubview:container];

    UIView *itemContainer = [[UIView alloc] init];
    [itemContainer setBackgroundColor:[UIColor colorWithWhite:0.9 alpha:1.0]];
    [container addSubview:itemContainer];

    UIImageView *itemImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Test"]];
    [itemContainer addSubview:itemImage];

    UILabel *itemTitle = [[UILabel alloc] init];
    [itemTitle setNumberOfLines:1];
    [itemTitle setText:@"Lorem ipsum dolor sit amet."];
    [itemTitle setFont:[UIFont boldSystemFontOfSize:12]];
    [itemTitle setTextColor:[UIColor blackColor]];
    [itemContainer addSubview:itemTitle];

    UILabel *itemText = [[UILabel alloc] init];
    [itemText setNumberOfLines:2];
    [itemText setText:@"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt"];
    [itemText setTextColor:[UIColor blackColor]];
    [itemText setFont:[UIFont systemFontOfSize:10]];
    [itemContainer addSubview:itemText];

    [container makeConstraints:^(MASConstraintMaker *make) {
        UIView *topLayoutGuide = (id)self.topLayoutGuide;
        make.top.equalTo(topLayoutGuide.bottom);
        make.left.right.bottom.equalTo(self.view).insets(UIEdgeInsetsMake(10, 10, 10, 10));
    }];

    [itemContainer makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.right.equalTo(container);
        make.height.equalTo(@80);
    }];

    [itemImage makeConstraints:^(MASConstraintMaker *make) {
        make.top.bottom.left.equalTo(itemContainer);
        make.width.equalTo(itemImage.height);
    }];

    [itemTitle makeConstraints:^(MASConstraintMaker *make) {
        make.top.right.equalTo(itemContainer);
        make.left.equalTo(itemImage.right).offset(5);
    }];

    [itemText makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.equalTo(itemTitle);
        make.top.equalTo(itemTitle.bottom).offset(5);
    }];
}

Now I want to center the labels vertically, like so:

centered

My approaches so far have failed. Any idea how to achieve this with autolayout / Masonry?

-- EDIT

Using spacer views like chris838 suggested is working. This is the updated code:

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.view setBackgroundColor:[UIColor whiteColor]];

    UIView *container = [[UIView alloc] init];
    [self.view addSubview:container];

    UIView *itemContainer = [[UIView alloc] init];
    [itemContainer setBackgroundColor:[UIColor colorWithWhite:0.9 alpha:1.0]];
    [container addSubview:itemContainer];

    UIImageView *itemImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Test"]];
    [itemContainer addSubview:itemImage];

    UIView *spacer1 = [[UIView alloc] init];
    [itemContainer addSubview:spacer1];

    UIView *spacer2 = [[UIView alloc] init];
    [itemContainer addSubview:spacer2];

    UILabel *itemTitle = [[UILabel alloc] init];
    [itemTitle setNumberOfLines:1];
    [itemTitle setText:@"Lorem ipsum dolor sit amet."];
    [itemTitle setFont:[UIFont boldSystemFontOfSize:12]];
    [itemTitle setTextColor:[UIColor blackColor]];
    [itemContainer addSubview:itemTitle];

    UILabel *itemText = [[UILabel alloc] init];
    [itemText setNumberOfLines:2];
    [itemText setText:@"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt"];
    [itemText setTextColor:[UIColor blackColor]];
    [itemText setFont:[UIFont systemFontOfSize:10]];
    [itemContainer addSubview:itemText];

    [container makeConstraints:^(MASConstraintMaker *make) {
        UIView *topLayoutGuide = (id)self.topLayoutGuide;
        make.top.equalTo(topLayoutGuide.bottom);
        make.left.right.bottom.equalTo(self.view).insets(UIEdgeInsetsMake(10, 10, 10, 10));
    }];

    [itemContainer makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.right.equalTo(container);
        make.height.equalTo(@80);
    }];

    [itemImage makeConstraints:^(MASConstraintMaker *make) {
        make.top.bottom.left.equalTo(itemContainer);
        make.width.equalTo(itemImage.height);
    }];

    [spacer1 makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(itemContainer.top);
        make.height.equalTo(spacer2);
    }];

    [itemTitle makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(spacer1.bottom);
        make.right.equalTo(itemContainer);
        make.left.equalTo(itemImage.right).offset(5);
    }];

    [itemText makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.equalTo(itemTitle);
        make.top.equalTo(itemTitle.bottom).offset(5);
        make.bottom.equalTo(spacer2.top);
    }];

    [spacer2 makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(itemContainer.bottom);
        make.height.equalTo(spacer1);
    }];
}
Midhun MP
  • 103,496
  • 31
  • 153
  • 200
Jaap van Hengstum
  • 4,494
  • 4
  • 30
  • 34

1 Answers1

9

Often when using auto-layout, I find I have to add additional 'spacer' views to achieve the layout I want. See the red coloured views in the example below:

Example of adding spacer views to centre content

Once you have the layout you want, you can set the views to hidden. Typically the constraints you would need for your spacer view (in this case) would be:

  • Top and bottom space to the adjacent view (or superview) set to zero.
  • Equal heights.
  • Fixed width.
  • Centred horizontally in container.

The equal heights bit is obviously the key to getting the content centred!

chris838
  • 5,148
  • 6
  • 23
  • 27
  • I have it working now with spacer views. I wasn't sure that was the recommended approach but then I saw the Apple documentation doing the same thing. – Jaap van Hengstum Nov 05 '14 at 13:14