I have a table with a custom cell, which has only one UIImageView. I want each cell to have its own height based on an image height I will place in it. In my heightForRow method I have
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
FAppFormula *formula = self.formulas[indexPath.row];
UIImage *img = [formula getFormulaImageSmallSize];
if (img.size.height <= 100){
return 30;
}
return 75;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *cellIDSmall = #"FormulaCellSmall";
FormulaCell *cell = (FormulaCell *)[tableView dequeueReusableCellWithIdentifier:cellIDSmall
forIndexPath:indexPath];
cell.formulaImage.image = formulaImg;
return cell;
}
The cells themselves do get proper heights, however images don't get scaled appropriately. In storyboard cell prototype I set UIImageView's mode to Aspect Fit, however looks like all images get scaled based on a default(?) row height, but not on the one which heightForRowAtIndexPath returns...
Any ideas on why it happens and how to fix it? How it looks now img
Related
I have created a simple UITableView with a prototype cell and I have to enlarge the height of row. Unfortunately, I cannot achieve that. I just put the custom size of height for the prototype cell in Interface Builder (Xcode) and put method in ViewController:
-(float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 200.0;
}
And cellForRowAtIndexPath method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
AlbumCell *cell = [tableView dequeueReusableCellWithIdentifier:#"albumCellID"];
if (cell == nil) {
cell = [[AlbumCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"albumCellID"];
}
cell.albumTitle.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
Simulator returns my table with still small height for rows (ca. 40 px). How can I enlarge the height of a row?
I am unsure if I'm setting up the UITableView the right way when using multiple custom cell views. I seem to have my table working however, i think the reuse of cells makes the first cells you see once you load the view the same size as the very first cell which should be the only cell thats double in size. Once I scroll passed them and back up they go to the size thats set for them.
Is there a right way of doing this? I've looked through other forms and tried their ways but this is the closed I've gotten it to work with just that one flaw.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"profileCell";
static NSString *CellIdentifier2 = #"profileCells";
if (indexPath.section == 0) {
PFProfileTableCellView * cell = (PFProfileTableCellView *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
//only one row in this section
return cell;
} else{
PFWallPostTableViewCell * cell = (PFWallPostTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
return cell;
}
}
Use this UITableView delegate method - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; and return row height according to the sections of your tableview like the example below
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
return 100.0;
}
return 50.0;
}
I have created two different tableviewcell into single tableview, Now I have set separate height for separate cells at storyboard "row height". Now the problem is whenever I run the application Its not changing both height are same.
You should implement
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
and return different heights for Parent and Child cells.
Sample Implementation :
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat height = 0;
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
if ([cell.reuseIdentifier isEqualToString:#"ParentCell"]) {
height = 100.0; //Parent Cell height
} else if ([cell.reuseIdentifier isEqualToString:#"ChildCell"]) {
height = 50.0; //Child Cell height
}
return height;
}
Most of the time, when my app is working the way it should, my Table View items look like this:
But every so often a cell (on initial load) looks likes this:
As you can see the image has resized, the 'published By' label has resized.
Why would this happen? The same code/storyboard should affect all the cells the same way? Why are some not doing what they are told?
If it helps, when a cell loads the wrong way, all I have to do is scroll up, and back down again, and the problem is fixed !!
This means that there clearly isn't a problem with the image or the amount of text, is it just the iPhone acting up?
Thanks for any help !
I think its cell dequeue issue. Your cell could not calculate proper height for cell. If you are using autolayout try the following code. hope it will works for you.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
static YOUR_TABLEVIEW_CELL *sizingCell = nil;
static NSString *CellIdentifier=#"YOUR_TABLEVIEW_CELL_IDENTIFIER";
sizingCell =[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (sizingCell==nil)
{
sizingCell=[[YOUR_TABLEVIEW_CELL alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[self configureFareIssueCell:sizingCell atIndexPath:indexPath];
return [self calculateHeightForConfiguredSizingCell:sizingCell];
}
//assign all the lables & images here
- (void)configureFareIssueCell:(YOUR_TABLEVIEW_CELL* )cell atIndexPath:(NSIndexPath *)indexPath
{
//e.g
cell.lbl.text=#"YOUR_TEXT";
cell.imageView.image=[UIImage imageNamed:#"NAME_OF_YOUR_IMAGE"];
}
- (CGFloat)calculateHeightForConfiguredSizingCell:(YOUR_TABLEVIEW_CELL *)sizingCell
{
CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size.height + 1.0f; // Add 1.0f for the cell separator height
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier=#"YOUR_TABLEVIEW_CELL_IDENTIFIER";
YOUR_TABLEVIEW_CELL *cell =[tableView dequeueReusableCellWithIdentifier:#"YOUR_TABLEVIEW_CELL_IDENTIFIER"];
if (cell==nil)
{
cell=[[YOUR_TABLEVIEW_CELL alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[self configureFareIssueCell:cell atIndexPath:indexPath];
return cell;
}
Do you use layer mask for creating rounded image? If yes, you see this strange behavior because layer mask was created before UITableView assign proper frame for cell, so layer mask will have incorrect frame.
I am not a full-time iOS dev and I'm trying to return the cell at the current indexPath but this is crashing and I am not sure exactly why. I maintain the height dynamically on the cell. My cell is a custom UITableViewCell called MICell and I have a property called height which is dynamically calculated in the updateCell method.
#import "MICell.h"
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
MICell *cell = (MICell *)[self tableView:tableView cellForRowAtIndexPath:indexPath];
// hardcoded to 200.0f but still crashing
NSLog(#"here is my height; %f",cell.height);
return 200.0f;
}
Edit 1
As a workaround, I am able to make an instance variable and just write the current cell height which is then accessed in heightForRowAtIndexPath, like the following. I do feel that this is potentially making assumptions that I'm not fully comfortable with:
#interface ListViewController (){
NSMutableArray *_data;
CGFloat _currentCellHeight;
}
...
-(MICell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MICell";
MICell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
// Configure the cell here ...
NSDictionary *tmp=[_data objectAtIndex:indexPath.row];
[cell updateCell:tmp];
_currentCellHeight=cell.height;
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return _currentCellHeight;
}
Edit 2
Here's a reference to this exact technique. How to get the cell object in tableView:(UITableView *)tableView heightForRowAtIndexPath function?
Edit #3
The above code works fine - there was an issue with IB connections.
It's because you're causing an infinite cycle. You cannot call:
[self tableView:tableView cellForRowAtIndexPath:indexPath];
In height for row at index path.
[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
will cause issues when called from height for row at index path. You must call tableView dequeueReusableCellWithIdentifier: without the forIndexPath. You should probably create a configureWithCell:(YourCellClass *)cell method separate from these so you can just configure your cell after properly dequeueing/allocating it.
Also, you do not grab the height from the cell as you're doing above (unless you're assigning a height property with some weird forwarding stuff that breaks class containment... which you shouldn't do either). Use the following for dynamic cell heights via auto layout:
CGFloat cellHeight = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
Something like the following below should do the trick:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCellClass *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([MyCellClass class]) forIndexPath:indexPath];
[self configureMyCell:cell forIndexPath:indexPath];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCellClass * cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([MyCellClass class])];
[self configureMyCell:cell forIndexPath:indexPath];
CGFloat cellHeight = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
return cellHeight;
}
In ios, the height of the cell is calculated in heightForRowAtIndexPath. What you are trying to do is to get height of the cell inside heightForRowAtIndexPath. It is definitely not the way to do it. To have dynamic height, calculate the height inside heightForRowAtIndexPath using the features/values you might need and return that height.
Bottom line is you cannot call cell.height inside heightForRowAtIndexPath.
Edit 1:
To help you deal with the dynamic heights in cell, please look at this tutorial. It might help you understand the issue : Dynamic Cell
Just go straight to the tableView delegates method to get an understanding of how to proceed.