2

I have added a view to my tableView header consisting of an imageView and a textView. The image view is left aligned in the top corner and the textview extends over the imageview to the right side of the screen like as follows.

references image

The textView can have dynamic content and has an exclusion path set as follows:

let imagePath = UIBezierPath(rect: imageView.frame)
self.textView.textContainer.exclusionPaths = [imagePath]

I have disabled scrolling for the textview and have set the following constraints inside of the header view:

TextView: left - 8px, right - 8px, top - 0px, bottom - 8px

ImageView: left - 8px, width - 100px, height 100px, top - 8px, bottom - greater than or equal to 8px

I have added this code after my textView is populated with the dynamic text:

if let headerView = self.tableView.tableHeaderView {
    let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
    var headerFrame = headerView.frame

    if height != headerFrame.size.height {
        headerFrame.size.height = height
        headerView.frame = headerFrame
        self.tableView.tableHeaderView = headerView
    }
}

Which adjusts the size of the header. However, when the textView has less text than the height of the image, the size of the view grows.

Example of three lines of text: enter image description here

Example of six lines of text: enter image description here

Example of enough text to pass imageview: enter image description here

Does anyone know why this is happening?

havak5
  • 714
  • 1
  • 6
  • 20

3 Answers3

7

I have a fix for this, because I just encountered this issue myself :) You see, I was trying to do something very similar, where a UITextView's text should avoid a UIImageView to its left. My code was the following:

let ticketProfileExclusionPath = UIBezierPath(roundedRect: ticketProfilePicture.frame, cornerRadius: Constants.ProfilePictureExclusionRadius)
ticketContent.textContainer.exclusionPaths.append(ticketProfileExclusionPath)

And my results were not very good:

enter image description here

As you can see, the problem relies on the CGRect given to the ticketContent UITextView as its exclusion path, since the latter assumes the given CGRect is corrected to its own frame, not its superview's.

The fix is very simple and requires the use of an API present since the dawn of time (iOS 2.0):

let exclusionPathFrame = convert(ticketProfilePicture.frame, to: ticketContent).offsetBy(dx: Constants.SystemMargin, dy: Constants.Zero)

What we're doing here is converting the UIImageView's frame to the UITextView's coordinate system, therefore providing the correct exclusion path from the perspective of the UITextView. The added offset is simply to align all three of my UITableViewCell's text UIViews.

convert() is a UIView method.

enter image description here

As you can see, the text now wraps around the ticketProfilePicture UIImageView quite nicely.

Hope this helps.

dinesharjani
  • 545
  • 6
  • 14
0

For anyone using Auto Layout, make sure to add the exclusionPathFrame in viewDidLayoutSubviews().

CristianMoisei
  • 2,071
  • 2
  • 22
  • 28
-1
You can calculate textview text height with content size.

let tempTextview = UITextView(frame: CGRect(x: 50, y: 50, width: 120, height: 250))
tempTextview.text = "Dynamic Text"
let height = tempTextview.contentSize.height

Add you extra top and bottom padding to this height. 

height = height + padding 

if imageview.frame.size.height > height 
{
  return imageview.frame.size.height 
}
else
{
   return height 
}
Chanchal Warde
  • 983
  • 5
  • 17
  • This doesnt account for the ignored imageview so it adds extra spacing when near the end of the line – havak5 Feb 01 '17 at 19:38