Text Kit not word-wrapping first/last lines in UITextView

When using an exclusion path with an UITextView, the text view is not properly wrapping the words for the first and last line in the example shown (lower text). It does render properly using word-wrap with Core Text (top example).


(Hmm - the image link I provided in the HTML here works with the preview, but not the post. The example image is at: http i.stack.imgur.com/Z91ge.png



Here is the code for the UITextView (both this and the Core Text example use the same size bezier path, and both use the appropriate corresponding font and paragraph settings; wrap by word and centered):

NSString *testText = @"Text Kit exclusion paths ..."; /
UIBezierPath *viewPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 280, 280)];
UIBezierPath *shapePath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(10, 10, 265, 265)];

viewPath.usesEvenOddFillRule = true;
shapePath.usesEvenOddFillRule = true;
[shapePath appendPath:viewPath];

NSMutableAttributedString *title = [[NSMutableAttributedString alloc]initWithString:testText];
UIFont *font = [UIFont fontWithName:@"BradleyHandITCTT-Bold" size:14];

[title addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, title.length)];
[title addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, title.length)];

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setAlignment:NSTextAlignmentCenter];
[paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping];
[title addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, title.length)];

UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(0.0, 370.0, 280, 280)];
textView.textContainerInset = UIEdgeInsetsMake(0,0,0,0);
textView.textContainer.exclusionPaths = @[shapePath];
[textView.textContainer setLineBreakMode:NSLineBreakByWordWrapping];
textView.contentInset = UIEdgeInsetsMake(0,0,0,0);
textView.attributedText = title;
textView.backgroundColor = [UIColor clearColor];


It is worth noting that the Text Kit is respecting the word wrapping rules except for the first and (possibly last) line where the text does not actually fit. I need this to work with a UITextView because text entry is required, or I would be done with my Core Text example.


I have tried everything I can think of to reliably work-around the issue. I don't fully understand how UITextView is working with Core Text (or I would expect to get the same results which I don’t), so any suggestions would be greatly appreciated.

Replies

Note that the simplest way to demonstrate the issue is by downloading Apple’s IntroToTextKitDemo2013 sample code and add the following lines to viewDidLoad and viewDidLayoutSubviews in TKDExclusionPathsViewController.m in place of the following line. I aplogize for not being more concise to begin with.

  self.textView.textContainer.exclusionPaths = @[[self translatedBezierPath]];


Replace that line with:

  UIBezierPath *viewPath =  [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.width)];
  UIBezierPath *shapePath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(20, 20, self.view.frame.size.width - 40, self.view.frame.size.width - 40)];
  viewPath.usesEvenOddFillRule = true;
  shapePath.usesEvenOddFillRule = true;
  [shapePath appendPath:viewPath];
  self.textView.textContainer.exclusionPaths = @[shapePath];

Sumbitted to Apple Radar: ticket 24748182.

I'm also facing this issue. Is there any workaround available?