0

I am encountering a strange behaviour when using UITextView with a long text. In particular, when setting the maximumNumberOfLines of its textContainer to 0, the content disappears completely.

I have created a small test project to be sure there was nothing strange in my code that was causing it, and you can see it in the screenshots. In my project I have a UIViewController that contains a UIScrollView, that contains a vertical UIStackView. The stack view contains a UITextView (the red title in the screenshots), another stackview containing a label, text view, button, and then other text views.

When the button is clicked I am setting maximumNumberOfLines to 0 (before it was 2), and the content just disappears. I've tried with and without animation and I have the same result. The disappearing seems to be related to the height of the final text, as if I use a smaller font, the content disappears only after setting much more text.

Any ideas why it could be happening?

For completeness, I am using Xamarin.iOS, and here is my ViewController.

Before

After

papafe
  • 2,959
  • 4
  • 41
  • 72
  • Are you setting a Height constraint on your text view? If not, do you have scrolling disabled? – DonMag Apr 24 '18 at 12:17
  • @DonMag Scrolling is disabled, no height constraint on the text view. – papafe Apr 24 '18 at 12:22
  • Hmmm... sounds like you have it set up correctly... you said you *"created a small test project"* --- can you share that project? – DonMag Apr 24 '18 at 12:23
  • @DonMag I have edited my question and added a link to a paste of my view controller at the end of my question. And I realised I forgot to say I'm using Xamarin. Nevertheless I suppose it's not too easy to understand. And sorry for the not so clear and nice code, but it was just for a test ;) – papafe Apr 24 '18 at 12:49
  • Are you using `UITextView` instead of `UILabel` because you need it to be editable at some point? – DonMag Apr 24 '18 at 13:38
  • @DonMag No, it will never be editable, but the text view seems to be more appropriate because it should be the most appropriate to display large amounts of text – papafe Apr 24 '18 at 13:44
  • 1
    `UITextView` would only be more appropriate if it was going to be editable, or scrollable. Since you're doing neither, I'd suggest going with labels. It would simplify things quite a bit, since you can set the `.numberOfLines` directly on the label, instead of dealing with `NSTextStorage` / `NSLayoutManager` / `NSTextContainer` (which may be the root of the issue anyway). – DonMag Apr 24 '18 at 14:34

1 Answers1

3

The Content disappears because your text is too large for a UIView object to show. According to this post we know that, actually UIView has a maximum height and width limited by the amount of memory they consume.

In my test if we don't set too much characters to the textView(remove some textView.Text += textView.Text;), the content will show. And I also tested that on UILabel, so does it. Because they all inherit from UIView.

If you do want to show so many strings, try to enable the textView's ScrollEnabled. Do not let the textView's Bounds exceed the maximum limit. You can try to add the Height and Width Constraints when you want to expand the textView:

var textViewContraints = new NSLayoutConstraint[]
{
    NSLayoutConstraint.Create(textView, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1f, 700),
    NSLayoutConstraint.Create(textView, NSLayoutAttribute.Width, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1f, 500)
};

UIView.AnimateNotify(1.2d, () =>
{
    if (!buttonExpanded)
    {
        textView.ScrollEnabled = true;
        textView.TextContainer.MaximumNumberOfLines = 0;
        textView.TextContainer.LineBreakMode = UILineBreakMode.WordWrap;
        textView.SizeToFit();
        textView.AddConstraints(textViewContraints);
        expandButton.Transform = CGAffineTransform.MakeRotation((nfloat)(Math.PI / 2.0f));

        textView.Text = "r" + textStr;
        textView.Text = textView.Text.Substring(1);
    }
    else
    {
        textView.ScrollEnabled = false;
        foreach (NSLayoutConstraint constraint in textView.Constraints)
        {
            textView.RemoveConstraint(constraint);
        }
        textView.TextContainer.MaximumNumberOfLines = 3;
        textView.TextContainer.LineBreakMode = UILineBreakMode.WordWrap;
        expandButton.Transform = CGAffineTransform.MakeRotation(0f);

        textView.Text = textStr;
    }

    scrollView.LayoutIfNeeded();
    buttonExpanded = !buttonExpanded;
}, null);
Ax1le
  • 6,563
  • 2
  • 14
  • 61