swift UITableView set rowHeight

XcodeSwiftUitableview

Xcode Problem Overview


I am trying to set the height of each row in the tableView to the height of the corresponding cell with this code:

override func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
      var cell = tableView.cellForRowAtIndexPath(indexPath)
      return cell.frame.height
}

I get this error when initialising var cell : >Thread 1:EXC_BAD_ACCESS(code=2,address=0x306d2c)

Xcode Solutions


Solution 1 - Xcode

For setting row height there is separate method:

For Swift 3

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 100.0;//Choose your custom row height
}

Older Swift uses

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return 100.0;//Choose your custom row height
}

Otherwise you can set row height using:

self.tableView.rowHeight = 44.0

In ViewDidLoad.

Solution 2 - Xcode

Put the default rowHeight in viewDidLoad or awakeFromNib. As pointed out by Martin R., you cannot call cellForRowAtIndexPath from heightForRowAtIndexPath

self.tableView.rowHeight = 44.0

Solution 3 - Xcode

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        var height:CGFloat = CGFloat()
        if indexPath.row == 1 {
            height = 150
        }
        else {
            height = 50
        }
        return height
    }

Solution 4 - Xcode

yourTableView.rowHeight = UITableViewAutomaticDimension

Try this.

Solution 5 - Xcode

As pointed out in comments, you cannot call cellForRowAtIndexPath inside heightForRowAtIndexPath.

What you can do is creating a template cell used to populate with your data and then compute its height. This cell doesn't participate to the table rendering, and it can be reused to calculate the height of each table cell.

Briefly, it consists of configuring the template cell with the data you want to display, make it resize accordingly to the content, and then read its height.

I have taken this code from a project I am working on - unfortunately it's in Objective C, I don't think you will have problems translating to swift

- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    static PostCommentCell *sizingCell = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    	sizingCell = [self.tblComments dequeueReusableCellWithIdentifier:POST_COMMENT_CELL_IDENTIFIER];
    });
    
    sizingCell.comment = self.comments[indexPath.row];
    [sizingCell setNeedsLayout];
    [sizingCell layoutIfNeeded];
    
    CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    return size.height;
}

Solution 6 - Xcode

Problem Cause:
The problem is that the cell has not been created yet. TableView first calculates the height for row and then populates the data for each row, so the rows array has not been created when heightForRow method gets called. So your app is trying to access a memory location which it does not have the permission to and therefor you get the EXC_BAD_ACCESS message.

How to achieve self sizing TableViewCell in UITableView:
Just set proper constraints for your views contained in TableViewCell's view in StoryBoard. Remember you shouldn't set height constraints to TableViewCell's root view, its height should be properly computable by the height of its subviews -- This is like what you do to set proper constraints for UIScrollView. This way your cells will get different heights according to their subviews. No additional action needed

Solution 7 - Xcode

Make sure Your TableView Delegate are working as well. if not then in your story board or in .xib press and hold Control + right click on tableView drag and Drop to your Current ViewController. swift 2.0

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return 60.0;
}

Solution 8 - Xcode

There is no way to call tableView.dequeueReusableCell from within tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath).

So you have to compute the height from the data. In my case that was not possible because I have a textView in the cell, which size I did not know.

So I come around with the following strategies:

  1. Do not use tableView.dequeueReusableCell. Just use an array of cells yo have under full control. If your cell is not too large in memory and you don't have too much rows, this is the simplest strategy.

  2. Use a dummy cell, configure it with your data and compute the size.

Solution 9 - Xcode

Try code like this copy and paste in the class

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 100
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questiontim_yngView Question on Stackoverflow
Solution 1 - XcodeNagarjunView Answer on Stackoverflow
Solution 2 - XcodeMundiView Answer on Stackoverflow
Solution 3 - XcodeVishal VaghasiyaView Answer on Stackoverflow
Solution 4 - XcodePrabhavView Answer on Stackoverflow
Solution 5 - XcodeAntonioView Answer on Stackoverflow
Solution 6 - XcodeMehdi IjadnazarView Answer on Stackoverflow
Solution 7 - XcodeAmeer ChandView Answer on Stackoverflow
Solution 8 - XcodeStephan JanuarView Answer on Stackoverflow
Solution 9 - XcodeTalha ShafaqatView Answer on Stackoverflow