无法加载UIView与UICollectionVIewCell数据

问题描述:

我已经搜索到处找到解决方案。通过写这个问题再次尝试我的运气。我有一个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中设置的属性?

最后定了!下面是我在代码所做的更改:在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帮助我解决了一个很大的问题!

您的PlayerView类中的item属性从未在您的初始化程序中设置。您需要将其设置为或具有创建PlayerView实例的任何类设置项目属性。否则它将永远是零。

+0

谢谢你的回答。你能告诉我如何创建一个实例吗? – Mohit

您可能想要在选择单元格时检索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