2017-08-29 35 views
0

我已經搜索到處找到解決方案。通過寫這個問題再次嘗試我的運氣。我有一個collectionViewCell,其中我已經解析了包含名稱和ID的XML URL數據。現在當我點擊單元格時,我想加載一個帶有AVPlayer的UIView。要播放該文件,我必須使用其他網址,但使用的是我在該單元格中解析過的ID。這裏是我的didSelectItem func無法加載UIView與UICollectionVIewCell數據

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 
     let playerLauncher = PlayerLauncher() 
     playerLauncher.showPlayer() 
} 

這是我PlayerLauncher文件:

import UIKit 

import AVFoundation 

class PlayerView: UIView { 

    var item: Item? 

    override init(frame: CGRect) { 
     super.init(frame: frame) 

     backgroundColor = UIColor.black 

     let id = item?.itemId 

     if let url = URL(string: "http://xample.com/play.m3u?id=\(id)") { 
      let player = AVPlayer(url: url) 
      print(url) 
      let playerLayer = AVPlayerLayer(player: player) 
      self.layer.addSublayer(playerLayer) 
      playerLayer.frame = self.frame 

      player.play() 
     } 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 
} 

class PlayerLauncher: NSObject { 

     func showPlayer() { 

      if let keyWindow = UIApplication.shared.keyWindow { 
       let view = UIView(frame: keyWindow.frame) 
       view.backgroundColor = UIColor.white 

       view.frame = CGRect(x: 0, y: keyWindow.frame.height - 50, width: view.frame.width, height: 50) 

       let playerFrame = CGRect(x: 0, y: 0, width: keyWindow.frame.width, height: keyWindow.frame.height) 
       let playerView = PlayerView(frame: playerFrame) 
       view.addSubview(playerView) 

       keyWindow.addSubview(view) 

       UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: { 
        view.frame = keyWindow.frame 
       }, completion: nil) 
      } 
     } 
    } 

我從我的項目NSObject類,但選擇單元格中的UIView加載罰款後設定的項目,但不會玩文件並顯示id = nil。我該如何解決它?

更新:所以我改了一下我的代碼,我可以打印id。

下面是我在didSelectItem方法所做的更改:我在PlayerView和PlayerLauncher類改變了一些代碼

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 

     collectionView.deselectItem(at: indexPath, animated: true) 

     let playerView = PlayerView() 
     playerView.item = items?[indexPath.item] 

     let playerLauncher = PlayerLauncher() 
     playerLauncher.showPlayer() 
} 

在此之後:

import UIKit 
import AVFoundation 

class PlayerView: UIView { 

    var id: String? 

    var item: Item? { 
     didSet { 
      id = item?.itemId 
      print(id) 
     } 
    } 

    override init(frame: CGRect) { 
     super.init(frame: frame) 

     backgroundColor = UIColor.black 
    } 

    func startPlaying() { 

     if let url = URL(string: "http://xample.com/play.m3u?id=\(id)") { 
      let player = AVPlayer(url: url) 
      print(url) 
      let playerLayer = AVPlayerLayer(player: player) 
      self.layer.addSublayer(playerLayer) 
      playerLayer.frame = self.frame 

      player.play() 
     } 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 
} 

class PlayerLauncher: NSObject { 

    func showPlayer() { 

     if let keyWindow = UIApplication.shared.keyWindow { 
      let view = UIView(frame: keyWindow.frame) 
      view.backgroundColor = UIColor.white 

      view.frame = CGRect(x: 0, y: keyWindow.frame.height - 50, width: view.frame.width, height: 50) 

      let playerFrame = CGRect(x: 0, y: 0, width: keyWindow.frame.width, height: keyWindow.frame.height) 
      let playerView = PlayerView(frame: playerFrame) 
      view.addSubview(playerView) 

      keyWindow.addSubview(view) 

      UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: { 
       view.frame = keyWindow.frame 
      }, completion: { (completeAnimation) in 
       playerView.startPlaying() 
      }) 
     } 
    } 
} 

現在我可以從didSet打印ID,但當在startPlaying()方法中時,它仍然顯示id = nil當我選擇該項目。我如何獲得在initstartPlaying() func中的didSet中設置的屬性?

回答

0

最後定了!下面是我在代碼所做的更改:在didSelectItem方法 :

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 

    if let item = items?[indexPath.item] { 
     showPlayer(item: item) 
    } 
} 

func showPlayer(item: Item) { 

    let playerLauncher = PlayerLauncher() 
    playerLauncher.item = item 
    playerLauncher.showVideoPlayer() 
} 

在PlayerView我編輯initdidSet到:

var item = Item() 

init(frame: CGRect, item: Item) { 
    super.init(frame: frame) 
    self.item = item 

    setupPlayerView() 
    backgroundColor = UIColor(white: 0.3, alpha: 1) 
} 

setupPlayerView方法,我設置的itemId和最後在PlayerLauncher中我剛加入:

