Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calculate TextView height base on text

Tags:

ios

uitextview

I am using the code below for calculate the height of text, then set this height for UILabel and UITextView

CGSize targetSize = CGSizeMake(300, CGFLOAT_MAX);
NSString *message = @"The Internet connection appears to be offline.";

NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init];
CGSize boundingBox = [message boundingRectWithSize:targetSize
                                              options:NSStringDrawingUsesLineFragmentOrigin
                                           attributes:@{NSFontAttributeName:FontOpenSanWithSize(14)}
                                              context:context].size;

CGSize size = CGSizeMake(ceil(boundingBox.width), ceil(boundingBox.height));
// it will return size:width = 299 and size height 20
// => if I use this height and set for UILabel, it can display full content
// => if I use this height and set for UITextView, it can not display full content 

It's work perfect for UILabel but for UITextView sometime it calculate wrong.
I think the problem happened because the padding (left, right) of UITextView is bigger than UILabel.
So how can I calculate the correct size of text for display in UITextView. Any help or suggestion would be great appreciated.

Like the description image below
With the same size (300), same font, same text but the UITextView display in 2 lines, but UILabel in 1 lines. And my code for calculate height return 20, it not enough for display in 2 lines, so the UITextViewcan not display full content

The reason why I need to calculate the height of UITextView base on text because my UITextView is in a popup. And the popup height will depend on the TextView height

enter image description here

like image 984
Linh Avatar asked Sep 01 '16 10:09

Linh


2 Answers

There are two things you can try:

  1. Set textView.textContainerInset = UIEdgeInsetsZero
  2. Set textView.textContainer.lineFragmentPadding = 0

With these operations you can get rid of all the padding in the textView and when its width matches with the label's one the heights are also the same.

Here's a sample code you can place in an empty viewController and test it yourself:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    NSString *text = @"The internet connection appears to be offline.";
    CGFloat width = 100.f;

    UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(20, 20, width, 300)];
    textView.font = [UIFont fontWithName:@"AvenirNext-Regular" size:12.f];
    textView.text = text;
    [self.view addSubview:textView];

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20 + width, 20, width, 300)];
    label.numberOfLines = 0;
    label.font = [UIFont fontWithName:@"AvenirNext-Regular" size:12.f];
    label.text = text;
    [self.view addSubview:label];

    // Getting rid of textView's padding
    textView.textContainerInset = UIEdgeInsetsZero;
    textView.textContainer.lineFragmentPadding = 0;

    // Setting height of textView to its contentSize.height
    CGRect textViewFrame = textView.frame;
    textViewFrame.size = textView.contentSize;
    textView.frame = textViewFrame;

    // Setting height of label accorting to it contents and width
    CGRect labelFrame = label.frame;
    labelFrame.size = [label sizeThatFits:CGSizeMake(width, HUGE_VALF)];
    labelFrame.size.width = width;
    label.frame = labelFrame;

    NSLog(@"Label bounds: %@", NSStringFromCGRect(label.bounds));
    NSLog(@"TextView bounds: %@", NSStringFromCGRect(textView.bounds));

    // Visualizing final effect with borders
    textView.layer.borderColor = [UIColor redColor].CGColor;
    textView.layer.borderWidth = 1.f;
    label.layer.borderColor = [UIColor greenColor].CGColor;
    label.layer.borderWidth = 1.f;
}

Console output:

2016-09-01 14:29:06.118 stack39268477[943:243243] Label bounds: {{0, 0}, {100, 66}}
2016-09-01 14:29:06.119 stack39268477[943:243243] TextView bounds: {{0, 0}, {100, 66}}
like image 103
Mr Quattro Avatar answered Sep 30 '22 10:09

Mr Quattro


You don't need to calculate Height of UITextview based on text.

Just change frame and set height like this:

textview.size.height = textview.contentSize.height;

This is easy solution. I hope this helps you.

like image 32
Nimisha Ranipa Avatar answered Sep 30 '22 08:09

Nimisha Ranipa