【Swift 2.0】实现简单弹幕功能
let DANMAKU_SPEED: CGFloat = 150 // 弹幕每秒移动速度 let DANMAKU_SPACE_TIME: NSTimeInterval = 1 // 弹幕之间的时间间隔 let DANMAKU_MAX_ROW = 3 // 最多同时弹幕行数 let danmakuFont = UIFont.systemFontOfSize(18) // 弹幕字体大小 var rowArray = Array<Array<Danmaku>>(count: 3, repeatedValue: Array<Danmaku>()) var danmakuQueue = NSOperationQueue() // 队列 class Danmaku : NSObject{ var msg: Msg var view: UILabel? var size = CGSize(width: 0, height: 0) var row = 0 var startTime: NSDate? var duration: NSTimeInterval = 0 var delay: NSTimeInterval = 0 init(_ msg: Msg, _ row: Int, _ delay: NSTimeInterval = 0) { self.msg = msg self.row = row self.delay = delay } } func queueDanmaku(msg: Msg) { danmakuQueue.addOperation(NSBlockOperation(block: { [weak self] in if let weakself = self { repeat { //检测放第几行 for var row = 0; row < weakself.DANMAKU_MAX_ROW; ++row { let rowDanmaku = weakself.rowArray[row] if rowDanmaku.count == 0 { let danmaku = Danmaku(msg, weakself.danmakuFont, row) weakself.rowArray[row].append(danmaku) self?.performSelectorOnMainThread("sendDanmaku:", withObject: danmaku, waitUntilDone: true) return } else { if let lastDanmaku = rowDanmaku.last { if let startTime = lastDanmaku.startTime { let now = NSDate() let seconds = now.timeIntervalSinceDate(startTime) let widthDuration = Double(lastDanmaku.size.width / weakself.DANMAKU_SPEED) var delay = seconds - weakself.DANMAKU_SPACE_TIME - widthDuration if delay >= 0 { delay = 0 } else { if lastDanmaku.delay > lastDanmaku.duration { continue } } let danmaku = Danmaku(msg, weakself.danmakuFont, row, abs(delay) + lastDanmaku.delay) weakself.rowArray[row].append(danmaku) self?.performSelectorOnMainThread("sendDanmaku:", withObject: danmaku, waitUntilDone: true) return } } } } sleep(1000) } while self != nil } })) } func sendDanmaku(danmaku: Danmaku) { let text = "\(danmaku.msg.user_name) : \(danmaku.msg.text)" let size = NSString(string: text).sizeWithAttributes([NSFontAttributeName : danmakuFont]) let width = UIScreen.mainScreen().bounds.size.width let top = 54 + danmaku.row * (Int(size.height) + 10) let label = UILabel(frame: CGRectMake(width, CGFloat(top), size.width, size.height)) let duration = (width + size.width) / DANMAKU_SPEED danmaku.view = label danmaku.size = size danmaku.startTime = NSDate() danmaku.duration = NSTimeInterval(duration) label.text = text label.font = danmakuFont label.textColor = UIColor.whiteColor() label.shadowColor = UIColor.blackColor() label.shadowOffset = CGSizeMake(0, -1.0) self.view.addSubview(label) UIView.animateWithDuration(Double(duration), delay: danmaku.delay, options: UIViewAnimationOptions.CurveLinear, animations: { () -> Void in label.left = -label.width }) { [weak self] (Bool) -> Void in if !(self?.rowArray[danmaku.row].isEmpty ?? true) { self?.rowArray[danmaku.row].removeFirst() } label.removeFromSuperview() } }
代码说明:
代码控制了最多同时只能弹三行,每行最后一条如果延迟大于跑弹幕的时间(已经有一条处于完全等待状态)就自动切到下一行,超过最大限制就等待。
* rowArray 主要用于查询前一个弹幕的位置和时间
* 别忘了在 deinit 里面加上 danmakuQueue.cancelAllOperations()
* 注意 NSBlockOperation 的 block 并不在主线程上
本文转自博客园农民伯伯的博客,原文链接:【Swift 2.0】实现简单弹幕功能,如需转载请自行联系原博主。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
【Swift】iOS开发笔记(一)
1、隐藏/显示密码功能 光设置secureTextEntry还不行,你会发现UITextField在切换到显示密码时会多一个空字符,看着巨别扭,需要在更改secureTextEntry后进行如下设置: letpwd=psdField.text self.psdField.text=pwd+ " " self.psdField.text=pwd 2、获取当前类的名称 String.fromCString(object_getClassName(self)) 注意:通过_stdlib_getDemangledTypeName也能取到,但是如果在父类里面去就只能取到父类的名称 3、 国际化 find.\(-name'*.m'-o-name'*.h'\)-print0|xargs-0genstrings-oen.lproj 凡是使用了NSLocalizedString的字符串都能被找到,支持子目录查找,注意替换en.lproj 4、UITableView分割线的显示问题 去掉分割线:设置UITableView的separatorStyle =UITableViewCellSepara...
-
下一篇
【Swift】UILabel 设置内边距
class UILabelPadding : UILabel { private var padding = UIEdgeInsetsZero @IBInspectable var paddingLeft: CGFloat { get { return padding.left } set { padding.left = newValue } } @IBInspectable var paddingRight: CGFloat { get { return padding.right } set { padding.right = newValue } } @IBInspectable var paddingTop: CGFloat { get { return padding.top } set { padding.top = newValue } } @IBInspectable var paddingBottom: CGFloat { get { return padding.bottom } set { padding.bottom = newValue } } overri...
相关文章
文章评论
共有0条评论来说两句吧...