mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
Various improvements
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
|
||||
public class CompositeTextNode: ASDisplayNode {
|
||||
public enum Component: Equatable {
|
||||
case text(NSAttributedString)
|
||||
case icon(UIImage)
|
||||
}
|
||||
|
||||
public var components: [Component] = []
|
||||
|
||||
private var textNodes: [Int: ImmediateTextNode] = [:]
|
||||
private var iconViews: [Int: UIImageView] = [:]
|
||||
|
||||
public var imageTintColor: UIColor? {
|
||||
didSet {
|
||||
for (_, textNode) in self.textNodes {
|
||||
textNode.layer.layerTintColor = self.imageTintColor?.cgColor
|
||||
}
|
||||
for (_, iconView) in self.iconViews {
|
||||
iconView.tintColor = self.imageTintColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func update(constrainedSize: CGSize) -> CGSize {
|
||||
var validTextIds: [Int] = []
|
||||
var validIconIds: [Int] = []
|
||||
|
||||
var size = CGSize()
|
||||
|
||||
var nextTextId = 0
|
||||
var nextIconId = 0
|
||||
for component in self.components {
|
||||
switch component {
|
||||
case let .text(text):
|
||||
let id = nextTextId
|
||||
nextTextId += 1
|
||||
validTextIds.append(id)
|
||||
|
||||
let textNode: ImmediateTextNode
|
||||
if let current = self.textNodes[id] {
|
||||
textNode = current
|
||||
} else {
|
||||
textNode = ImmediateTextNode()
|
||||
textNode.maximumNumberOfLines = 1
|
||||
textNode.insets = UIEdgeInsets(top: 3.0, left: 0.0, bottom: 3.0, right: 0.0)
|
||||
textNode.layer.layerTintColor = self.imageTintColor?.cgColor
|
||||
self.textNodes[id] = textNode
|
||||
self.addSubnode(textNode)
|
||||
}
|
||||
textNode.attributedText = text
|
||||
|
||||
let textSize = textNode.updateLayout(CGSize(width: max(1.0, constrainedSize.width - size.width), height: constrainedSize.height))
|
||||
|
||||
textNode.frame = CGRect(origin: CGPoint(x: size.width - textNode.insets.left, y: -textNode.insets.top), size: textSize)
|
||||
size.width += textSize.width - textNode.insets.left - textNode.insets.right
|
||||
size.height = max(size.height, textSize.height - textNode.insets.top - textNode.insets.bottom)
|
||||
case let .icon(icon):
|
||||
let id = nextIconId
|
||||
nextIconId += 1
|
||||
validIconIds.append(id)
|
||||
|
||||
let iconView: UIImageView
|
||||
if let current = self.iconViews[id] {
|
||||
iconView = current
|
||||
} else {
|
||||
iconView = UIImageView()
|
||||
self.iconViews[id] = iconView
|
||||
self.view.addSubview(iconView)
|
||||
}
|
||||
iconView.image = icon
|
||||
iconView.tintColor = self.imageTintColor
|
||||
|
||||
let iconSize = icon.size
|
||||
if size.width != 0.0 {
|
||||
size.width += 3.0
|
||||
}
|
||||
iconView.frame = CGRect(origin: CGPoint(x: size.width, y: 3.0 + UIScreenPixel), size: iconSize)
|
||||
size.width += iconSize.width
|
||||
size.width += 3.0
|
||||
size.height = max(size.height, iconSize.height)
|
||||
}
|
||||
|
||||
if size.width >= constrainedSize.width {
|
||||
size.width = constrainedSize.width
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var removeTextIds: [Int] = []
|
||||
for (id, textNode) in self.textNodes {
|
||||
if !validTextIds.contains(id) {
|
||||
textNode.removeFromSupernode()
|
||||
removeTextIds.append(id)
|
||||
}
|
||||
}
|
||||
for id in removeTextIds {
|
||||
self.textNodes.removeValue(forKey: id)
|
||||
}
|
||||
|
||||
var removeIconIds: [Int] = []
|
||||
for (id, iconView) in self.iconViews {
|
||||
if !validIconIds.contains(id) {
|
||||
iconView.removeFromSuperview()
|
||||
removeIconIds.append(id)
|
||||
}
|
||||
}
|
||||
for id in removeIconIds {
|
||||
self.iconViews.removeValue(forKey: id)
|
||||
}
|
||||
|
||||
return size
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user