user9898
user9898

Reputation: 25

iOS masonry on tableView cells

I'm using Masonry on table view cells, right now I have a UITableViewCell which is a container of views, something like this:

*Table View(cellForRowAtIndexPath):

MasonryTestTableViewCell *masonryCell = [tableView dequeueReusableCellWithIdentifier:@"masonryCell"];

if (masonryCell == nil) {
    masonryCell = [[MasonryTestTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"masonryCell"];
}
[masonryCell addSubview:[self createViewForCell]];

return masonryCell;

*createViewForCell method(which also uses masonry):

-(UIView *) createViewForCell{
    self.textLabel = [[UILabel alloc]init];
    [self.textLabel setLineBreakMode:NSLineBreakByWordWrapping];
    [self.textLabel setTextAlignment:NSTextAlignmentLeft];
    [self.textLabel setNumberOfLines:0];
    [self.textLabel setText:@"TEST TEXT"];
    [self.textLabel setPreferredMaxLayoutWidth:[UIScreen mainScreen].bounds.size.width];
    [self addSubview:self.textLabel];

    [self.textLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.mas_left).with.offset(10);
        make.bottom.equalTo(self.mas_bottom).with.offset(-10);
        make.right.equalTo(self.mas_right).with.offset(-10);
        make.top.equalTo(self.mas_top).with.offset(10);
    }];

    self.textLabel.layer.borderColor = [UIColor grayColor].CGColor;
    self.textLabel.layer.borderWidth = 3;
}

*@implementation MasonryTestTableViewCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
    return [super initWithStyle:style reuseIdentifier:reuseIdentifier];
}

- (void) setContent:(UIView *)view{
    [self setBackgroundColor:[UIColor greenColor]];
    [self addSubview:view];

    [view mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(self.mas_top).with.offset(kYPosition);
            make.bottom.equalTo(self.mas_bottom).with.offset(-kYPosition);
            make.left.equalTo(self.mas_left).with.offset(kCellPadding);
            make.right.equalTo(self.mas_right).with.offset(-kCellPadding);
     }];
}

The issue that I'm facing right now is that the cell doesn't risize properly, it get to a point that, if I set a long text on the textLabel, it doesn't increase the cell height, I can't fix this, do you know if there is something else that ai should do to get this working?

Upvotes: 0

Views: 997

Answers (2)

childrenOurFuture
childrenOurFuture

Reputation: 1987

Doro shows a way to solve your problem, but I think how to deal with your problem depends on the way you choose t make the cell height dynamically.
If your use autoLayout and UITableViewAutomaticDimension, so you don't have to calculate the height by code, just make the internal subview stretch the cell's height.
In this situation, I found bug in your code, you have to let cell.contentView to addSubview instead cell itself.
I hope it works, good luck!

Upvotes: 0

Doro
Doro

Reputation: 2413

Masonry is only a wrapper framework on NSAutolayoutConstraint functionality. In order to properly resize cell you should provide height information to your tableView via

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  return [self heightForBasicCellAtIndexPath:indexPath];
}

The method heightForBasicCellAtIndexPath: could look like

- (CGFloat)heightForBasicCellAtIndexPath:(NSIndexPath *)indexPath {
  static UITableViewCell *sizingCell = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sizingCell = [self.tableView dequeueReusableCellWithIdentifier:@"your_Cell_identifier"];
  });

  [self configureBasicCell:sizingCell atIndexPath:indexPath];
  return [self calculateHeightForConfiguredSizingCell:sizingCell];
}

- (CGFloat)calculateHeightForConfiguredSizingCell:(UITableViewCell *)sizingCell {
  [sizingCell setNeedsLayout];
  [sizingCell layoutIfNeeded];

  CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
  return size.height + 1.0f; // Add 1.0f for the cell separator height
}

And the last thing to do - define configureBasicCell: atIndexPath: In your case it may look like:

- (void)configureBasicCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
 [cell addSubview:[self createViewForCell]];
}

For more information - see this

Hope this helps

Upvotes: 0

Related Questions