Q:

UITableView crash after i implemented `estimatedHeightForRowAt indexPath`?

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    let cellHeight = self.promotionListViewList[indexPath.row].tableViewHeight.value
    if cellHeight < 0 {
        return 1.0
    } else {
        return cellHeight
    } 
}

When I uncomment this method and run my project on iPhone5 or iPad2, I got this exception:

'table view row height must not be negative - provided height for index path' 

and the app crashes.
But why?
I didn't produce a negative value in this method.
If I comment it nothing happens.

A:

If you are using autolayout according to this stackoverflow answer  https://stackoverflow.com/questions/18397206/autolayout-error-with-uitableview:

Estimating row height of 1.0 results in an exception: "NSInternalInconsistencyException', reason: 'table view row height must not be negative...'"

Estimating less than 1.0 has strange results as well.

Estimating between 2.0 and the actual works just fine without any exceptions (although 2.0 is probably a bad choice for optimization reasons - you want to be as close to actual as possible).

The constraint exception only occurs when the estimated row height is greater than the actual row height. The closer you are to the actual, the less likely the exception will occur. How far off your estimate can be before getting the exception seems to be related to several different factors: actual row height, the position of the row, etc.

This solution should avoid the exception:
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    let cellHeight = self.promotionListViewList[indexPath.row].tableViewHeight.value
    if cellHeight < 0 {
        return 1.01
    } else {
        return cellHeight
    } 
}

