UITextView resizing does not work correctly for first two newlines

I have a UITextView

called messageTextView

which is a subset of UIView

which I am calling messageFieldContainer

.

I need to resize both my UITextView

and the container UIView

as the user is typing more characters into UITextView

.

Here's the current method I'm using to accomplish this:

- (void)textViewDidChange:(UITextView *)textView
{
    CGFloat fixedWidth = textView.frame.size.width;
    CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, CGFLOAT_MAX)];
    CGRect newFrame = textView.frame;
    newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);

    if (self.previousFrameSize.height && self.previousFrameSize.height != newFrame.size.height) {
        self.messageFieldContainer.frame = CGRectMake(0, self.messageFieldContainer.frame.origin.y - 20, self.messageFieldContainer.bounds.size.width, newFrame.size.height + 20);

    }

    self.previousFrameSize = newFrame.size;
    textView.frame = newFrame;
}

      

I use previousFrameSize

to track the resizing of the frame UITextView

, and if the frame ever resizes, I increase the size messageFieldContainer

to accommodate the increased size of the image frame.

This works fine in most cases, except for two situations:

  • Newline, first character

Here is a screenshot of what the text view looks like when starting a new line and you enter the first character of the line:

enter image description here

  1. New line, second character

Here is a screenshot of what the text view looks like when a new line starts and you enter the second line character:

enter image description here

Here is a screenshot of what the text view looks like as soon as you enter the third newline character. This is how it should look 100% of the time:

enter image description here

I need to fix this logic so that the text view always looks like the third image, even when you type the first or second newline character.

+3


source to share


3 answers


I managed to solve the newline issues by disabling Autolayout

in my nib/xib

file and setting the property to a UITextView's

scrollEnabled

value NO

.

Disabling Autolayout

has improved slightly, but UITextView

will still garble when starting a new line. The only way to fix this problem is to disable scrolling.



Hope someone finds this helpful. I spent several hours trying to implement tricky solutions Autolayout

before I came across the accidental comment mentioned above.

0


source


I've been doing this for two days and disabling Autolayout was not an option for me. After searching and trying, I found a solution. The code is in Swift, but it shouldn't be too hard. Basically you should use KVO to control the size of the textView content.

override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
    println("Observed")

    //I have to format the textView twice, not sure why, but it is not a mistake.
    // Dont like having to do this, but this has been the only way to make the textview scroll properly on newline.
    let textView:UITextView = object as UITextView
    formatTextViewHeight(textView)
    var topOffset = (textView.bounds.size.height - textView.contentSize.height - textView.contentInset.top * textView.zoomScale) / 2.0
    textView.contentOffset = CGPoint(x: 0, y: -topOffset)
    formatTextViewHeight(textView)

}

      

My formatted text view method needs to be called twice in KVO



func formatTextViewHeight(textView: UITextView) {

    let stryBrdPad:CGFloat = 4.0
    self.tableView.beginUpdates()
    self.replyView.frame.size.height = textView.contentSize.height + stryBrdPad
    textView.frame.size.height = textView.contentSize.height
    self.tableView.endUpdates()

}

      

I'm new to text APIs so I might be missing something, but I've noticed that some popular apps have this problem too. When I tried formatting in textviewDidChange I noticed in my logs that the contentSize changed, but if I were to set the textView frame to contentSize and increase my container frame nothing would happen ... even using layoutIfNeeded, updateConstrainst, setNeedsDisplay, I tried All of them..

0


source


I have seen several people on the internet who have this problem. If you have a UITextView whose property scrollEnabled

is equal false

, it automatically expands its height after a newline only after another character is entered.

To fix this, use the method UITextViewDelegate

textViewDidChange

for listening to text changes of text and call sizeToFit()

and layoutIfNeeded()

.

Example

func textViewDidChange(textView: UITextView) {

    textView.sizeToFit()
    textView.layoutIfNeeded()

}

      

0


source







All Articles