iOS LED跑馬燈效果實現

來源:互聯網
上載者:User

標籤:

iOS中實現LED跑馬燈效果

 

 

實現原理是使用scrollView, 將需要滾動的label添加兩次到 scrollView的subView下面, 然後通過滾動scrollView來實現跑馬燈效果。

 

具體實現代碼如下:

////  KMScrollLabel.swift//  StopSmokingPrograms////  Created by Fran on 15/11/2.//  Copyright © 2015年 kimree. All rights reserved.//import UIKit// 文字滾動方向enum KMScrollDirection: Int{    case Left = 0    case Right    case Up    case Down}class KMScrollLabel: UIScrollView {        // label 是唯讀    // 在外部只修改label的text即可    private var label = UILabel()    var textLabel: UILabel{        get{            return label        }    }        // label是否在滑動    private var keepScroll = false        // 動畫時間    var animationDuringTime:Double = 5        deinit{        KMLog("KMScrollLabel deinit")    }        convenience init(){        self.init(frame: CGRectZero)    }        override init(frame: CGRect) {        super.init(frame: frame)        KMLog("init frame")                self.scrollEnabled = false        self.showsHorizontalScrollIndicator = false        self.showsVerticalScrollIndicator = false        self.addSubview(label)    }        required init?(coder aDecoder: NSCoder) {        super.init(coder: aDecoder)        KMLog("init aDecoder")                self.scrollEnabled = false        self.showsHorizontalScrollIndicator = false        self.showsVerticalScrollIndicator = false        self.addSubview(label)    }        // MARK: - 開始滑動    func startScroll(direction: KMScrollDirection = .Left){        fitFrame(direction)                // 當label不處於滑動狀態時, 才可以開始滑動, 避免動畫效果疊加        if !keepScroll{            keepScroll = true            self.contentOffset = CGPointZero            beginScroll(direction)        }    }        // removeAllAnimations 之後會立刻執行 animation block 的 completion 部分,     // 目前無法確定 completion 部分的參數總會是 false, 為了避免巧合, 需要配合 keepScroll 參數一起使用    func stopScroll(){        keepScroll = false        self.layer.removeAllAnimations()    }        // MARK: - 具體怎樣滑動    func beginScroll(direction: KMScrollDirection = .Left){        let w = label.frame.size.width        let h = label.frame.size.height                switch direction{        case .Left:            self.contentOffset.x = 0            UIView.animateWithDuration(animationDuringTime, delay: 0, options: UIViewAnimationOptions.CurveLinear, animations: { [weak self]() -> Void in                self?.contentOffset.x = w                }, completion: { [weak self](finished: Bool) -> Void in                    if finished && (self != nil && self!.keepScroll){                        self!.contentOffset.x = 0                        self!.beginScroll(direction)                    }                })                    case .Right:            self.contentOffset.x = w            UIView.animateWithDuration(animationDuringTime, delay: 0, options: UIViewAnimationOptions.CurveLinear, animations: { [weak self]() -> Void in                self?.contentOffset.x = 0                }, completion: { [weak self](finished: Bool) -> Void in                    if finished && (self != nil && self!.keepScroll){                        self!.contentOffset.x = w                        self!.beginScroll(direction)                    }                })                    case .Up:            self.contentOffset.y = 0            UIView.animateWithDuration(animationDuringTime, delay: 0, options: UIViewAnimationOptions.CurveLinear, animations: { [weak self]() -> Void in                self?.contentOffset.y = h                }, completion: { [weak self](finished: Bool) -> Void in                    if finished && (self != nil && self!.keepScroll){                        self!.contentOffset.y = 0                        self!.beginScroll(direction)                    }                })                    case .Down:            self.contentOffset.y = h            UIView.animateWithDuration(animationDuringTime, delay: 0, options: UIViewAnimationOptions.CurveLinear, animations: { [weak self]() -> Void in                self?.contentOffset.y = 0                }, completion: { [weak self](finished: Bool) -> Void in                    if finished && (self != nil && self!.keepScroll){                        self!.contentOffset.y = h                        self!.beginScroll(direction)                    }                })        }            }        // MARK: - 適配frame    private func fitFrame(direction: KMScrollDirection){        // 按照水平方向移動的要求修改frame        func fitFrameAtHorizontalDirection(){                        let width = self.frame.size.width            var height = self.frame.size.height                        label.numberOfLines = 1            label.lineBreakMode = .ByWordWrapping            var size = label.sizeThatFits(CGSizeMake(CGFloat.max, height))                        // scroll 的 height 不能小於 label 的 height            if height < size.height{                self.frame.size.height = size.height                height = size.height            }                        // label 的 width 要加上 scroll width 的一半作為留白, 並且 label 的 width 不能小於 scroll 的 width            size.width += width / 2.0            if size.width < width{                size.width = width            }                        label.frame = CGRectMake(0, (height - size.height) / 2.0, size.width, size.height)                        let tempLabel = NSKeyedUnarchiver.unarchiveObjectWithData(NSKeyedArchiver.archivedDataWithRootObject(label)) as! UILabel            tempLabel.frame.origin.x += size.width            self.addSubview(tempLabel)                        self.contentSize = CGSizeMake(2 * size.width, height)        }                // 按照豎直方向移動的要求修改frame        func fitFrameAtVerticalDirection(){                        var width = self.frame.size.width            let height = self.frame.size.height                        label.numberOfLines = 0            label.lineBreakMode = .ByWordWrapping            let originalText = label.text                        // 擷取單個文字的寬度            label.text = "田"            let singleSize = label.sizeThatFits(CGSizeZero)                        label.text = originalText            var size = label.sizeThatFits(CGSizeMake(singleSize.width, CGFloat.max))                        if width < size.width{                self.frame.size.width = size.width                width = size.width            }                        size.height += height / 2.0            if size.height < height{                size.height = height            }                        label.frame = CGRectMake((width - size.width) / 2.0, 0, size.width, size.height)                        let tempLabel = NSKeyedUnarchiver.unarchiveObjectWithData(NSKeyedArchiver.archivedDataWithRootObject(label)) as! UILabel            tempLabel.frame.origin.y += size.height            self.addSubview(tempLabel)                        self.contentSize = CGSizeMake(width, 2 * size.height)        }                // 首先遍曆 scroll 的所有 subView, 將佔位的 label 移除        for view in self.subviews{            if view != label{                view.removeFromSuperview()            }        }                switch direction{        case .Left, .Right:            fitFrameAtHorizontalDirection()        case .Up, .Down:            fitFrameAtVerticalDirection()        }            }        /*    // Only override drawRect: if you perform custom drawing.    // An empty implementation adversely affects performance during animation.    override func drawRect(rect: CGRect) {    // Drawing code    }    */    }

  

iOS LED跑馬燈效果實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.