【Swift 2.0】实现简单弹幕功能
前言
简单实现弹幕功能,表跟我谈效率,但也有用队列控制同时弹的数量。
声明
欢迎转载,但请保留文章原始出处:)
博客园:http://www.cnblogs.com
农民伯伯: http://over140.cnblogs.com
正文
let DANMAKU_SPEED: CGFloat = // 弹幕每秒移动速度
let DANMAKU_SPACE_TIME: NSTimeInterval = // 弹幕之间的时间间隔
let DANMAKU_MAX_ROW = // 最多同时弹幕行数
let danmakuFont = UIFont.systemFontOfSize() // 弹幕字体大小
var rowArray = Array<Array<Danmaku>>(count: , repeatedValue: Array<Danmaku>())
var danmakuQueue = NSOperationQueue() // 队列 class Danmaku : NSObject{
var msg: Msg
var view: UILabel?
var size = CGSize(width: , height: )
var row =
var startTime: NSDate?
var duration: NSTimeInterval =
var delay: NSTimeInterval = init(_ msg: Msg, _ row: Int, _ delay: NSTimeInterval = ) {
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 = ; row < weakself.DANMAKU_MAX_ROW; ++row {
let rowDanmaku = weakself.rowArray[row]
if rowDanmaku.count == {
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 >= {
delay =
} 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()
} 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 = + danmaku.row * (Int(size.height) + )
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(, -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】实现简单弹幕功能的更多相关文章
- 用SignalR实现的弹幕功能
弹幕功能通常用于实时显示当前视频或者文档的评论内容,在上快速飞过的方式呈现,看起来比较酷炫. 这种典型的多用户实时交互的功能,很适合使用SignalR实现,通过SignalR提供后台的服务推送功能,客 ...
- Swift 2.0 到底「新」在哪?
[编者按]2015年6月,一年一度的苹果 WWDC 大会如期而至,在大会上苹果发布了 Swift 2.0,引入了很多新的特性,以帮助开发者更快.更简单地构建应用.本篇文章作者是 Maxime defa ...
- Android弹幕功能实现,模仿斗鱼直播的弹幕效果
转载出处:http://blog.csdn.net/sinyu890807/article/details/51933728 本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即 ...
- Swift 4.0:访问级别(访问控制)
基础篇 注: 下文中所提及的类和类型为Class, Enum和Struct Swift中的访问级别有以下五种: open: 公开权限, 最高的权限, 可以被其他模块访问, 继承及复写. public: ...
- Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理
这是本人第一次写,写的不好的地方还忘包含.写这个的主要原因是想通过这个来学习下EF的CodeFirst模式,本来也想用AngularJs来玩玩的,但是自己只会普通的绑定,对指令这些不是很熟悉,所以就基 ...
- Swift 2.0 异常处理
转自:http://www.jianshu.com/p/96a7db3fde00 WWDC 2015 宣布了新的 Swift 2.0. 这次重大更新给 Swift 提供了新的异常处理方法.这篇文章会主 ...
- 可在广域网部署运行的QQ高仿版 -- GG叽叽V3.0,完善基础功能(源码)
(前段时间封闭式开发完了一个项目,最近才有时间继续更新GG的后续版本,对那些关注GG的朋友来说,真的是很抱歉.)GG的前面几个版本开发了一些比较高级的功能,像视频聊天.远程桌面.文件传送.远程磁盘等, ...
- fir.im Weekly - Swift 3.0 的迁移适配指南
无论你是移动开发者,还是桌面端开发者,或者正在IoT领域探索的技术人员,那么应该更加关注 iDev 全平台开发者大会,也许是后半年 iOS 开发者最盛大的技术盛宴.既有知名公司带来专业视野,又有从 S ...
- python3实现简单爬虫功能
本文参考虫师python2实现简单爬虫功能,并增加自己的感悟. #coding=utf-8 import re import urllib.request def getHtml(url): page ...
随机推荐
- 【开源】OSharp框架解说系列(6.1):日志系统设计
OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...
- 清除页面广告?身为前端,自己做一款简易的chrome扩展吧
大家肯定有这样的经历,浏览网页的时候,左右两端广告,诸如“屠龙宝刀,点击就送”,以及最近火的不行的林子聪37传奇霸业什么“霸业面具,霸业吊坠”的魔性广告总是充斥我们的眼球. 当然有现成的扩展程序或者插 ...
- Notes:indexedDB使用
indexedDB是浏览器端保存结构化数据的一种数据库,类似于mysql,oracle等数据库,但indexedDB使用对象存储数据,而不是用表. indexedDB是全局的宿主对象,使用window ...
- Ubuntu杂记——Ubuntu下安装VMware
转战Ubuntu,不知道能坚持多久,但是自己还是要努力把转战过程中的学习到的给记录下来.这次就来记录一下,Ubuntu下如何安装VMware. 就我所知,Linux下有VirtualBox和VMwar ...
- codefordream 关于js中级训练
中级训练接着就紧锣密鼓的开始了. 首先是关于变量,变量的作用是给一个数据值标注名称. 注:JavaScript中变量名,函数名,参数名的命名规范:至少由字母,下划线,美元符号,数字其中的一种组成,但不 ...
- 关于Repository、IUnitOfWork 在领域层和应用服务层之间的代码分布与实现
本来早就准备总结一下关于Repository.IUnitOfWork之间的联系以及在各层中的分布,直到看到田园里的蟋蟀发表的文章:<DDD 领域驱动设计-谈谈 Repository.IUnitO ...
- 利用private font改变PDF文件的字体
利用private font改变PDF文件的字体 前几天做项目,需要使用未安装的字体来改变PDF的文件.以前并没有实现过类似的功能,幸运的是我在网上找到了类似的教程,并成功实现了这个功能. 下面就跟大 ...
- objective-c 语法快速过(2)
oc类的声明和定义的常见错误 1.只有类的声明,没有类的实现 2.漏了@end 3.@interface和@implementation嵌套,也就是@interface或者@implementatio ...
- Web接口测试工具---Poster与Postman
工作当中有不少时间在编写和维护接口自动化测试用例.打算先整理一些接口相关工具的使用. 简单对接Web口测试的相关工具/技术做个划分. HTTP/SOAP协议接口的功能测试: 1.浏览器URL(GET请 ...
- 【JVM】JVM系列之类加载机制(四)
一.前言 前面分析了class文件具体含义,接着需要将class文件加载到虚拟机中,这个过程是怎样的呢,下面,我们来仔细分析. 二.什么是类加载机制 把class文件加载到内存,并对数据进行校验.转换 ...