Search code examples
iosuitextviewuitextviewdelegate

dynamically resizing UITextView width and height


My code dynamically adjusts according to the text. It increases height when we press enter and increases the width unless we press return.

But how do I make it

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
CGFloat height = [textView.text sizeWithFont:textView.font].height;
CGFloat width =  [textView.text sizeWithFont:textView.font].width;
 if ([[NSCharacterSet newlineCharacterSet] characterIsMember:[text characterAtIndex:text.length-1]])
 {
     self.textViewHeight += height;

     [textView setFrame:CGRectMake(self.contentView.frame.origin.x, self.contentView.frame.origin.y, width, self.textViewHeight)];
     self.contentView.frame = textView.frame;
     self.frame = textView.frame;
     [_editButton setFrame:CGRectMake(self.contentView.frame.size.width - 14, 0, 28, 28)];
   }
    else{

    int charsAsInt = (int)(textView.text.length);
    CGFloat charWidth = width / charsAsInt;

    [textView setFrame:CGRectMake(self.contentView.frame.origin.x, self.contentView.frame.origin.y, width+ charWidth, self.textViewHeight)];
     self.contentView.frame = textView.frame;
     self.frame = textView.frame;
     [_editButton setFrame:CGRectMake(self.contentView.frame.size.width - 14, 0, 28, 28)];


}

But it increases width even when I press return. How to prevent that.


Solution

  • OK the width is width of whole text in all the lines. So have to find a max line length.

    - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
    {
    CGFloat height = [textView.text sizeWithFont:textView.font].height;
    //CGFloat lineWidth;
    
    int charsAsInt;
     if ([[NSCharacterSet newlineCharacterSet] characterIsMember:[text characterAtIndex:text.length-1]])
     {
         self.lineWidth = 0;
         newLine = @"";
         self.textViewHeight += height;
         NSLog(@"height: %f, width: %f, new Height: %f", height, self.textViewWidth, self.textViewHeight);
         [textView setFrame:CGRectMake(self.contentView.frame.origin.x, self.contentView.frame.origin.y, self.textViewWidth, self.textViewHeight)];
         self.contentView.frame = textView.frame;
         self.frame = textView.frame;
         [_editButton setFrame:CGRectMake(self.contentView.frame.size.width - 14, 0, 28, 28)];
    
         [super setFrame:textView.frame];
     }
     else{
         newLine = [newLine stringByAppendingString:text];
         self.lineWidth = [newLine sizeWithFont:textView.font].width;
         charsAsInt = (int)(newLine.length);
         CGFloat charWidth = self.lineWidth / charsAsInt;
    
    
         if(self.lineWidth >= self.textViewWidth){
             self.textViewWidth = self.lineWidth;
             [textView setFrame:CGRectMake(self.contentView.frame.origin.x, self.contentView.frame.origin.y, self.lineWidth, self.textViewHeight)];
         }
    
         else{
             [textView setFrame:CGRectMake(self.contentView.frame.origin.x, self.contentView.frame.origin.y, self.textViewWidth, self.textViewHeight)];
         }
         self.contentView.frame = textView.frame;
         self.frame = textView.frame;
         [_editButton setFrame:CGRectMake(self.contentView.frame.size.width - 14, 0, 28, 28)];
         //[super setContentView:self.contentView];
         [super setFrame:textView.frame];
    }
    
    return YES;
    }
    

    Whats happening is We have a multiline UITextView Sticker, so when you press return on your keyboard, you have a new line. Which I'm storing in a new variable now. And the width of whole textVIew is increasing only if width of new line is more than width of old line(self.textViewWidth)