iOS:一用就上癮的跑馬燈視圖

簡介

在產品開發過程當中,有可能會遇到這樣一個狀況:一個UILabel設計爲僅能顯示一行,可是在小屏手機中,由於寬度不夠,最終會顯示省略號...。 可是這些信息又比較重要、不能省略,卻沒有充足的空間換行顯示。 那麼問題來了,該怎麼辦呢?這個時候,聰明的產品經理摸了摸下巴,忽然雙眼放光「用跑馬燈啊」git

image

好吧,既然產品都給出了精妙絕倫的方案,程序員的使命就是義無反顧地實現它!程序員

Github地址

喜歡就給顆小星星喲❤️ JXMarqueeView地址️github

動圖預覽

  • JXMarqueeType.left:往左滾動 swift

    left.gif

  • JXMarqueeType.right:往右滾動 bash

    right.gif

  • JXMarqueeType.reverse:循環反轉 閉包

    reverse.gif

  • 圖片滾動 ide

    picture.gif

  • 自定義View ui

    poetry.gif

原理

  • 使用CADisplayLink,每次屏幕刷新的時候,調整視圖的位置就行。爲了達到循環顯示,須要添加兩個同樣的視圖。
  • 爲了擴大跑馬燈的使用範圍,我進行了抽象化處理,並無寫死用UILabel來實現,而是暴露了一個屬性contentView: UIView。只要是UIView及其子類,均可以用來進行跑馬燈顯示。對於複雜的視圖,須要本身重寫contentView的sizeThatFits方法,返回正確的size便可。

這裏分享兩個騷操做:

  1. 如何實現UIView的拷貝?
//騷操做:UIView是沒有聽從拷貝協議的。能夠經過UIView支持NSCoding協議,間接來複制一個視圖
let otherContentViewData = NSKeyedArchiver.archivedData(withRootObject: validContentView)
let otherContentView = NSKeyedUnarchiver.unarchiveObject(with: otherContentViewData) as! UIView
otherContentView.frame = CGRect(x: validContentView.bounds.size.width + contentMargin, y: 0, width: validContentView.bounds.size.width, height: self.bounds.size.height)
containerView.addSubview(otherContentView)
複製代碼
  1. 如何斷開CADisplayLink的循環引用? 你們知道CADisplayLink和NSTimer都會對Target強持有,Target通常也會強持有它們。若是使用閉包回調的API,能夠解決這個問題,可是這些API要求iOS的系統都比較高。因此,仍是須要直面這個問題。
override func willMove(toSuperview newSuperview: UIView?) {
        //騷操做:當視圖將被移除父視圖的時候,newSuperview就爲nil。在這個時候,中止掉CADisplayLink,斷開循環引用,視圖就能夠被正確釋放掉了。
        if newSuperview == nil {
            self.stopMarquee()
        }
    }
複製代碼

使用

  • UILabel使用示例
let label = UILabel()
label.textColor = UIColor.red
label.font = UIFont.systemFont(ofSize: 30, weight: .medium)
label.text = "abcdefghijklmnopqrstuvwxyz"

marqueeView.contentView = label
marqueeView.contentMargin = 50
marqueeView.marqueeType = .left
self.view.addSubview(marqueeView)
複製代碼
  • UIImageView使用示例
let imageView = UIImageView(image: UIImage(named: "haizeiwang.jpeg"))
imageView.contentMode = .scaleAspectFill

marqueeView.contentView = imageView
marqueeView.marqueeType = .reverse
self.view.addSubview(marqueeView)
複製代碼
  • 拷貝自定義View

若是contentView帶有圓角、陰影等,經過NSCoding協議拷貝的View會丟失掉這些信息。這種特殊狀況須要本身從新建立一個一樣的自定義View。 重寫JXMarqueeViewCopyable協議的func copyMarqueeView() -> UIView方法便可。具體能夠參考demo裏面的源碼。spa

Github地址

喜歡就給顆小星星喲❤️ JXMarqueeView地址️設計

相關文章
相關標籤/搜索