UITableViewCell with intrinsic height based on width
Got it! It seems that height of autodimensioned UITableViewCell is determined from UITableView by calling systemLayoutSizeFitting()
of the cell . In my cell class, I have overriden the method, and call layoutIfNeeded() before calling super.systemLayoutSizeFitting() - in order to have correct dimensions. And that works! Maybe I even could call the ExpressionView arranging method directly, not through layoutIfNeeded(), but I will leave it as it is.
This is the override in my cell class:
override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize {
//force layout of all subviews including ExpressionView, which
//updates ExpressionView's intrinsic height, and thus height of a cell
self.setNeedsLayout()
self.layoutIfNeeded()
//now intrinsic height is correct, so I can call super method
return super.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: horizontalFittingPriority, verticalFittingPriority: verticalFittingPriority)
}
How to create an UITableView with an intrinsic Height in Swift 5 using UIKit?
You can use something along the lines of:
final class AutoSizingTableView: UITableView {
override init(frame: CGRect, style: UITableView.Style) {
super.init(frame: frame, style: style)
setContentCompressionResistancePriority(.required, for: .vertical)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setContentCompressionResistancePriority(.required, for: .vertical)
}
override var contentSize: CGSize {
didSet {
invalidateIntrinsicContentSize()
}
}
override func reloadData() {
super.reloadData()
invalidateIntrinsicContentSize()
}
override var intrinsicContentSize: CGSize {
setNeedsLayout()
layoutIfNeeded()
return contentSize
}
}
Basically what this does is set an intrinsicContentSize equal to the contentSize when the data of the tableview is reloaded, or if the contentSize changes.
However you have to ask yourself the question: If I don't need dequeuing logic, do I actually need a tableview?
Can you get a UITableView's intrinsic content size to update based on the number of rows shown if scrolling is disabled?
Ok, so unlike UITextView
, it doesn't look like UITableView
ever returns an intrinsic size based on the visible rows. But that's not that big a deal to implement via a subclass, especially if there's a single section, no headers or footers, and the rows are of a fixed height.
class AutoSizingUiTableView : UITableView
{
override func intrinsicContentSize() -> CGSize
{
let requiredHeight = rowCount * rowHeight
return CGSize(width: UIView.noIntrinsicMetric, height: CGFloat(requiredHeight))
}
}
I'll leave it up to the reader to figure out how to get their own rowCount
. The same if you have variable heights, multiple sections, etc. You just need more logic.
By doing this, it works great with AutoLayout. I just wish it handled this automatically.
How can I adjust the UITableViewCell height to the content of UITextView that's inside?
The key to getting self-sizing table cells (autolayout-based, which I recommend) is as follows:
- Add your subviews to the
contentView
of theUITableViewCell
- Provide constraints between your subviews and the
contentView
such that your subviews reach all edges of the table cell. In your case, this probably means aligning theleading
,trailing
,top
, andbottom
edges of yourUITextView
to the corresponding edges of thecontentView
. - Set the row height to
UITableViewAutomaticDimension
instead of a hardcodedCGFloat
. - Somewhere in your controller, provide an estimation of the height with
tableView.estimatedRowHeight = x
(a hard coded constant is fine, this is for performance).
Related Topics
Find Delegate in a Swift Array of Delegates
Swift 2 - Separating an Array into a Dictionary with Keys from a to Z
Swift - Nsdate and Last Week of Year
Binary Operator + Cannot Be Applied to Operands of Type Cgfloat Int
Mysterious "Cryptographic Verification Failure" Error on MACos Sierra, Xcode 8
Square Video Using Avfoundation
How to Update a Swiftui View State from Outside (Uiviewcontroller for Example)
How to Convert Bytes to Half-Floats in Swift
How to Change Uitextfield Color in Searchcontroller
Subview Gesture Recognizer Not Being Called
Crashing While Collection View Cell Deletion Because of "Uicollectionviewlayoutattributes"
Save Video to a Custom Album Using Photos Framework in iOS
Uiimageview .Scaleaspectfit and Autolayout Not Working Programmatically from Swift
Programmatically Auto-Connect to Wifi iOS
How to Turn Off Core Data Write-Ahead Logging in Swift Using Options Dictionary
Uitabbar Transition Issue Below iOS 11 Swift
Get "No Keychain Available" Error When Try to Access Keychain from App Extension