程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 更多關於編程 >> IOS 完成復雜的彈幕功用

IOS 完成復雜的彈幕功用

編輯:更多關於編程

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開發 復雜的彈幕功用的完成代碼,有需求開發這種功用的冤家可以參考下。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved