一. demo效果如下:
二. 如何使用:
????????下載https://github.com/moonCai/MNMarqueeView.git, 將MNMarqueeView拖入項目中初始化即可。在獲取到文本標題后對MNMarqueeView對象的textList賦值享郊,然后調(diào)用run(). 在需要暫停的合適地方調(diào)用pause(),在需要視圖銷毀時調(diào)用stop()。
三. 實現(xiàn)思路大綱:
? ? 1.設(shè)置textLabelContainerView屬性院峡,作為文本控件(TextLabel)的容器視圖奔害;
? ? 2.創(chuàng)建以下對象:
? ? ? ? TextLabel對象:展示newsTitle;
????????onScreenTextLabels:?[TextLabel] ? ?記錄屏幕上的TextLabel對象;
? ??????offScreenTextLabels:[TextLabel] ? ?記錄離開textLabelContainerView的TextLabel對象(用于緩存離開屏幕的textLabel, 在下一個textLabel即將創(chuàng)建時使用绪囱。避免屏幕的內(nèi)存開辟)镶奉。
? ? 3. 設(shè)置displayLink屬性础淤,通過displayLink的定時源監(jiān)聽MNMarqueeView對象來實現(xiàn)橫向滾動:
敲黑板崭放,重點來了:
? ? ? ?通過速度 *?displayLink的持續(xù)時長來獲取偏移量。我在實現(xiàn)橫向滾動這里的思路不是直接改變每個textLabel的偏移量鸽凶。原因主要是:1.獲取每個textLabel的“年齡”(自創(chuàng)建到當(dāng)前時間的時長)較為繁瑣币砂。因此在這里借鑒系統(tǒng)組件UIScrollView的原理,改變?nèi)萜饕晥D的bounds從而改變其子視圖的位置。
? ? ? 因此,我在這里采取用定時源持續(xù)改變textLabelContainerView的bounds中x坐標的偏移量凶杖,textLabelContainerView的frame是沒有被改變的种远。因此它在屏幕上的位置固定不變,添加在其上面的子視圖持續(xù)偏移祝懂,這就是跑馬燈實現(xiàn)的原理之一票摇。
? ? ? ? ?第二個原理的著眼點在于如何給每個textLabel設(shè)置frame??
? ? ? ? ?每個textLabel被創(chuàng)建出來就馬上添加到onScreenTextLabels砚蓬,直至它的maxX小于父視圖的minX時就被移除矢门,然后被添加到offScreenTextLabels。
? ? ? ? ?第一個被創(chuàng)建的textLabel,它的frame的x坐標是textLabelContainerView的bounds的l.frame.origin.x =?textLabelContainerView.bounds.maxX灰蛙。之后被創(chuàng)建的textLabel的frame.origin.x 被賦值為onScreenTextLabels最后一個元素的frame的maxX + 文本之間的間隔祟剔。
? ? ? ? 此外,值得一說的是offScreenTextLabels摩梧。上文中有提及它起到的作用是復(fù)用物延。具體的原理是借鑒UITableView的復(fù)用機制。我在需要創(chuàng)建textLabel時仅父,調(diào)用offScreenTextLabels的popLast()叛薯。也就是,如果最后一個元素存在就取出使用笙纤,offScreenTextLabels在取出后自動移除耗溜,如果最后一個元素不存在就新創(chuàng)建。
? ? ? ? 最后要說的是一個細節(jié)處理:跑馬燈左右兩端的漸變模糊視圖省容。顯而易見抖拴,這么做的目的是為了柔和文本從移除父控件的視覺感受。漸變寬度和漸變色都留了接口腥椒,詳情見demo中代碼阿宅。