iosobjective-ctextkitnstextattachment

Change NSTextAttachment image don't work immediately even in main queue


I use NSTextAttachment to Display a placeholder image . when click this image , I want to show another image. I do this in UItextView delegate method :

-(BOOL)textView:(UITextView *)textView shouldInteractWithTextAttachment:(NSTextAttachment *)textAttachment inRange:(NSRange)characterRange

I encounter below problems: tap(click) image and already go into delegate method, but the image don't change immediately. I try change image in main queue and call setNeedsDisplay,But it still not work. Please help :)

Here is my main code:

viewDidLoad:

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:@"This is an example by @marcelofabri_"];

[attributedString addAttribute:NSLinkAttributeName
                         value:@"username://marcelofabri_"
                         range:[[attributedString string] rangeOfString:@"@marcelofabri_"]];

//first image
NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
textAttachment.image = [UIImage imageNamed:@"sample_image.png"];
NSAttributedString *attrStringWithImage = [NSAttributedString attributedStringWithAttachment:textAttachment];

[attributedString appendAttributedString:attrStringWithImage];

self.textView.attributedText = attributedString;
self.textView.delegate = self;
self.textView.editable = NO;

UITextView Delegate method

-(BOOL)textView:(UITextView *)textView shouldInteractWithTextAttachment:(NSTextAttachment *)textAttachment inRange:(NSRange)characterRange{
UIImage *image  = textAttachment.image;

NSLog(@"width:%f , height:%f",image.size.width,image.size.height);
//change second image
  dispatch_async(dispatch_get_main_queue(), ^{                      

    textAttachment.image = [UIImage imageNamed:@"sample_image_1"];        
    [_textView setNeedsDisplay];
});

return true;
}

Thanks for help :)


Solution

  • after some digging, I found textview can redrawing image by invalidating the layout manager

    [textView.layoutManager invalidateDisplayForCharacterRange:characterRange];