mparrish91
mparrish91

Reputation: 101

tableview dynamic height rows according to content height

My tableview rows are not stretching to fit the imageviews and the imageviews are overlapping. enter image description here

I set the tableview in automatic dimension and constrain the bottom of the imageview to the cell

There must be something missing, but I could not figure out what.

tableviewcell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{   
    self.photoImageView = [[UIImageView alloc]init];
    if (!(self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]))
        return nil;

    [self.contentView addSubview:self.photoImageView];

    [self setConstraints];

    return self;
}

-(void) layoutSubviews {
    [super layoutSubviews];

    self.nameLabel.preferredMaxLayoutWidth = self.nameLabel.frame.size.width;

    [self setConstraints];

}

- (void) setConstraints {

    UILayoutGuide *margins = self.contentView.layoutMarginsGuide;

    self.photoImageView.translatesAutoresizingMaskIntoConstraints = false;
    [self.photoImageView.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:7].active = YES;
    [self.photoImageView.bottomAnchor constraintGreaterThanOrEqualToAnchor:self.contentView.bottomAnchor constant:12].active = YES;
    [self.photoImageView.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:8].active = YES;
    [self.photoImageView.heightAnchor constraintEqualToConstant:65].active = YES;
    [self.photoImageView.widthAnchor constraintEqualToConstant:65].active = YES;
    self.photoImageView.contentMode = UIViewContentModeScaleAspectFit;
    self.photoImageView.layer.cornerRadius = self.photoImageView.frame.size.height / 3;
    self.photoImageView.layer.masksToBounds = YES;

}

tableviewcontroller

- (void)viewDidLoad {
    [super viewDidLoad];


    //tableview
    NSString *cellIdentifier = @"cell";
    [self.businessesTableView registerClass:[YPBusinessTableViewCell class] forCellReuseIdentifier:cellIdentifier];
    self.businessesTableView.delegate = self;
    self.businessesTableView.dataSource = self;
    self.refreshControl = [[UIRefreshControl alloc]init];
    [self.businessesTableView addSubview:self.refreshControl];
    [self.refreshControl addTarget:self action:@selector(refreshTable) forControlEvents:UIControlEventValueChanged];

    UIEdgeInsets insets = self.businessesTableView.contentInset;
    insets.bottom += YPInfiniteScrollActivityView.defaultHeight;
    self.businessesTableView.contentInset = insets;

    self.businessesTableView.estimatedRowHeight = 120;
    self.businessesTableView.rowHeight = UITableViewAutomaticDimension;

    UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];

    UIBarButtonItem *filter = [[UIBarButtonItem alloc] initWithTitle:@"Filter" style:UIBarButtonItemStylePlain target:self action:@selector(presentFilterView)];
    negativeSpacer.width = -14;

    [self.navigationItem setLeftBarButtonItems:@[negativeSpacer, filter] animated:NO];


    [self setConstraints];
    [self doSearch:@"test"];

    [self setupInfiniteScrollView];
    [self addSearchBar];
    [self hideErrorView:self.errorView];


}

EDIT:

I figured out my problem was changing this line

[self.contentView.bottomAnchor  constraintGreaterThanOrEqualToAnchor:self.photoImageView.bottomAnchor constant:0].active = YES;

I needed to constrain the bottom anchor of the contentView to the imageView and not the other way around.

Only issue now is my tableview loads initially with very small cells then when i refresh the images become biggerenter image description here

enter image description here

Upvotes: 1

Views: 132

Answers (4)

mparrish91
mparrish91

Reputation: 101

My problems were completely related to autolayout.

I first needed to constrain the bottom of the cell to the imageviews bottom and not the other way around.

[self.contentView.bottomAnchor  constraintGreaterThanOrEqualToAnchor:self.photoImageView.bottomAnchor constant:0].active = YES;

After that I was having issues with the startup size of the imageview and the size after reloading the table.

I then set fixed width and height on the imageview and that solved all other sizing/reloading issues.

[self.photoImageView.heightAnchor constraintEqualToConstant:65].active = YES;
[self.photoImageView.widthAnchor constraintEqualToConstant:65].active = YES;

Upvotes: 0

iOS Geek
iOS Geek

Reputation: 4855

Just set tableview properties in viewdidload() method

**

tableView.estimatedRowHeight = 2000;  // example
tableView.rowHeight = UITableViewAutomaticDimension;

**

set tableview delegate as

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:
(NSIndexPath *)indexPath{
return UITableViewAutomaticDimension;
}

Also set the elements in UITableView cell with constraints attached from top to bottom

Please refer to this link for more info - https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithSelf-SizingTableViewCells.html

Upvotes: 1

Dan
Dan

Reputation: 31

This line in setConstraints looks suspicious to me:

    [self.photoImageView.heightAnchor constraintEqualToConstant:65].active = YES;

If you are using self-sizing table view cells, you probably don't want a constant height.

This is a pretty good tutorial on self-sizing table view cells, which may be helpful: https://www.raywenderlich.com/129059/self-sizing-table-view-cells

Upvotes: 0

keverly
keverly

Reputation: 1430

In you're tableview delegate (tableviewcontroller), you can implement a function called heightForrowAtIndexPath

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

Assuming you have an Array with all the images, return the corresponding height of the image in at that index.

Upvotes: 0

Related Questions