3

I've already set the properties textContainerInset and lineFragmentPadding to zero as seen on this code thanks to this removing the padding and margin via this SO answer.

// this is inside a UITextView Subclass
required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    self.textContainerInset = .zero
    self.textContainer.lineFragmentPadding = 0
}

Here's how the UITextView renders when it has text

enter image description here

Here it is with multiple lines

enter image description here

Here's how it renders without text

enter image description here

Is it possible to make the height 0 if the UITextView's text is empty?

Edit:

  1. There is no constraint being used on the UITextView and I'm not planning to set a height constraint as I want this UITextView to automatically resize depending on the text being set into it

  2. This is a isScrollEnabled = false UITextView inside a UITableViewCell, which automatically resizes depending on the data fetched from the api server.

About:

Language: Swift 3.2

IDE: Xcode 9.2

Zonily Jame
  • 5,053
  • 3
  • 30
  • 56

5 Answers5

3

Thanks to uhuru's answer I've formulated an answer to the code of mine that wouldn't need too much of an overhaul.

First I've setup a height constraint for the UITextView programatically.

// outside the scope
var contentTextViewConstraint: NSLayoutConstraint?

// inside awakeFromNib
self.contentTextViewConstraint = NSLayoutConstraint(
    item: self.lblContent,
    attribute: NSLayoutAttribute.height,
    relatedBy: NSLayoutRelation.equal,
    toItem: nil,
    attribute: NSLayoutAttribute.notAnAttribute,
    multiplier: 1,
    constant: 0)
self.contentTextViewConstraint?.isActive = false

Then activate/deactivate the constraint depending on the String

// inside the setup
let contentText: String = model.contentText
self.tvContent.text = contentText
self.contentTextViewConstraint?.isActive = contentText.isEmpty
Zonily Jame
  • 5,053
  • 3
  • 30
  • 56
1

You can set two height constraints for the TVw. One with your desired height and the other one with 0 height and less priority.

Then on the TextView's delegate do something like:

func textViewDidChange(_ textView: UITextView) {
    constraint.isActive = textView.text.count != 0
}
0

Try this code:

CGSize sizeThatFitsTextView = [TextView sizeThatFits:CGSizeMake(TextView.frame.size.width, MAXFLOAT)];
TextViewHeightConstraint.constant = sizeThatFitsTextView.height;
iGatiTech
  • 2,306
  • 1
  • 21
  • 45
Sach
  • 69
  • 2
-1

Another possible solution is to add a constraint in InterfaceBuilder for height == 0, set it as isActive == false and give it a custom identifier.

Activate/deactivate it when needed in the code using :

textView.constraints.first { $0.identifier == "theConstrainIdentifier" }?.isActive = false // or true

Alex C
  • 29
  • 1
  • 4
-2

This may be UITextView's bug. Try to follow code:

- (CGSize)intrinsicContentSize {
    CGSize size = [super intrinsicContentSize];
    if ((size.width < FLT_EPSILON || size.height < FLT_EPSILON) && self.textStorage.string.length == 0) {
        return CGSizeZero;
    } else {
        return size;
    }
}
Michael
  • 3,093
  • 7
  • 39
  • 83