基于Telegram二次開發(fā) --- Node 篇

Telegram 使用的核心 Node

image.png
  • 帶箭頭的邊框:右邊的 Node 是左邊 Node 的子類;
  • 無箭頭的邊框:相同級別,且與最左側(cè) Node 繼承同一個父類;

1、 --- Text ---

TextNode、ImmediateTextNodeASTextNode 負責(zé)文本渲染。

public class TextNode: ASDisplayNode {
    public internal(set) var cachedLayout: TextNodeLayout?
    
    public static func asyncLayout(_ maybeNode: TextNode?) -> (TextNodeLayoutArguments) -> (TextNodeLayout, () -> TextNode)
}

public class ImmediateTextNode: TextNode {
    public var attributedText: NSAttributedString?
    public var textAlignment: NSTextAlignment = .natural
    public var truncationType: CTLineTruncationType = .end
    public var maximumNumberOfLines: Int = 1
    public var lineSpacing: CGFloat = 0.0
    public var insets: UIEdgeInsets = UIEdgeInsets()
    public var textShadowColor: UIColor?
    public var textStroke: (UIColor, CGFloat)?
    public var cutout: TextNodeCutout?
    public var truncationMode: NSLineBreakMode
    public var linkHighlightColor: UIColor?
    public var trailingLineWidth: CGFloat?
    public var highlightAttributeAction: (([NSAttributedString.Key: Any]) -> NSAttributedString.Key?)?
    public var tapAttributeAction: (([NSAttributedString.Key: Any], Int) -> Void)?
    public var longTapAttributeAction: (([NSAttributedString.Key: Any], Int) -> Void)?
    ...
}

public class ASTextNode: ImmediateTextNode {
    override public var attributedText: NSAttributedString? {
        didSet {
            self.setNeedsLayout()
        }
    }
    ...
}
  • TextNode 利用 CoreText 渲染 NSAttributedString ;
    它有一個基于 row 計算出文本布局的方法 calculateLayout ,并重寫父類方法 draw 來渲染文本;
    公開方法 asyncLayout 被用來異步調(diào)用布局計算并緩存計算結(jié)果,該方法是被設(shè)計來供上一級調(diào)用的,不然,它將不會呈現(xiàn)任何內(nèi)容,因為緩存的布局為 nil ;
    支持 RTL(維語,阿拉伯語等從右到左顯示) 和 Accessibility(視障服務(wù)功能);
  • ImmediateTextNode 通過聲明更多屬性來控制文本布局樣式使得 TextNode 更加豐富,它還支持高亮顯示和點擊事件。
  • ASTextNode 只需設(shè)置 attributedText 屬性就能更新布局,雖然和 AsyncDisplayKit 里的 node 名字一樣但并不是同一個。
  • EditableTextNode 擴展 ASEditableTextNode 用來檢測 RTL 輸入。

2、 --- Image ---

open class ASImageNode: ASDisplayNode {
    public var image: UIImage?
}

public class ImageNode: ASDisplayNode {
    public func setSignal(_ signal: Signal<UIImage?, NoError>)
}

open class TransformImageNode: ASDisplayNode {
    public var imageUpdated: ((UIImage?) -> Void)?
    public var contentAnimations: TransformImageNodeContentAnimations = []
    
    public func setSignal(_ signal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>, attemptSynchronously: Bool = false, dispatchOnDisplayLink: Bool = true)
    public func setOverlayColor(_ color: UIColor?, animated: Bool)
}
  • ASImageNode 渲染 UIImage 并使用圖片的 Size 作為自己的 Size;同樣,它和 AsyncDisplayKit 里的 Node 并不是同一個。
  • ImageNode 接收一個 Signal 來異步顯示圖片;僅在 AvatarNode 使用。
  • TransformImageNode 是異步加載圖片使用最多的類;它支持在更改圖片時使用 alpha 動畫,并支持顏色疊加。

3、 --- Button ---

open class ASButtonNode: ASControlNode {
    public let titleNode: ImmediateTextNode
    public let highlightedTitleNode: ImmediateTextNode
    public let disabledTitleNode: ImmediateTextNode
    public let imageNode: ASImageNode
    public let highlightedImageNode: ASImageNode
    public let selectedImageNode: ASImageNode
    public let highlightedSelectedImageNode: ASImageNode
    public let disabledImageNode: ASImageNode
    public let backgroundImageNode: ASImageNode
    public let highlightedBackgroundImageNode: ASImageNode
}

open class HighlightTrackingButtonNode: ASButtonNode {
   public var highligthedChanged: (Bool) -> Void = { _ in }
}

open class HighlightableButtonNode: HighlightTrackingButtonNode {
   ...
}
  • ASButtonNode 圖片和標(biāo)題組成 ,共有四個狀態(tài):normal、 highlighted、selected、disabled。
  • HighlightableButtonNode 在點擊按鈕時添加高亮動畫。

4、 --- Status ---

5、 --- Media ---

Telegram 使用了很多組件來支持不同的媒體類型,這里僅僅簡單說明;

  • MediaPlayNodeMediaPlayer 的子類,用于在 AVSampleBufferDisplayLayer 上渲染視頻幀。
  • WebEmbedPlayerNode 通過 WKWebView 播放嵌入網(wǎng)頁的視頻;它支持來自Youtube、Vimeo、Twitch等的視頻。
  • AnimatedStickerNode 用于播放來自 AnimatedStickerNodeSource 的動畫。

6、 --- Bar ---

7、 --- List ---

  • ListView 是為可滑動列表設(shè)計的最復(fù)雜的node類之一;它利用隱藏的 UIScrollView 并借用其 pan 手勢來獲得滾動行為;除了管理 Listitems (無論大小) 的可見性以外,還提供其他簡便功能,如 item headers 、可自定義的 scroll indicators記錄 item 、滾動節(jié)點捕捉邊界 等。
  • GridNode 是另一個用于網(wǎng)格布局的滾動UI組件;它支持貼紙選擇,墻紙設(shè)置等功能。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容