I have UITableViewCell
and inside of that cell I have a UITextView
. When I will change text of UITextView
I want to change cell height real time?
How can I do that? Thanks.
I have UITableViewCell
and inside of that cell I have a UITextView
. When I will change text of UITextView
I want to change cell height real time?
How can I do that? Thanks.
The main idea of this solution is to calculate the textView's height and assigns it to its row.
Note: this is Swift 3 code:
class ViewController: UIViewController {
// array containing rows heights:
var rowHeights = [CGFloat]()
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// fill it with default values of row heights
for _ in 1...10 {
rowHeights.append(44)
}
}
}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return rowHeights[indexPath.row]
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// return the actual number of your rows...
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TextViewTableViewCell") as! TextViewTableViewCell
// assgin the tag of current text view to use for determining the current cell's height
cell.textView.tag = indexPath.row
cell.textView.delegate = self
return cell
}
}
extension ViewController: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
// calculate the current height and append it in the rowHeights depends on the textView's tag. Add your the textView fontSize instead of 15
rowHeights[textView.tag] = (textView.text?.heightWithConstrainedWidth(width: tableView.frame.size.width, font: UIFont.systemFont(ofSize: 15)))!
// for updating the tableView appearence (don't use "reloadData", it will resignFirstResponder the textView)
tableView.beginUpdates()
tableView.endUpdates()
textView.setContentOffset(CGPoint.zero, animated: true)
//textView.becomeFirstResponder()
}
}
extension String {
// this method calculates the height of string depending on your view width and font
func heightWithConstrainedWidth(width: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)
return boundingBox.height
}
}
CustomTableViewCell:
class TextViewTableViewCell: UITableViewCell {
@IBOutlet weak var textView: UITextView!
}
The output should looks like this:
Hope That Helped.
If you are using auto layout to calculate your cells height, I think you just have to use reloadData()
method on your tableView.
you need to set autolayout of UITableviewCell
as per below link :
Using Auto Layout in UITableView for dynamic cell layouts & variable row heights
after this you have to reload UITableViewCell
as per your needs using below link :
Reference from : Using Auto Layout in UITableView for dynamic cell layouts & variable row heights
You need to calculate height of cell after the auto layout do its part I mean after arranging the inner views width/height based on text provided.
Follow the solution:
First add UITableView
delegate method below in view controller,
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
Calculate cell's height in heightForRowAtIndexPath:
delegate method:
* THIS IS IMPORTANT*: Do remember that assign cell label's and textView's values same like you did in cellForRowAtIndexPath
delegate method.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellIdentifier = [NSString stringWithFormat:@"CustomCell%d%d",(int)indexPath.section, (int)indexPath.row];
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
// Set cell label text same like you did in `cellForRowAtIndexPath`
// For example
NSString *name = [self.dataArray objectAtIndex:indexPath.row];
cell.nameLabel.text = name;
cell.textView.text = @"This is long text.....";
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(tableView.bounds), CGRectGetHeight(cell.bounds));
[cell setNeedsLayout];
[cell layoutIfNeeded];
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
height += 5;
return height;
}
Now if you have created CustomCell
add below constraints in cell's initWithStyle:
method
// Other controls initialisation and creation code
// ....
// TextView control setup
[self.textView setTranslatesAutoresizingMaskIntoConstraints:NO];
// Above line is very important otherwise below constraint wont work
// Because by default it uses auto size constraints
// Other controls constraints
// ....
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[textView]-10-|" options:0 metrics:nil views:@{@"textView" : self.textView}]];
NSLayoutConstraint *pinToBottom = [NSLayoutConstraint constraintWithItem:self.textView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.contentView
attribute:NSLayoutAttributeBottom
multiplier:1
constant:0];
[self.contentView addConstraint:pinToBottom];
And add below delegate method
- (void)layoutSubviews {
[super layoutSubviews];
[self.contentView setNeedsLayout];
[self.contentView layoutIfNeeded];
self.textView.preferredMaxLayoutWidth = CGRectGetWidth(self.textView.frame);
}
But if you have not created custom cell and you are using cell from Storyboard, add bottom constraint to your superView (cell's content view).
Call This method from cellForRowAtIndexPath Delegate
(CGSize)attributedText:(NSAttributedString *)text sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size
{
return [self textViewHeightForAttributedText:text constrainedToSize:size];
}
This method will give you the height of your cell.
(CGSize)textViewHeightForAttributedText: (NSAttributedString*)text constrainedToSize:(CGSize)size
{
UITextView *calculationView = [[UITextView alloc] init];
[calculationView setAttributedText:text];
CGSize size1 = [calculationView sizeThatFits:size];
return size1;
}
use this statement in cellForRowAtIndexPath
CGSize textSize = {tableView.frame.size.width-70, 10000.0 };
CGSize size1 =[self attributedText:attrString sizeWithFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:14] constrainedToSize:textSize];