Search code examples
swiftdtcoretext

How to show image inline with html in DTCoreText in Swift 3


I have DTAttributedTextContentView, where i sucessfully render text from HTML. Now i want to embed a picture shown inline with text. I looked through documentation and there is only Objective-C examples. How to do same on Swift:

The best way to display remote images is to use DTLazyImageView. First you will need to return DTLazyImageView instance for your image attachments.

- (UIView *)attributedTextContentView:(DTAttributedTextContentView *)attributedTextContentView viewForAttachment:(DTTextAttachment *)attachment frame:(CGRect)frame
{
    if([attachment isKindOfClass:[DTImageTextAttachment class]])
     {
        DTLazyImageView *imageView = [[DTLazyImageView alloc] initWithFrame:frame];
        imageView.delegate = self;

        // url for deferred loading
        imageView.url = attachment.contentURL;
        return imageView;
    }
    return nil;
}

Then in the in delegate method for DTLazyImageView reset the layout for the affected DTAttributedContextView.

- (void)lazyImageView:(DTLazyImageView *)lazyImageView didChangeImageSize:(CGSize)size 
{
    NSURL *url = lazyImageView.url;
    NSPredicate *pred = [NSPredicate predicateWithFormat:@"contentURL == %@", url];

    // update all attachments that matching this URL
    for (DTTextAttachment *oneAttachment in [self.attributedTextContentView.layoutFrame textAttachmentsWithPredicate:pred]) 
     {
        oneAttachment.originalSize = size;
    }

    // need to reset the layouter because otherwise we get the old framesetter or cached layout frames
    self.attributedTextContentView.layouter = nil;

    // here we're layouting the entire string,
    // might be more efficient to only relayout the paragraphs that contain these attachments
    [self.attributedTextContentView relayoutText];
}

similar question is here


Solution

  • I've rewrote this to Swift 3 syntax at the end:

      @IBOutlet weak var textLabel: DTAttributedTextContentView!
    
    
            func attributedTextContentView(viewForAttachment: DTAttributedTextContentView, attachment: DTTextAttachment, frame: CGRect) -> UIView {
                if attachment is DTImageTextAttachment {
                    let imageView = DTLazyImageView(frame: frame)
                    imageView.delegate = self as! DTLazyImageViewDelegate
                    // url for deferred loading
                    imageView.url = attachment.contentURL
                    return imageView
                }
                return UIView(frame: CGRect.zero)
            }
    
            func lazyImageView(lazyImageView: DTLazyImageView, didChangeImageSize: CGSize) {
                guard let url = lazyImageView.url else {return}
                let pred = NSPredicate(format: "contentURL == %@", url as CVarArg)
    
                let array = textLabel.layoutFrame.textAttachments(with: pred)
    
    
    
                for (_, _) in (array?.enumerated())! {
                    let element = DTTextAttachment()
                    element.originalSize = didChangeImageSize
                }
    
                textLabel.layouter = nil
                textLabel.relayoutText()
            }