metatext/Views/UIKit/AnimatingLayoutManager.swift

55 lines
2 KiB
Swift
Raw Normal View History

2021-02-22 07:10:34 +00:00
// Copyright © 2021 Metabolist. All rights reserved.
2021-02-22 23:59:33 +00:00
import SDWebImage
2021-02-22 07:10:34 +00:00
import UIKit
final class AnimatingLayoutManager: NSLayoutManager {
weak var view: UIView?
override func drawGlyphs(forGlyphRange glyphsToShow: NSRange, at origin: CGPoint) {
guard let textStorage = textStorage else {
super.drawGlyphs(forGlyphRange: glyphsToShow, at: origin)
return
}
2021-02-22 23:59:33 +00:00
var attachmentImageViews = Set<SDAnimatedImageView>()
2021-02-22 07:10:34 +00:00
textStorage.enumerateAttribute(
.attachment,
in: NSRange(location: 0, length: textStorage.length)) { attachment, _, _ in
guard let attachmentImageView = (attachment as? AnimatedTextAttachment)?.imageView else { return }
attachmentImageViews.insert(attachmentImageView)
}
for subview in view?.subviews ?? [] {
2021-02-22 23:59:33 +00:00
guard let attachmentImageView = subview as? SDAnimatedImageView else { continue }
2021-02-22 07:10:34 +00:00
if !attachmentImageViews.contains(attachmentImageView) {
attachmentImageView.removeFromSuperview()
}
}
textStorage.enumerateAttribute(
.attachment,
in: glyphsToShow,
options: .longestEffectiveRangeNotRequired) { attachment, range, _ in
guard let animatedAttachment = attachment as? AnimatedTextAttachment,
let textContainer = textContainer(forGlyphAt: range.location, effectiveRange: nil)
else { return }
animatedAttachment.imageView.frame = boundingRect(forGlyphRange: range, in: textContainer)
animatedAttachment.imageView.image = animatedAttachment.image
animatedAttachment.imageView.contentMode = .scaleAspectFit
2021-02-22 23:59:33 +00:00
animatedAttachment.imageView.sd_setImage(with: animatedAttachment.imageURL)
2021-02-22 07:10:34 +00:00
if animatedAttachment.imageView.superview != view {
view?.addSubview(animatedAttachment.imageView)
}
}
super.drawGlyphs(forGlyphRange: glyphsToShow, at: origin)
}
}