Inferring row height in heightForRowAtIndexPath - ios

What I would like to do:
In the UITableViewController method heightForRowAtIndexPath I would like to infer the value of the row height rather than hardcoding it.
I set the value previously in the storyboard in Interface builder.
Wrong approach:
The following method is the wrong approach as it is called before the actual cell is created and hence it loops:
// wrong approach
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//AppTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"AppCel" forIndexPath:indexPath];
//int height = cell.frame.size.height;
// TODO: Make it more dynamic
return 112;
}
Approach I am thinking of:
Is there a way to load the cell main.storyboard document and infer the height value? Or is there some other approach?
Related questions search:
I found the following unanswered related question dating back to 2010. This other question is not of much use as it derives the height from the cell content rather than from the story board document.

The approach you had coded is actually not totally wrong. What is wrong is using dequeueReusableCellWithIdentifier:forIndexPath. Instead you want to use the simpler version dequeueReusableCellWithIdentifier which you can use to provide a prototype cell which you can configure, layout and then calculate the height.
If using purely iOS8, all this is done for you with the new auto layout. If you want to support iOS7 as well, then you need to do this manually.
The following link explains the process you need to use. I use this and it works great when you want to support both iOS7 and iOS8.
Using Auto Layout in UITableView for dynamic cell layouts & variable row heights
You also have to watch if you use size class based constraints in your cells as there is a less than obvious issue you have to work around to get the height correct. See Offscreen UITableViewCells (for size calculations) not respecting size class?

Yes you can.
You can use autolayout constraints and let the autolayout do the calculations for you.
check out AppCoda tutorial for this Link

If you have the cell in a xib (CP_Cell.xib) you can do that:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return ((CP_Cell *) [[NSBundle mainBundle] loadNibNamed:#"CP_Cell" owner:self options:nil].lastObject).frame.size.height;
}

Related

iOS11 UITableview reloadRowsAtIndexPaths glitch

Can anyone help me understand or solve this UITableView glitch in iOS11. I have managed to reproduce my issue in a fairly simple test case.
https://github.com/trapper-/iOS11-tableview-glitch
When reloading cells near the bottom of a tableview the reloaded cell will start to scroll weirdly and other cells start to move and hop around.
It gets much worse when reloading multiple cells, but I didn't want to complicate this simple example.
Edit: This issue only occurs in iOS11, works fine in iOS10 & iOS12. So
you need to download the iOS11 simulator to test this in Xcode 10
This should help:
[UIView performWithoutAnimation:^{
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}];
If I use like this, its working.
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 100;
}
Try providing estimatedRowHeight to 0 to table view on viewDidLoad. It works for me.
Please try setting you're table view estimatedRowHeight (in the viewDidLoad method):
self.tableView.estimatedRowHeight = 100;
The tableView.rowHeight is set to UITableViewAutomaticDimension by default but you need to set the estimatedRowHeight
From apple - "To enable self-sizing table view cells, you must set the table view’s rowHeight property to UITableViewAutomaticDimension. You must also assign a value to the estimatedRowHeight property. As soon as both of these properties are set, the system uses Auto Layout to calculate the row’s actual height."
You can check out:
https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithSelf-SizingTableViewCells.html

UITableViewCell size does not follow Content View size

I have two UITableViewControllers which use the same set of cell templates, therefore I have created a table view controller in my Storyboard which contains these templates. My table view controllers instantiate an instance of this template holder tableview, then in -tableView:cellForRowAtIndexPath: they deque one of it's cells, and configure it as they need.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *widgetDict = [self.widgets objectAtIndex:indexPath.row];
DMSWidget *widget = [self.widgetStorageTableViewController.tableView dequeueReusableCellWithIdentifier:#"Key Value Row"];
...
return widget;
}
These cells have their inner layouts set up entirely using AutoLayout.
Everything works fine, except that I get cells which have the standard 44 px height and width of the table view, with Content Views narrower than this (depending which they contain, the ones with less contents are smaller), and are longer than the cells themselves. So the Content Views overlap the next cell but don't fill the entire width.
I don't understand, how this could happen. How is it possible, that the UITableViewCell has different size than it's Content View? They should be the same, isn't it?
What I tried to do but failed:
implement -tableView:heightForRowatIndexPath:: tried to return UITableViewAutomaticDimension, but did not help
reload my table view when the sizes are calculated: does nothing
add hacks to cell implementations, like setting autoresizingMask in -awakeFromNib: I could make the Content View expand to the width of the cell itself, but it was still overlapping to the next cell
UPDATE: It looks like it is not related to the dual table view architecture. When I copy my cell to the tableView where it will show up, has the same issues.
I've found the solution: it was all my fault. In some of the ancestors of my cell has an init, which called -initWithFrame: explicitly with CGRectZero. After removing this, iOS 8 could use it's frame values and everything worked fine.

UICollectionViewCells with dynamic heights

What would the pattern be for sizing a UICollectionViewCell based on some content I've downloaded? I wouldnt know the size when the cell gets created - it would be sometime after my content has downloaded that the cell would callback with its height. What would I call on the collectionview to have it re layout its cells?
I've faced this with tableviews and ended up calculating the height based on the strings and controls in the cell. But in that case essentially everything was a function of data already in my model. Thats not the case here.
Thanks,
Jason
Depending on the number of cells you will displaying (e.g. a small # of cells), simply calling [UICollectionView reloadData] will do the trick once you know the different heights from that network callback.
I think that the the RFQuiltLayout can solve your problem.
Use the function
(CGSize) blockSizeForItemAtIndexPath:(NSIndexPath *)indexPath
Here is the link https://github.com/bryceredd/RFQuiltLayout

How to set dynamic height of cell based on content

I am have an app which requires to display user comments within a table cell. How can I set the dynamic height of the cell based on the contents of the cell like in Instagram?
Basically, I have texts and comments that have different length in different cells. Can anyone advise me on how I can implement the dynamic height method (like instagram)?
Check the UITableViewDelegate documentation.
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath
Bear in mind you can't reference the cell from this method, so you want to calculate the height of the contents separately and use it to generate the height.
Combine my dynamic label category here with my dynamic table cell height here. Perfect combination!
You should give a look at three20 library source code, which offers complex cells like you want to do. It might give you answers on how to do this, even if you do not intend to use it:
You should refer to this question. The answer is here.
Dynamic UITableView height in UIPopoverController (contentSizeForViewInPopover)?

What replacement options are there for heightForRowAtIndexPath in a UITableView?

tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath is deprecated according to the iOS docs. It mentions using rowHeight instead, but that property is for all rows. I want to flow the rows' height versus the content's (UILabel) varying size.
Is several custom cell styes my only other option besides heightForRowAtIndexPath?
http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewDelegate_Protocol/Reference/Reference.html
Sorry to tell you that...but it isn't deprecated ;)
EDIT: only thing they are saying is if you have very big tables (1000+ cells) it's better to use rowHeight because of performance issues.

Resources