Texture基礎(chǔ)篇
一、介紹
Texture原名AsyncDisplayKit,是Facebook的Paper團(tuán)隊(duì)發(fā)布的一個(gè)用于優(yōu)化APP界面流暢度的庫(kù),這個(gè)庫(kù)能夠?qū)D片、布局以及UI渲染操作放在后臺(tái)線程,從而使用戶界面流暢度非常快,從而不會(huì)因界面卡頓而阻止用戶交互。
二、安裝
安裝一般通過(guò)CocoaPods安裝,如果您還不了解CocoaPods,請(qǐng)參考CocoaPods安裝和使用教程, 安裝方式如下:
安裝Podfile配置如下
target 'MyApp' do
pod "Texture"
end
三、基本使用方法
AsyncDisplayKit針對(duì)UIKit的很多控件都定義了對(duì)應(yīng)的封裝,一些常用的控件對(duì)應(yīng)關(guān)系如下
ASDisplayNode? ? ? ? :? UIView
ASTableNode? ? ? ? ? :? UITableView
ASCollectionNode? ? ? :? UICollectionView
ASCellNode? ? ? ? ? ? :? UITableViewCell
ASScrollNode? ? ? ? ? :? UIScrollView
ASEditableTextNode? ? :? UITextView
ASControlNode? ? ? ? :? UIControl
ASButtonNode? ? ? ? ? :? UIButton
ASTextNode? ? ? ? ? ? :? UILabel
ASImageNode? ? ? ? ? :? UIImageView
ASNetworkImageNode? ? :? // 此類用于家中網(wǎng)絡(luò)圖片
1、ASDisplayNode 對(duì)應(yīng) UIView
ASDisplayNode可以說(shuō)是AsyncDisplayKit的核心類,和UIKit中的UIView類似,因?yàn)锳SDisplayNode不存在layer屬性,所以有一些UIView的效果需要通過(guò)layer屬性實(shí)現(xiàn)的ASDisplayNode已經(jīng)存在屬性可以直接設(shè)置,例如設(shè)置圓角,ASDisplayNode可以直接設(shè)置cornerRadius實(shí)現(xiàn)
// 初始化方法
let node: ASDisplayNode = ASDisplayNode.init()
// 一些常用屬性, 例如設(shè)置邊框
node.borderColor = UIColor.lightGray.cgColor
node.borderWidth = 1.0
// AsyncDisplayKit 為 UIView 擴(kuò)展了一個(gè)方法 addSubnode(node: ASDisplayNode)
// 此方法用戶將 ASDisplayNode 添加到 UIView 上面
view.addSubnode(node)
2、ASTableNode 對(duì)應(yīng) UITableView
ASTableNode是使用方法和UITableView使用方法如下
// 初始化
let tableNode: ASTableNode = ASTableNode.init(style: .plain)
// 代理 ASTableDelegate
tableNode.delegate = self
// 數(shù)據(jù)源 ASTableDataSource
tableNode.dataSource = self
// 添加
view.addSubnode(tableNode)
幾個(gè)主要的代理方法實(shí)現(xiàn)如下, 具體的自動(dòng)計(jì)算CellNode的方法稍后會(huì)介紹
// 分組
func numberOfSections(in tableNode: ASTableNode) -> Int {
return 1
}
// 每個(gè)分組Cell個(gè)數(shù)
func tableNode(_ tableNode: ASTableNode, numberOfRowsInSection section: Int) -> Int {
return 0
}
// 配置CellNode
func tableNode(_ tableNode: ASTableNode, nodeBlockForRowAt indexPath: IndexPath) -> ASCellNodeBlock {
return {
return ASCellNode.init()
}
}
// 配置Cell的尺寸, ASNodeCell的具體尺寸需可以自動(dòng)計(jì)算,此處返回一個(gè)醉倒尺寸和最小尺寸,方便自動(dòng)計(jì)算
func tableNode(_ tableNode: ASTableNode, constrainedSizeForRowAt indexPath: IndexPath) -> ASSizeRange {
let minSize = CGSize.init(width: UIScreen.main.bounds.width, height: 10)
let maxSize = CGSize.init(width: UIScreen.main.bounds.width, height: CGFloat(MAXFLOAT))
return ASSizeRange.init(min: minSize, max: maxSize)
}
3、ASTextNode 與 UILabel
ASTextNode 和 UILabel的使用還是有一些區(qū)別的,主要區(qū)別如下
ASTextNode 繼承自 ASControlNode ,也就是說(shuō)可以直接給ASTextNode添加點(diǎn)擊事件, ASControlNode 的和UIControl 類似,但是因?yàn)閁ILabel繼承自UIView, 所以不能直接添加點(diǎn)擊事件
ASTextNode 不能直接設(shè)置 String 類型的文本,必須設(shè)置NSAttributeString作文顯示文本,因?yàn)镹SAttributeString可以設(shè)置字符串屬性,所以 ASTextNode 沒(méi)有直接設(shè)置文本的屬性,例如沒(méi)有 font, textColor 等屬性
基本的使用方法如下
// 配置文本段落屬性
let paragraphStyle = NSMutableParagraphStyle.init()
paragraphStyle.lineSpacing = 5
paragraphStyle.alignment = .center
paragraphStyle.paragraphSpacing = 20
// 裝配文本屬性
let attributes = [
NSFontAttributeName: UIFont.systemFont(ofSize: 20),
NSForegroundColorAttributeName: UIColor.lightGray,
NSParagraphStyleAttributeName: paragraphStyle
]
let textNode: ASTextNode = ASTextNode.init()
// 設(shè)置屬性換字符串
textNode.attributedText = NSAttributedString.init(string: "您好, 我是一個(gè)程序員", attributes: attributes)
textNode.frame = view.bounds
view.addSubnode(textNode)
4、ASImageNode 和 ASNetworkImageNode
ASImageNode 的使用方法和UIImageView類似, 唯一不同的就是 ASImageNode 繼承自 ASControlNode , 可添加點(diǎn)擊事件,ASNetworkImageNode可以加載網(wǎng)絡(luò)圖片,以前在項(xiàng)目中大多數(shù)使用SDWebImage, 但是個(gè)人感覺(jué)SDWebImage 的性能不是太好,而且SDWebImage還有個(gè)缺點(diǎn)就是不支持gif圖片
提示:
在使用ASNetworkImageNode加載圖片的時(shí)候如果和UITableViewCell重用機(jī)制混合使用有些時(shí)候可能出現(xiàn)BUG,就是圖片可能會(huì)不更新
,特別是加載gif的時(shí)候可能出現(xiàn),我的解決辦法是將YYWebImage封裝成ASDisplayNode對(duì)象使用。
ASImageNode的簡(jiǎn)單使用例子
let imageNode: ASImageNode = ASImageNode.init()
imageNode.frame = view.bounds
imageNode.image = UIImage.init(named: "70753")
view.addSubnode(imageNode)
5、將UIKit原生控件封裝成ASDisplayNode
可以將UIKit的控件封裝成ASDisplayNode, 封裝如下:
// 將一個(gè)UIButton封裝成一個(gè)ASDisplayNode對(duì)象
let displayNode: ASDisplayNode = ASDisplayNode.init { () -> UIView in
let btn = UIButton.init(type: .custom)
btn.setTitle("你好,請(qǐng)點(diǎn)擊我", for: .normal)
btn.setTitleColor(UIColor.red, for: .normal)
return btn
}
displayNode.frame = CGRect.init(origin: CGPoint.init(x: 100, y: 100),
size: CGSize.init(width: 180, height: 100))
displayNode.backgroundColor = UIColor.orange
displayNode.cornerRadius = 10
view.addSubnode(displayNode)
用同樣的方法,在某些場(chǎng)合你可以將一些第三方的控件封裝成ASDisplaNode對(duì)象,這樣做也有助于界面的流暢度提升
6、在項(xiàng)目中具體該怎樣使用?
是整個(gè)項(xiàng)目全部控件都采用 AsyncDisplayKit呢? 還是部分控件采用 AsyncDisplayKit? 我個(gè)人認(rèn)為還是要依據(jù)不同的條件來(lái)看。
如果項(xiàng)目已經(jīng)發(fā)布了,已經(jīng)處于維護(hù)階段,這個(gè)時(shí)候如果全部替換的話首先工作量比較大,這種可以適當(dāng)替換一些控件慢慢過(guò)渡,例如項(xiàng)目哪些界面存在明顯卡頓,可以將卡頓界面的一些控件替換解決問(wèn)題
如果是一個(gè)新開(kāi)始的項(xiàng)目,那就看下整個(gè)項(xiàng)目成員對(duì) AsyncDisplayKit 的熟悉程度做出取舍,畢竟 AsyncDisplayKit 還是要學(xué)習(xí)一下下的,偶爾還是會(huì)遇到一些坑。
總結(jié):
這一章簡(jiǎn)單介紹了一些基本控件的使用,對(duì)于布局方面 AsyncDisplayKit 也有一套自己的布局體系,這章暫未講解,下一章將會(huì)具體講解 AsyncDisplayKit 的布局系統(tǒng)