I have one UItableview and I have one customCell for printing the data in the UITable.
Now, I want to put more data in specific cell. When I select on cell, it should increase the height of cell and put that data. How is it possible.?
In DidSelect make the height of particular selected cell to your required cell.
And reload the table.
This is helpful : How to programmatically increase UITableView cell's height in iPhone?
Call reload table data by changing the parameters of row and to find the height of a cell after adding data use:
CGSize size=[youstring sizeWithFont:yourlabel.font constrainedToSize:labelfontsize lineBreakMode:lineBreakmodestyle];
And get height from size.height and return the height in heightForRowAtIndexPath method while reloading tableview.
what you should do is First Calculate the Size of your content for which you have to increase the cell height
//Suppose here is your string which you want to show
-(float) calculateHeight:(NSString *)dataStr
{
CGSize size = [dataStr sizeWithFont:[UIFont fontWithName:#"Helvetica" size:17] constrainedToSize:CGSizeMake(280, 999) lineBreakMode:UILineBreakModeWordWrap];
NSLog(#"%f",size.height);
return size.height + 10;
}
This Above function will return the height according to your Text Size.
Now just have to call this function on the
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
}
delegete and reload the tableview and give the size you calculated with the above function at heightForRowAtIndexPath delegete.
Try this sample if I've understood what you want: https://github.com/Dmitriy837/changeTableRowHeighWhenTaped
I suggest you subclass UITableView and support additional property with cell heights in it and change the cell's height when it's taped.
Related
I want to increase tableview cell and tableview height based on content.
Suppose tableview contain 2 record and his 1st cell height is 100 and 2nd cell height is 25 then tableview height should be 100+25=125.
How to achieve this functionality?
Thanks in advance.
You can definitely do that,
First make sure your constraint of cells subView must set to top to bottom in order to calculate the height required for the cell.
Make sure your delegated are set as below
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 44;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
Set height constraint of your tableView and make outlet of that constraint.
Add below method to your class where you want to resize your tableView dynamically.
- (void)adjustHeightOfTableview
{
CGFloat height = self.tableView.contentSize.height;
//CGFloat maxHeight = self.tableView.superview.frame.size.height - self.tableView.frame.origin.y;
/*
Here you have to take care of two things, if there is only tableView on the screen then you have to see is your tableView going below screen using maxHeight and your screen height,
Or you can add your tableView inside scrollView so that your tableView can increase its height as much it requires based on the number of cell (with different height based on content) it has to display.
*/
// now set the height constraint accordingly
self.constraintHeightTableView.constant = height;
//If you want to increase tableView height with animation you can do that as below.
[UIView animateWithDuration:0.5 animations:^{
[self.view layoutIfNeeded];
}];
}
Call this method when you are ready with the dataSource for the table, and call the method as
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
//In my case i had to call this method after some delay, because (i think) it will allow tableView to reload completely and then calculate the height required for itself. (This might be a workaround, but it worked for me)
[self performSelector:#selector(adjustHeightOfTableview) withObject:nil afterDelay:0.3];
});
If you are running iOS 8+,
You can use:
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 80 // your desired or expected height
properties.
for this to take effect you should not have any height set in heightForRowAtIndexpath
You should set the cell constraints i.e., constraints for the elements present inside cell, so the set constraints are enough for the tableviewcell to calculate it's height in run time
Solution in swift 3
Step 1.
Set the top, bottom, leading and trailing constraints (do not make it constant height, but do set a constant height constraint as of now).
Now we gonna change this height dynamically based on the number of cells and its height.
Step 2.
Drag an outlet of that height constraint to the class, and copy this function anywhere in the class.
func adjustHeightOfTableview() {
let height: CGFloat = tableview.contentSize.height
self.outLetOfTheHeightConstraint.constant = height
}
Step 3.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
DispatchQueue.main.async {
self.tableview.reloadData()
self.perform(#selector(self.adjustHeightOfTableview))
}
}
self.tableView.frame = CGRectMake(self.tableView.origin.x, self.tableView.origin.y, self.tableView.frame.size.width, 125);
It sounds so simple but it's not, what I want is to make a UITableViewCell with a UITextView inside. I am using auto layout so when the tableview first loads all cell they will all be in the same maximum static size and when I press the cell the cell expand according to the UITextView's text.
The hard part is to add a "See More" button in the end of the text view if it doesn't fit the static size.(before the cell was pressed)
I also saved to array if the cell was pressed to know if to expand it or not.
another tricky part is if the textview is below the static size than use the UITableViewAutomaticDimension so if its 40 points of height I don't want the cell to be 102 point because of a blank space the will be created
for that I need to know if the textview is below 102 point.
I thought about implementing heightForRow something like that
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if([self isCellWithIndexNeedsToExpand:[NSNumber numberWithInteger:indexPath.row]])
{
return UITableViewAutomaticDimension;
}
else
{
int height = [self someFunctionThatGivesTheTextViewHeight];
if(height>102)
return 102;
else
return UITableViewAutomaticDimension;
}
}
In autolayout it does not matter at all.. but through code you can use this below code to find estimated string size,
CGSize labelSize = [myLabel.text sizeWithFont:myLabel.font
constrainedToSize:myLabel.frame.size
lineBreakMode:NSLineBreakByWordWrapping];
CGFloat labelHeight = labelSize.height;
then you can increase the height of row
Iam creating a custom UITableViewCell programatically , I need the height of the cell (which I changed) , at my custom cell I get the cell's height by self.contentView.bounds.height , which gives me the original height (not the changed one ) , how can I get the changed height ???
You MUST calculate cell height in
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
Otherwise tableView uses Row Height from Interface Builder Size inspector for tableView.
You can use this
CGRect frame = [tableView rectForRowAtIndexPath:indexPath];
//To get the height
NSLog(#"row height: %#", frame.size.height");
I have a UITableViewCell which contains a UIWebView as a subview. The web view fills the entire cell. I am using estimatedRowHeight to calculate the row height. However, at the time the table view is built, the cell has no height because the web view has not loaded it's content, therefore the cell has no content. Because of this, estimatedRowHeight returns 44 instead of the correct height of the web view content.
Does anyone know how I can correctly calculate the height of a row when the content is not immediately set? Is there a way to estimate the height of some cells and explicitly set the heigh of other cells, in the same table view?
This is how I am using estimatedRowHeight:
self.tableView.estimatedRowHeight = 200;
self.tableView.rowHeight = UITableViewAutomaticDimension;
I am not using the delegate method. I have tried it, but it does not change the result. The cell I am using has a xib which also uses Auto Layout constraints. To be clear, the cell does appear and the web view does get added to the cell. The problem is that the height of the cell is not big enough to show the entire web view. The web view loads an HTML embed code for an audio player.
I did some fiddling around and found out that you can use UITableViewAutomaticDimension in the following way:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
TableSection *tableSection = (self.tableModel.sections)[indexPath.section];
if (tableSection.sectionType == TableSectionTypeWebView)
{
return 120;
}
else
{
return UITableViewAutomaticDimension;
}
}
This basically says, use a height of 120 for any WebView sections but for everything else I want you to figure out the height. I am using a my own custom table model here (i.e. TableSection, sectionType, etc...)
I had to add self.tableView.estimatedRowHeight = 200; to my init method for that to work.
Now I can provide an estimated row height but also explicitly set a row height for some sections, or even some rows if I wanted.
I haven't seen any documentation for this, but I tested it with variable length strings and it held up just fine.
You make your class a UIWebViewDelegate and then in and set your class as a delegate to every single UIWebView in your UITableViewCell
-(void)webViewDidFinishLoad:(UIWebView *)aWebView {
CGRect frame = aWebView.frame;
frame.size.height = 1;
aWebView.frame = frame;
//Asks the view to calculate and return the size that best fits //its subviews.
CGSize fittingSize = [aWebView sizeThatFits:CGSizeZero];
frame.size = fittingSize;
aWebView.frame = frame;
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
Now you can get the height of the UIWebView and set it to the rows height, because the following method will be called again once a 'beginUpdates' is invoked
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath*)indexPath {
return _webView.frame.size.height;
}
Hope This helps
This question already has answers here:
UITableViewCell, UITextView with dynamic height
(3 answers)
Closed 8 years ago.
I have a UILabel inside a UITableViewCell. I am not using autolayout, but creating and adding the views manually.
The UILabel can contain a variable amount of text so in my tableview delegate i implement heightForRowAtIndexPath.
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
TableCellWithDocument *cell = (TableCellWithDocument*)[self tableView: tableView cellForRowAtIndexPath: indexPath];
NSLog(#"Cell frame: %#", NSStringFromCGRect(cell.frame));
return [cell heightForCellForWidth: cell.frame.size.width];
The problem i'm having is that when this delegate method is called, the frame size of the cell is not correct. It just returns "default" 320x44.
So when i try to calculate the label size, i have the wrong cell width and my cell height gets the wrong height.
In my subclassed TableCellWithDocument class, i can override layoutSubviews and get the correct cell width, but that is too late since heightForRowAtIndexPath has already been called.
How should i handle this?
You are doing it in recursive manner. If you carefully debug your code, you will find that heightForRowAtIndexPath is called first to estimate cell height, and cellForRowAtIndexPath is called later.
Ideally, within heightForRowAtIndexPath, you should take all your data source content, and estimate the size of it. cellForRowAtIndexPath should be able to use this height to set the cell content.
For example, if there is some text to be displayed, you could use [UILabel sizeThatFits] or [NSString sizeWithFont] method to estimate cell.textLabel size, and so on.
Remember that no answer is the right answer and you must do tweaks according your own data - be it strings, images or anything else. It's data size, not the size of your controls - that must decide what you return from heightForRowAtIndexPath.
Try doing this in Your heightForRowAtIndexPath
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGSize size = [text sizeWithFont:[UIFont fontWithName: #"YourFont" size:24.0];
constrainedToSize:CGSizeMake(kMessageTextWidth, CGFLOAT_MAX)
lineBreakMode:NSLineBreakByWordWrapping];
return MAX(size.height + 17.0f);
}