Search code examples
iosobjective-ciphoneuitableviewipad

UITableViewCell subviews are not honoring the Autolayout constraints


I'm drawing a fairly simple custom UITableViewCell--thumbnail on the left, name and link labels on the right. I want my name and link labels to be one-liners, truncating at the tail if texts exceed the cell's width. I am pretty sure that I am adding my constraints correctly, yet my name and link labels won't honor them.

This is what the cells look like on an iPhone 4S running iOS 8:

enter image description here

In my code, I am adding a 10-point trailing constraint for the name and link labels to the superview (the cell's contentView) and yet, notice that even at landscape, iOS doesn't seem to honor the constraints.

Can someone show me what I'm doing wrong? This is my code for the whole cell. I am creating the views programatically and I have the Autolayout constraints in the table view cell's initializer.

#import "PopularWikiCell.h"

// Models
#import "Wiki.h"

// Pods
#import "UIImageView+AFNetworking.h"

// Constants
static const CGFloat kPadding = 10;
static const CGFloat kImageSize = 100;
const CGFloat kPopularWikiCellHeight = kImageSize + kPadding * 2;

@interface PopularWikiCell ()

@property (nonatomic, strong) UIImageView *thumbnailView;
@property (nonatomic, strong) UILabel *nameLabel;
@property (nonatomic, strong) UILabel *linkLabel;

@end

@implementation PopularWikiCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        // Initialise the subviews.
        _thumbnailView = [[UIImageView alloc] init];
        _thumbnailView.contentMode = UIViewContentModeScaleAspectFill;
        _thumbnailView.clipsToBounds = YES;

        _nameLabel = [[UILabel alloc] init];
        _nameLabel.backgroundColor = [UIColor blueColor];
        _nameLabel.numberOfLines = 1;
        _nameLabel.lineBreakMode = NSLineBreakByTruncatingTail;
        _nameLabel.text = @"Name";

        _linkLabel = [[UILabel alloc] init];
        _linkLabel.backgroundColor = [UIColor redColor];
        _linkLabel.text = @"Link";
        _linkLabel.numberOfLines = 1;
        _linkLabel.lineBreakMode = NSLineBreakByTruncatingTail;

        // Add the subviews.
        [self.contentView addSubview:_thumbnailView];
        [self.contentView addSubview:_nameLabel];
        [self.contentView addSubview:_linkLabel];

        _thumbnailView.translatesAutoresizingMaskIntoConstraints = NO;
        _nameLabel.translatesAutoresizingMaskIntoConstraints = NO;
        _linkLabel.translatesAutoresizingMaskIntoConstraints = NO;
        self.contentView.translatesAutoresizingMaskIntoConstraints = NO;

        // Add the layout constraints.

        NSDictionary *metrics = @{@"kPadding" : @(kPadding),
                                  @"kImageSize" : @(kImageSize)};
        NSDictionary *views = @{@"thumbnailView" : _thumbnailView,
                                @"nameLabel" : _nameLabel,
                                @"linkLabel" : _linkLabel};

        NSArray *constraints = @[@"H:|-kPadding-[thumbnailView(kImageSize)]-kPadding-[nameLabel]-kPadding-|",
                                 @"H:[thumbnailView]-kPadding-[linkLabel]-kPadding-|",
                                 @"V:|-kPadding-[nameLabel]-0-[linkLabel]",
                                 @"V:|-kPadding-[thumbnailView(kImageSize)]"];

        [self.contentView addConstraintsFromVisualFormatStrings:constraints
                                                        options:0
                                                        metrics:metrics
                                                          views:views];
    }
    return self;
}

- (void)setWiki:(Wiki *)wiki
{
    _wiki = wiki;

    self.thumbnailView.image = nil;
    self.thumbnailView.backgroundColor = [UIColor darkGrayColor];
    __weak typeof(self) weakSelf = self;
    [self.thumbnailView setImageWithURLRequest:[NSURLRequest requestWithURL:wiki.thumbnailURL]
                              placeholderImage:nil
                                       success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
                                           __strong typeof(self) strongSelf = weakSelf;
                                           strongSelf.thumbnailView.image = image;
                                           strongSelf.thumbnailView.backgroundColor = [UIColor whiteColor];
                                       }
                                       failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {

                                       }];

    self.nameLabel.text = wiki.name;
    self.linkLabel.text = wiki.URL;

    [self.contentView setNeedsLayout];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    // Selection removes all background colors so re-set it.
    [self resetSubviewBackgroundColors];

    [self.contentView setNeedsLayout];
}

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
    [super setHighlighted:highlighted animated:animated];

    // Highlighing removes all background colors so re-set it.
    [self resetSubviewBackgroundColors];

    [self.contentView setNeedsLayout];
}

- (void)resetSubviewBackgroundColors
{
    if (self.thumbnailView.image) {
        self.thumbnailView.backgroundColor = [UIColor whiteColor];
    } else {
        self.thumbnailView.backgroundColor = [UIColor darkGrayColor];
    }
}

@end

Solution

  • The problem is hidden in

    self.contentView.translatesAutoresizingMaskIntoConstraints = NO;
    

    removing this code fixes your issue.

    if you don't want traslate Autoresizing Mask Into Constraints - set yours desirable constraints for cell.contentView.