Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Newlines in iOS 7 UITextView breaking Text Kit exclusion zone wrapping

I'm working with Text Kit in iOS 7 and I'm finding a lot of oddities around NSTextContainer exclusion zones.

I've got two views: a UITextView and a simple draggable UIView; as the UIView moves, I create a bezier path from the UIView's frame (adjusted to within the UITextView's coordinate space) and I update the UITextView's NSTextContainer's exclusionPaths array - pretty straightforward.

In the first screenshot, you can see that Text Kit nicely wraps text around a rectangular exclusion zone:

Exclusion zone with no newlines in text

However, when the user introduces newlines into the UITextView, TextKit seems to think that the exclusion zone is much bigger vertically - by what appears to be exactly as high as the whitespace created by the newline. The bezier path is exactly the same, so this seems to be a Text Kit issue (unless I'm doing something wrong).

Exclusion zone with newlines in text

Code:

ViewController.h:

@interface ViewController : UIViewController<UITextViewDelegate>

@property (nonatomic, strong) IBOutlet UITextView *textView;
@property (nonatomic, strong) IBOutlet UIView *dragView;

@end

ViewController.m:

-(void)viewDidLoad
{
    [super viewDidLoad];

    UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(move:)];
    [panRecognizer setMinimumNumberOfTouches:1];
    [panRecognizer setMaximumNumberOfTouches:1];
    [self.dragView addGestureRecognizer:panRecognizer];

    [self updateExclusionZone];
}

-(void)move:(UIPanGestureRecognizer *)pan
{
    [self.view bringSubviewToFront:[pan view]];

    if ([pan state] == UIGestureRecognizerStateBegan) {
        NSLog(@"pan began");
    }

    self.dragView.center = [pan locationInView:self.view];
    [self updateExclusionZone];

    if ([pan state] == UIGestureRecognizerStateEnded) {
        NSLog(@"pan ended");
    }
}

-(void)updateExclusionZone
{
    CGRect dragViewFrame = self.dragView.frame;
    CGRect exclusionRect = [self.view convertRect:dragViewFrame toView:self.textView];

    UIBezierPath *exclusion = [UIBezierPath bezierPathWithRect:exclusionRect];

    self.textView.textContainer.exclusionPaths = @[exclusion];
}

Any thoughts?

like image 915
Rob Avatar asked Sep 23 '13 15:09

Rob


1 Answers

I ran into the same issue today.

This bug seem to appear, if you set editable and selectable at the same time. If only one or no is selected, it renders as expected. Both are selected by default.

enter image description here
enter image description here

If you need both options, just set them in code.

_textView.textContainer.exclusionPaths = exclusionPaths;
_textView.attributedText = attrString;
_textView.editable = YES;
_textView.selectable = YES;
like image 118
vikingosegundo Avatar answered Nov 20 '22 15:11

vikingosegundo