In my iPhone application I have four types of cells. Every cell has it's own height. I'd like to set the height of the row for each table view cell but it crashes in this method:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
NSLog(#"%#", cell);
if([cell.reuseIdentifier isEqualToString:PastEventWICellIdentifier]){
return 56;
}
if([cell.reuseIdentifier isEqualToString:PastEventWOICellIdentifier]){
return 56;
}
if([cell.reuseIdentifier isEqualToString:EventWICellIdentifier]){
return 112;
}
if([cell.reuseIdentifier isEqualToString:EventWOICellIdentifier]){
return 112;
}
return 56;
}
How can I resolve this?
You cannot get the cells using cellForRowAtIndexPath inside the method heightForRowAtIndexPath, because the cells are not there yet. They will be created after their heights are set.
You may set the heights of the cells based on their location using indexPath.row.
You cannot use method cellForRowAtIndexPath, this method is called before cellForRowAtIndexPath so the cells don't exists. You should have a list of Height already calculated when heightForRowAtIndexPath is called. Remember to not load all list in tableview because this method (heightForRowAtIndexPath) takes longer to load tableview...
Related
I have a UITableView with 16-20 cells inside with dynamic cell size. When a cell expands it self it should also move itself to the top of the screen. I did that using "UITableView setContentOffset" method. It works well except for the last cell in table, it's not able to move itself to the top.
I tried altering the frame & content size of UITableView but none of those were working for me!
Any Idea?
[UPDATE]
Here is a part of code: (it's inside the UITableViewCell, so self is pointing to current cell)
HomeViewController *tempViewController = (HomeViewController *) delegate;
UIView *commentField;
/*Skipping lines of codes manipulating commentField */
//Adding a subview to current cell which needs more space
[self addSubview:commentField];
//Expanding cellSize to EXPANDED_CELL_HEIGHT
//ViewController has access to cell size property and using that to determine each cell size.
[self setCellSize:(EXPANDED_CELL_HEIGHT)];
//Reloading UITableView to reflect the cell size change with animation
[[tempViewController tableView] beginUpdates];
[[tempViewController tableView] endUpdates];
[[tempViewController tableView] setContentOffset:CGPointMake(0, self.frame.origin.y) animated:YES];
and in my view controller (as I said earlier) I'm getting cellSize form cell itself
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [(BaseTableViewCell *)[cellContainer objectAtIndex:indexPath.row] cellSize];
}
You can change the height of the cell using the tableview delegate method heightForRowAtIndexPath: When indexPath.row equals your last row, return the height you would like.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == i)//i being whatever row index you want to change
{
return 60.0;//or float size you want
}
else
{
return 30.0;
}
}
Or you can just modify the bounds of the cell inside willDisplayCell:. If your using a custom tableview cell, just shrink the subviews to whatever frame you'd like and make the cell background clear etc.
If we return 100 in numberOfRowsInSection like
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 100;
}
then how many cells will be created at a time in cellForRowAtIndexPath method?
If you are asking how many times the -tableView:cellForRowAtIndexPath: method would be called, the answer is it would be called as much cells are visible for the moment. When you scroll, it would be called for each new cell which is about to be displayed. How does it knows how many cells are visible right now? The -tableView:heightForRowAtIndexPath: is called for each cell to calculate the contentSize of the table view.
Actually it wont allocate all the 100 cells. Instead only those which will be visible at the moment. As we are using [tableView dequeueReusableCellWithIdentifier:cellIdentifier];, the cells are reused for memory handling.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
just returns the total number of cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
this method will be called each time you scroll a table view.
It depends on your cell type. If you set dequeueReusableCellWithIdentifier, then it initializes only what you see on the screen and when you are scrolling it will scroll down to the amount of rows you set in the method above.
It will allocate all 100 Cells but visible at a time only the Cells which will be fixed as per
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
height of the Cell and width of the UITableView Frame
The number of cell return its base on UITableView height. means it return number of cell display at first time. tableView:cellForRowAtIndexPath method call for only visible cell it is not call for invisible cell of UITableView. if you scroll then tableView:cellForRowAtIndexPath reuse previous invisible cell rather then cerate new one.
Agree with #pbibergal, if you are used dequeueReusableCellWithIdentifier and put a condition like below then at a time approximately nine(9) cell created at a time (number of cell is depend on tableview height). otherwise 100 cell created by system at a time.
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell==nil) {
cell = [[MainCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if you used above code then at a time limited cell created at a time (nine cell) other wise 100 cell created at a time and it was affected in memory.
Is there anyway I can change the height of previous UITableViewCell when setting height for current cell in - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath?
Have two rows in a UITableView. When in first row, it will set the default height.. When in row two I want to change the height of first row. Is this possible? If so how?
Thanks,
Bharathi.
Try to work with a boolean check if the requirement is fulfilled.
You could do it like this:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0 && !secondRowIsSynced) {
return otherHeight ;
}
else {
return defaultHeight;
}
}
I think you misunderstand tableView:heightForRowAtIndexPath: is called multiple times (once for each row in your table).
If your rows have different heights then you need to determine which row you are on and what height it should have.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
CGFloat height;
if (0 == indexPath.row) {
// This is the first row
height = // what ever you want
} else if (1 == indexPath.row) {
// This is the second row
height = // what ever you want
}
return height;
}
If you later decide that a row needs to be a different height then it is still this method that needs to calculate the correct height to be used for each row. You can force this to be called without reloading the tableView like this
[tableView beginUpdates];
[tableView endUpdates];
bharathi:
You have to reload your table in the didSelectRowAtIndexPath method of UITableView.
You should check that the second row is selected, then reload all the table rows, so all tableview delegate and datasource methods get called again.
There are 1 table on uiview and I want to change the cell height when button pressed other cell's height remain same
Pass the button press event to the view controller through delegate methods and reload the table view as follows.
[self.tableView reloadData];
In view controller (ie., datasource for the table view), implement heightForRowAtIndexPath method and return the height as required.
You can change the cell height in the delegate method
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if(indexPath.row == clickedRow)
return newHeitht;
return cellHeight;
}
you can set some condition in button click and reload the tableview using [tableView reloadData]. this function will be called. return a new height for the particular cell.
-(void)buttonClick {
[self.tableview reloadData];
selectedRow = //do something here
}
and in your UITableview Datasource
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath {
if(indexPath.row == selectedRow)
return selectedRowHeight;
else
return defaultHeight;
}
1) Create a custom UITableViewCell class.
2) Populate you cell however you see fit. I use a 'hydrateWithArray' type function myself.
3) Once the data has been populated, resize and reposition elements using 'sizeToFit' functions to force labels to conform to the size of whatever you put into them. protip: by setting the frame of the label first, and setting the numer of lines to 0... when you fill the text and sizetofit, it will stretch the label vertically only and force the width to stay the same.
4) Create a seperate function (mine is called calculatedHeight) that returns a float and returns the height that you would like the cell to be in the table (based on the repositioned objects from step 3).
- (float)calculatedHeight {
return textLabel.frame.origin.ytextLabel.frame.size.height5;
}
5) In your UITableView class, you'll need to import your tableViewCell class and create a dummy cell object. You're going to use this class to calculate how tall each cell needs to be. Then in the heightOfRowAtIndex method....
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
float height;
if ( !dummyCell ) dummyCell = [[CustomCell alloc] initWithFrame:CGRectMake(0,0,0,0) reuseIdentifier:#"myCell"];
[dummyCell hydrateWithTweet:[tableArray objectAtIndex:indexPath.row]];
height = [dummyCell calculatedHeight];
if ( height == 0 ) height = 50;
return height;
}
This is a pretty simple example so you may need to go crazy with the error checking in your particular use, but this should at least point you in the right direction. Enjoy!
(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (isSearching && indexPath.row == selectedIndex) {
return 110;
}
else {
return rowHeight;
}
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:toReloadRows withRowAnimation: UITableViewRowAnimationNone];
[self.tableView endUpdates];
then
[self.tableView beginUpdates];
[self.tableView endUpdates];
I am working on a custom tableviewcell and trying to increase its height. I dont want to do it from my viewcontroller. Can someone please help me?
Thanks
You actually need to do it from your UITableViewDelegate.
What you can do though, is use UITableView's cellForRowAtIndexPath method to get the actual cell and call isKindOfClass: on it, and if it matches the type of your custom cell, you're golden.
Implement the tableView:heightForRowAtIndexPath: method and return the desired height for the specified row:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if([cell isKindOfClass:[YourCustomCell class]]) return someHeight;
return 44.0;
}
I'm afraid you have to do it from your controller in the tableView:heightForRowAtIndexPath:. There is no other way to do it. :(