Newlines in iOS 7 UITextView breaking Text Kit exc

2020-02-09 15:12发布

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?

1条回答
闹够了就滚
2楼-- · 2020-02-09 15:53

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;
查看更多
登录 后发表回答