var item = Item() 

何對未來某個人來說,這可能會有所幫助,因此將解決方案發布在此處感謝@sCha幫助我解決了一個很大的問題!

0

您的PlayerView類中的item屬性從未在您的初始化程序中設置。您需要將其設置爲或具有創建PlayerView實例的任何類設置項目屬性。否則它將永遠是零。

+0

謝謝你的回答。你能告訴我如何創建一個實例嗎? – Mohit

0

您可能想要在選擇單元格時檢索Item信息。

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 
    let item: Item = itemList[indexPath.item] // just for instance 
    let playerLauncher = PlayerLauncher() 
    playerLauncher.showPlayer(item) 
} 

,因此你需要改變你的Player類似如下:

class PlayerLauncher: NSObject { 

    func showPlayer(item: Item) { 

     if let keyWindow = UIApplication.shared.keyWindow { 
      let view = UIView(frame: keyWindow.frame) 
      view.backgroundColor = UIColor.white 

      view.frame = CGRect(x: 0, y: keyWindow.frame.height - 50, width: view.frame.width, height: 50) 

      let playerFrame = CGRect(x: 0, y: 0, width: keyWindow.frame.width, height: keyWindow.frame.height) 
      let playerView = PlayerView(frame: playerFrame) 
      playerView.item = item // Here 
      view.addSubview(playerView) 

      keyWindow.addSubview(view) 

      UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: { 
       view.frame = keyWindow.frame 
      }, completion: { _ in 
       playerView.startPlaying() // And here 
      }) 
     } 
    } 
} 

,並在PlayerView

class PlayerView: UIView { 

    var item: Item? 
    var player: AVPlayer? 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     backgroundColor = UIColor.black 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

    func startPlaying() { 
     let id = item?.itemId 

     if let url = URL(string: "http://xample.com/play.m3u?id=\(id)") { 
      self.player = AVPlayer(url: url) 
      print(url) 
      let playerLayer = AVPlayerLayer(player: self.player) 
      self.layer.addSublayer(playerLayer) 
      playerLayer.frame = self.frame 

      self.player.play() 
     } 
    } 
} 

更新:

試試這個看看會發生什麼:

func startPlaying() { 
    guard let id = id else { print("** id is nil"); return } // here 
    print("* item id = \(id)")   // and here 

    if let url = URL(string: "http://xample.com/play.m3u?id=\(id)") { 
     let player = AVPlayer(url: url) 
     print(url) 
     let playerLayer = AVPlayerLayer(player: player) 
     self.layer.addSublayer(playerLayer) 
     playerLayer.frame = self.frame 

     player.play() 
    } 
} 

更新:#2:

再次

,整個代碼:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 
    let item = items?[indexPath.item] 
    let playerLauncher = PlayerLauncher() 
    playerLauncher.showPlayer(item) 
} 

和:

class PlayerLauncher: NSObject { 

    func showPlayer(item: Item) { 

     if let keyWindow = UIApplication.shared.keyWindow { 
      let view = UIView(frame: keyWindow.frame) 
      view.backgroundColor = UIColor.white 

      view.frame = CGRect(x: 0, y: keyWindow.frame.height - 50, width: view.frame.width, height: 50) 

      let playerFrame = CGRect(x: 0, y: 0, width: keyWindow.frame.width, height: keyWindow.frame.height) 
      let playerView = PlayerView(frame: playerFrame) 
      playerView.item = item // Here 
      view.addSubview(playerView) 

      keyWindow.addSubview(view) 

      UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: { 
       view.frame = keyWindow.frame 
      }, completion: { _ in 
       playerView.startPlaying() // And here 
      }) 
     } 
    } 
} 

class PlayerView: UIView { 

    var id: String? 
    var item: Item? { 
     didSet { 
      id = item?.itemId 
      print(id) 
     } 
    } 
    var player: AVPlayer? 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     backgroundColor = UIColor.black 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

    func startPlaying() { 
     guard let id = id else { print("** id is nil"); return } // here 
     print("* item id = \(id)")   // and here 

     if let url = URL(string: "http://xample.com/play.m3u?id=\(id)") { 
      self.player = AVPlayer(url: url) 
      print(url) 
      let playerLayer = AVPlayerLayer(player: self.player) 
      self.layer.addSublayer(playerLayer) 
      playerLayer.frame = self.frame 

      self.player.play() 
     } 
    } 
} 
+0

你好!它仍然顯示id = nil。我需要在我的PlayerView類中進行任何更改嗎?因爲這是我打電話給AVPlayer播放鏈接的地方。 – Mohit

+0

@Mohit您的'PlayerView'似乎在初始化時開始播放,抱歉我瀏覽了代碼,因此無論是需要在'init'上傳遞'item'還是改變它的工作方式。我會在我的答案中添加幾個代碼。 – sCha

+0

@Mohit還有一件事。我相信你的AVPlayer實例應該在類中全局聲明。在我的回答中也添加了。 – sCha