I m using a UITableView and several custom cells. Each cell has his own height (the cells include UICollectionView, UITableView and some more customs UIView).
More then this, the customs cells (all of them) load from .xib.
Basically, the cell height should be determine from the Model (mvc) or it is static.
In My case, I can determine the cell's height after I instantiate each one of them, e.i loadNibNamed:owner:options: or dequeueReusableCellWithIdentifier:forIndexPath: (I don't care about reuse, It's not the point here), because I need to inflate the cell's content.
As far as I know the methods calls of UITableViewDelegate and UITableViewDataSource isn't documented, therefore I don't need to consider their calls order.
How can I determine cell's height without instantiate it? And without Magic numbers.
You need to calculate row heights in following UITableViewDelegate methods based on your model
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
If your height calculation is based on network response, update your data model when response is received and call [self.tableView reloadData]
Related
I have UITableView that contains 4 different types of customized cells in storyboard. Each cell has customized UILabels which get variable amount of text data from backend. I am struggling with making the cells resizing correctly. I would really want to change the height of each cell but I can not use heightForRowAtIndexPath because it is called before cellForRowAtIndexPath, but the height is actually calculated within each customized cell.
I tried writing in each cells' height into an array while the UITableView is loading, then just reloading it all over again once, but no effect. I tried using CGFloat rowHeight = UITableViewAutomaticDimension with no success either. The customized labels in each cell definitely grow with text which I see when I just statically change row height to higher numbers. So, I would need somehow my labels to push on rows to make them grow, not sure.
Different similar posts on stackoverflow that I found did not help.
The issue was that I needed to set up top and bottom constraints to the ContentView and NOT to the cell itself in the storyboard.
Label -> ContentView top and bottom constraints need to be set up. And then UITableViewAutomaticDimension specified in viewDidLoad:
self.tableView.rowHeight = UITableViewAutomaticDimension;
estimatedRowHeight should be set too. For example:
self.tableView.estimatedRowHeight = 76.0f;
First Method called is:
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
Second:
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Then:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
set a break point in the above methods and test it. So if you want to preset the height use estimatedHeightForRowAtIndexPathmethod.
Assume we have UITableView created in storyboard with prototype cells, it is required to change the structure of table cells (adjusting frames of labels in cell content) based on some calculations at loading the view, currently I change each cell in
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
after using dequeueReusableCellWithIdentifier: to load table cell,
but this is not efficient as each cell has to be modified individually, it would be much better if we could modify a loaded cell once and reuse the modified cell .
Any ideas ?
This could be useful:
Prefilling the UICollectionView cell reuse queue
UITableView dequeueReusableCellWithIdentifier Theory
I want to know if I have customized my own tableviewcell with a specified height and this value is not the same as I used in heightForRowAtIndexPath. Which height will be used for the cell. Since I have multiple customized cells in one tableview, it will be difficult for me to distinguish each type of them in the heightForRowAtIndexPath function. I just want to know in this case, can I just use the cell height I defined for each type of cell?
You can implement this method of the UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
//The height you desire to have for the row at *indexPath*
}
According to the UITableViewDelegate protocol reference,
The method allows the delegate to specify rows with varying heights. If this method is implemented, the value it returns overrides the value specified for the rowHeight property of UITableView for the given row.
My found is that before iOS8, you have to specify the row height in heightForRowAtIndexPath. Until iOS8, Apple provides autolayout and resize of cell, e.g. adding constraints.
Not sure if this is the only way to control the cell row height or not.
I adjust the height of a custom UITableViewCell inside the custom class, and I believe I need to use the -tableView:cellForRowAtIndexPath: method to adjust the height of the cell. I am attempting to just adjust the height of the custom cell in the custom cell class, then grab the cell at the given index path cast it, and return the height of that cell like this:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
CustomUITableViewCell *cell = (CustomUITableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
return cell.frame.size.height;
}
But I am getting stack overflow. What is a better way around doing this?
The table view delegate will first call heightForRowAtIndexPath: and then the datasource will construct the cell in cellForRowAtIndexPath: after that based on the computed information.
Therefore your approach will not work.
You need to have some logic for computing the height. (E.g. if you are displaying text the height might be dynamic and depend on the amount of text - you could calculate that with an NSString method.)
If you are just displaying a few types of cells with fixed heights, simply define these heights as constants and return the correct height based on the same logic you have in cellForRowAtIndexPath: to decide which cell to use.
#define kBasicCellHeight 50
#define kAdvancedCellHeight 100
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (needToUseBasicCellAtThisIndexPath) {
return kBasicCellHeight;
}
return kAdvancedCellHeight;
}
If it's a storyboard cell, you can call dequeueReusableCellWithIdentifier:. Otherwise, you can just instantiate the cell directly with something like [CustomUITableViewCell alloc] initWithFrame:].
I use this approach (using a prototype cell to calculate height) myself because it allows our designer to modify storyboard cells without requiring code changes.
You may want to adjust your approach based on whether the height is static or dynamic as discussed here.
I have a tableview that fill with custom cells,, Now I want to increase the width of the cell,I increased the cell height of UITableview. But the problem is still same. Any one know how to increase the height of custom cell in UITableView.
Thanks,
If your cell heights vary, implement the following delegate:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 44.0; // edit this return value to your liking
}
If they don't, merely set the rowHeight property of your table view instance to whatever height you want all of your cells to be. This answer does a good job of explaining why.