Skip to content

Commit

Permalink
优化附件的加载,提升加载效率
Browse files Browse the repository at this point in the history
  • Loading branch information
rztime committed Nov 11, 2024
1 parent d2b467e commit 62b6a73
Show file tree
Hide file tree
Showing 10 changed files with 333 additions and 270 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 14 additions & 21 deletions RZRichTextView/Classes/LabelRZRich.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
//

import UIKit
import Kingfisher
import QuicklySwift

public extension UILabel {
Expand Down Expand Up @@ -45,9 +44,7 @@ public extension UILabel {
func fix(attachment: NSTextAttachment, range: NSRange) {
if let info = attachment.rzattachmentInfo, let image = info.image {
attachment.image = image
var bounds = attachment.bounds
bounds.size = image.size.qscaleto(maxWidth: bounds.width)
attachment.bounds = bounds
attachment.bounds = .init(origin: .zero, size: image.size)
}
/// 此时富文本如果没有赋值到Label中,表示还在设置Attr
guard let attr = self.attributedText else {
Expand All @@ -57,35 +54,31 @@ public extension UILabel {
return
}
let temp = NSMutableAttributedString(attributedString: attr)
let attach = NSMutableAttributedString(attachment: attachment)
attach.addAttributes(temp.attributes(at: range.location, effectiveRange: nil), range: .init(location: 0, length: attach.length))
temp.addAttribute(.attachment, value: attachment, range: range)
if needPreView {
attach.addAttributes([.rztapLabel: "\(attachment)"], range: .init(location: 0, length: 1))
temp.addAttributes([.rztapLabel: "\(attachment)"], range: .init(location: 0, length: 1))
}
temp.replaceCharacters(in: range, with: attach)
self.attributedText = temp
sizeChanged?()
}
let ats = attr.rt.attachments()
let configure = RZRichTextViewConfigure.shared
for at in ats {
if let info = at.0.rzattachmentInfo {
/// 如果本地已经加载过图片了,则不需要异步即可实现富文本
switch info.type {
case .image, .video:
let url = info.poster?.qtoURL ?? info.src?.qtoURL
if let c = RZRichTextViewConfigure.shared.async_imageBy {
let complete: ((String?, UIImage?) -> Void)? = { [weak info] source, image in
info?.image = image
info?.image = UILabel.creatAttachmentInfoView(info, width: max)
fix(attachment: at.0, range: at.1)
}
let complete: ((String?, UIImage?) -> Void)? = { [weak info] source, image in
info?.image = image
let realWidth = (image?.size.width ?? max) + configure.imageViewEdgeInsetsNormal.left + configure.imageViewEdgeInsetsNormal.right
info?.image = UILabel.creatAttachmentInfoView(info, width: min(realWidth, max))
fix(attachment: at.0, range: at.1)
}
if let _ = info.image {
complete?("", info.image)
} else if let c = configure.async_imageBy {
let url = info.poster?.qtoURL ?? info.src?.qtoURL
c(url?.absoluteString, complete)
} else {
UIImage.asyncImageBy(url?.absoluteString) { [weak info] image in
info?.image = image
info?.image = UILabel.creatAttachmentInfoView(info, width: max)
fix(attachment: at.0, range: at.1)
}
}
case .audio:
info.image = UILabel.creatAttachmentInfoView(info, width: max)
Expand Down
7 changes: 5 additions & 2 deletions RZRichTextView/Classes/RZAttachmentInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,17 @@ public extension NSTextAttachment {
class func createWithinfo(_ info: RZAttachmentInfo) -> Self {
let attachment = Self.init()
attachment.rzattachmentInfo = info
let color = RZRichTextViewConfigure.shared.backgroundColor
switch info.type {
case .image, .video:
let size = (info.image?.size ?? .init(width: 1, height: 1)).qscaleto(maxWidth: info.maxWidth)
attachment.image = UIColor.clear.qtoImage(size)
attachment.image = color.qtoImage(size)
attachment.bounds = .init(origin: .zero, size: size)
break
case .audio:
let size = CGSize.init(width: info.maxWidth, height: info.audioViewHeight)
attachment.image = UIColor.clear.qtoImage(size)
attachment.image = color.qtoImage(size)
attachment.bounds = .init(origin: .zero, size: size)
break
}
return attachment
Expand Down
59 changes: 24 additions & 35 deletions RZRichTextView/Classes/RZAttachmentInfoLayerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

import UIKit
import QuicklySwift
import Kingfisher
import Photos
import Kingfisher
/// 操作
public enum RZAttachmentOperation {
case none
Expand All @@ -30,8 +30,6 @@ public protocol RZAttachmentInfoLayerProtocol: NSObjectProtocol {
var dispose: NSObject {get set}
/// 显示音频文件名 默认true
var showAudioName: Bool {get set}
/// 图片或者音频view上下左右边距
var imageViewEdgeInsets: UIEdgeInsets { get }
}
open class RZAttachmentInfoLayerView: UIView, RZAttachmentInfoLayerProtocol {
public var operation: QuicklySwift.QPublish<RZAttachmentOperation> = .init(value: .none)
Expand All @@ -45,51 +43,42 @@ open class RZAttachmentInfoLayerView: UIView, RZAttachmentInfoLayerProtocol {
audioContent.isHidden = info.type != .audio
self.playBtn.isHidden = info.type != .video
switch info.type {
case .image:
case .image, .video:
if let asset = info.asset {
let option = PHImageRequestOptions.init()
option.isNetworkAccessAllowed = true
option.resizeMode = .fast
option.deliveryMode = .highQualityFormat
PHImageManager.default().requestImageData(for: asset, options: option) { [weak self] data, _, _, _ in
if let imageData = data {
self?.imageView.kf.setImage(with: .provider(RawImageDataProvider(data: imageData, cacheKey: asset.localIdentifier))) { [weak self] _ in
self?.imageView.kf.setImage(with: .provider(RawImageDataProvider(data: imageData, cacheKey: asset.localIdentifier))) { _ in
self?.updateImageViewSize()
}
}
}
} else if let url = info.src {
} else if let image = info.image {
self.imageView.image = image
self.updateImageViewSize()
} else if let url = (info.poster ?? info.src) {
if let c = RZRichTextViewConfigure.shared.async_imageBy {
let complete: ((String?, UIImage?) -> Void)? = { [weak self] source, image in
self?.imageView.image = image
self?.updateImageViewSize()
}
c(url, complete)
} else {
self.imageView.kf.setImage(with: url.qtoURL, completionHandler: { [weak self] _ in
self?.updateImageViewSize()
})
}
}
} else {
info.imagePublish.subscribe({ [weak self] value in
guard let self = self else { return }
self.imageView.image = value
self.updateImageViewSize()
}, disposebag: dispose)
}
case .video:
info.imagePublish.subscribe({ [weak self] value in
guard let self = self else { return }
self.imageView.image = value
self.updateImageViewSize()
}, disposebag: dispose)
case .audio:
if let path = info.path ?? info.src {
self.nameLabel.text = path.qtoURL?.lastPathComponent
}
}
self.layoutIfNeeded()

info.uploadStatus.subscribe({ [weak self] value in
switch value {
case .idle:
Expand All @@ -116,6 +105,11 @@ open class RZAttachmentInfoLayerView: UIView, RZAttachmentInfoLayerProtocol {
public var canEdit: Bool = true {
didSet {
contentView.isHidden = !canEdit
let c = RZRichTextViewConfigure.shared
let inset = canEdit ? c.imageViewEdgeInsets : c.imageViewEdgeInsetsNormal
stackView.snp.updateConstraints { make in
make.left.top.right.bottom.equalToSuperview().inset(inset)
}
}
}
public var showAudioName: Bool = true {
Expand All @@ -125,7 +119,8 @@ open class RZAttachmentInfoLayerView: UIView, RZAttachmentInfoLayerProtocol {
}
/// 图片视频相关view
// 显示的图片
public var imageView: UIImageView = AnimatedImageView.init().qcontentMode(.scaleAspectFit).qcornerRadius(3, true)
public var imageView: UIImageView = AnimatedImageView().qcontentMode(.scaleAspectFit).qcornerRadius(3, true)
.qimage(RZRichTextViewConfigure.shared.loadingImage)
/// 播放按钮
var playBtn: UIButton = .init(type: .custom).qimage(RZRichImage.imageWith("play")).qisUserInteractionEnabled(false)

Expand All @@ -151,34 +146,29 @@ open class RZAttachmentInfoLayerView: UIView, RZAttachmentInfoLayerProtocol {
let contentView: UIView = .init()

public var dispose: NSObject = .init()
/// 图片或者音频view上下左右边距
public var imageViewEdgeInsets: UIEdgeInsets {
return .init(top: 15, left: 3, bottom: 0, right: 15)
}
/// 0.0-1.0
public func updateProgress(_ progress: CGFloat) {
var bounds = self.progressView.bounds
bounds.origin.x = bounds.size.width - bounds.size.width * progress
self.progressView.bounds = bounds
}

lazy var stackView = [imageContent, audioContent].qjoined(aixs: .vertical, spacing: 0, align: .fill, distribution: .equalSpacing)
public override init(frame: CGRect) {
super.init(frame: frame)
/// 测试用
// self.backgroundColor = RZRichTextViewConfigure.shared.backgroundColor
audioPlayBtn.imageView?.contentMode = .scaleAspectFit
let stackView = [imageContent, audioContent].qjoined(aixs: .vertical, spacing: 0, align: .fill, distribution: .equalSpacing)
self.qbody([
stackView.qmakeConstraints({ make in
make.left.equalToSuperview().inset(3)
make.top.right.equalToSuperview().inset(15)
make.bottom.lessThanOrEqualToSuperview()
make.left.right.top.bottom.equalToSuperview().inset(RZRichTextViewConfigure.shared.imageViewEdgeInsetsNormal)
}),
contentView.qmakeConstraints({ make in
make.edges.equalToSuperview()
})
])
contentView.qbody([
infoLabel.qmakeConstraints({ make in
make.left.bottom.right.equalTo(stackView)
make.left.bottom.right.equalToSuperview()
make.height.equalTo(18)
}),
progressView.qmakeConstraints({ make in
Expand All @@ -192,8 +182,8 @@ open class RZAttachmentInfoLayerView: UIView, RZAttachmentInfoLayerProtocol {
])
imageContent.qbody([
imageView.qmakeConstraints({ make in
make.top.left.right.equalToSuperview()
make.bottom.lessThanOrEqualToSuperview()
make.top.left.bottom.right.equalToSuperview()
make.width.lessThanOrEqualToSuperview()
}),
playBtn.qmakeConstraints({ make in
make.center.equalToSuperview()
Expand Down Expand Up @@ -252,10 +242,9 @@ open class RZAttachmentInfoLayerView: UIView, RZAttachmentInfoLayerProtocol {
fatalError("init(coder:) has not been implemented")
}
func updateImageViewSize() {
guard let image = self.imageView.image else { return }
let size = image.size
let size = imageView.image?.size ?? (.init(width: 16.0, height: 9.0))
self.imageView.snp.makeConstraints { make in
make.height.equalTo(self.imageView.snp.width).multipliedBy(size.height / size.width)
make.height.equalTo(self.imageView.snp.width).multipliedBy(size.height / size.width).priority(.high)
}
}
}
15 changes: 14 additions & 1 deletion RZRichTextView/Classes/RZCss.swift
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,20 @@ public extension NSMutableParagraphStyle {
public extension [NSAttributedString.Key: Any] {
var rz2cssStyle: String {
var styletexts:[String] = []
self.keys.forEach { key in
/// 用数组固定住,是为了每次生成的css内容顺序一致(为了判断是否有修改内容)
let needCodeKeys: [NSAttributedString.Key] = [
// .paragraphStyle, .strikethroughStyle, .underlineStyle, .attachment, .link, // 外部实现 <p> <s> <u> 附件<图片、音频、视频> <a>
// .ligature, .obliqueness, // 不使用
.font,
.foregroundColor,
.backgroundColor,
.kern,
.strokeWidth,
.shadow,
.baselineOffset,
.expansion,
]
needCodeKeys.forEach { key in
let value = self[key]
switch key {
case .paragraphStyle, .strikethroughStyle, .underlineStyle, .attachment, .link: break // 外部实现 <p> <s> <u> 附件<图片、音频、视频> <a> // 在外部实现
Expand Down
Loading

0 comments on commit 62b6a73

Please sign in to comment.