0

I am trying to build a similar TextView as iMessage/ WhatsApp, namely a textView that grows in height as the content grows but that also allows scrolling once a certain height is reached.

I set my textView to have textContainerInsent of [8,0,8,0] and a height of 38 and am able to easily resize my TextView using auto-layout as the content increases.

The problem comes when I try to enable scrolling. Whenever my textView has a new line of text, my textContainerInsent gets confused and "pushes" my text upward (meaning that the first line of text is cut with one half outside of the TextView). This happens only every other line (so on the 2nd, 4th, 6th, etc.) for some even weirder reason.

This also only happens only at the first character of the new line and snaps back to place on subsequent character (see pictures).

I was able to hack something together by forcing my top textContainerInsent to 16 ([16,0,8,0]) for even lines and by keeping it to [8,0,8,0]for odd lines.

This is however far from ideal as:

  • When I dismiss my textView the placeholder text that I inject in it is again pushed upward and I can't find a way to fix that
  • There are still micro-movements of a pixel or so even when trying to force the textContainerInsent to [16,0,8,0].

Any idea what is causing this? Am I misunderstanding something about textContainerInsents/ TextView or ContentSize? Any ideas you have on the root causes of this would be appreciated (and don't focus too much on my hack... I want to get rid of it anyway).

I found the following helpful thread but I tried the suggested answers but they didn't work for me (as I am not trying to remove ALL padding and want to keep the scrolling enabled):

How to lose margin/padding in UITextView?

ContentInsent too high when text is wrapped to next line ContentInsent snaps back at right place at the next character

    // Called by textViewDidChange delegate
    @objc func handleTextViewSearch() {

        let maxTextViewHeight : CGFloat = 180

        textView.isScrollEnabled = true
        textView.showsVerticalScrollIndicator = true

        textView.textContainerInset = UIEdgeInsetsMake(8, 0, 8, 0)

        let sizeHeight = min(maxTextViewHeight, textView.contentSize.height )

        // This is my textView Height Constraint

        viewHeightConstraint.constant = sizeHeight
        textView.contentOffset = CGPoint(x: 0, y: 0)

        // This my hack to manually "push" my text back when it jumps by increasing my textContainerInsent to [16,0,8,0]... It almost fixes the issue but doesn't address the root cause for the weird TextView behavior...

        if textView.contentSize.height > textView.frame.height && textView.contentSize.height <= (maxTextViewHeight - 10) {


            // Weird micro readjustment: When line goes from 1 to 2, need to increase insent by another 8 points but only when going from odd to even lines (go figure)...

            var insentAdjustment : CGFloat = 0
            let linesNumber = numberOfLines(textView: textView)
            if linesNumber % 2 == 0 {
                print("Is even number")
                insentAdjustment = 8
            } else if linesNumber == 1 {
                insentAdjustment = 8
            }

            textView.frame.size.height = textView.contentSize.height
            textView.textContainerInset = UIEdgeInsetsMake(8 + insentAdjustment, 0, 8, 0)


            print("Post update TextView: ", textView)
        }
     }
Franc
  • 351
  • 1
  • 3
  • 8
  • Are you using an `inputAccessoryView` ? The user might be using a custom keyboard too. Refer: https://developer.apple.com/documentation/uikit/uiresponder/1621119-inputaccessoryview – user1046037 Jun 21 '18 at 02:57
  • Nope. And it's happening a physical test phone (iPhone X)... – Franc Jun 21 '18 at 03:23
  • No inputAccessoryView is a special view that gets attached on top of any keyboard. Refer the link. And you can customise that view. I using it would be more appropriate – user1046037 Jun 21 '18 at 03:26
  • Gotcha! Yes it looks promising. How customizable is a inputAccessoryView (i.e., can it be easily resized programmatically to create custom animations and can it's look be changed)? In any case I would still love to hear if anyone has the same issues as me with TextView and how to address them (as I am sure I will still use lots of textViews in the future...) – Franc Jun 22 '18 at 15:15
  • `inputAccessoryView` is meant for this purpose, give it a shot see if it meets your needs, if it doesn't then try a custom solution. You got to taste the pudding yourself ;) – user1046037 Jun 22 '18 at 15:34

0 Answers0