I'm trying to create a self-sizing UITableView
but don't want to use Auto Layout to layout it's subviews.
Is there any way to do this? I'm setting
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 40
but adjusting self.frame.size.height
in layoutSubviews
doesn't help, the cell remains at 40 height, so I assume I need to return the real height in a different method. For UICollectionViewCells
the method is
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes
but I can't find the equivalent for UITableViewCell
.
Thanks for any pointers.
You can't create a dynamic height tableViewCell without auto-layout , actually when you pass this UITableViewAutomaticDimension
to a tableView's rowHeight it either
1- Return height specified in heightForCellAtRow
if implemented
2- Return correct height from Xib or if you created constraints in code
3- If non-valid it will return 40 (default)
Implement self-sizing UITableViewCell without auto layout, you have to calculate the size yourself and return it inside sizeForRowAtIndexPath:
class Cell: UITableViewCell {
...
func getCellHeight() -> CGFloat {
// calculate height yourself
}
...
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
guard let cell = tableView.cellForRow(at: indexPath) as? Cell else { return defaultHeight }
return cell.getCellHeight
}
Or you can override sizeToFit()
, sizeThatFits(size: CGSize)
to calculate your expected height and call these method when you need.
It's actually doable and it's a very good approach to do so without auto layout (if you want smooth scrolling on your TableView ).
You can achieve this by using sizeThatFits(_ size: CGRect)
method to calculate the size of your cell by considering all the views/paddings inside your cell. Then you will have to let the TableView know about that by using autoDimension rowHight as you also did yourself, but also in func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
method:
UITableView setup:
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = UITableView.automaticDimension
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
Keep in mind, if you have labels with dynamic texts in your cell, you need to set the texts inside the sizeThatFits(_ size: CGRect)
method and calculate the label height from there.
UITableViewCell:
let cellLabel = UILabel()
var labelText: String?
private let padding: CGFloat = 8
override func sizeThatFits(_ size: CGSize) -> CGSize {
guard let text = self.labelText else { return .zero } // You might not need this
let superHeight = super.sizeThatFits(size).height
let verticalPadding = padding * 2
descriptionLabel.text = text
descriptionLabel.font = UIFont.rpx.regular14
let labelHeight = labelHeight.text?.boundingRect(
with: CGSize(width: size.width, height: size.height),
options: .usesLineFragmentOrigin,
context: nil
).size.height ?? size.height
return CGSize(width: size.width, height: superHeight + labelHeight + verticalPadding)
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
let maxLabelWidth:CGFloat = tableView.frame.width
let title = UILabel()
label.numberOfLines = 0
let titleFont = [NSFontAttributeName: UIFont(name: "OpenSans", size: 10.0)! ]
let titleStr = "test Str" // update with your title string from Array
label.attributedText = NSMutableAttributedString(string: titleStr , attributes: titleFont)
let updatedSize:CGSize = title.sizeThatFits(CGSizeMake(maxLabelWidth, CGFloat.max))
let updatedHeight = updatedSize.height
return updatedHeight
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.