IOS 完成復雜的彈幕功用。本站提示廣大學習愛好者:(IOS 完成復雜的彈幕功用)文章只能為提供參考,不一定能成為您想要的結果。以下是IOS 完成復雜的彈幕功用正文
前言
復雜完成彈幕功用,表跟我談效率,但也有用隊列控制同時彈的數量。
注釋
代碼完成:
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 並不在主線程上
以上就是對IOS開發 復雜的彈幕功用的完成代碼,有需求開發這種功用的冤家可以參考下。