我正在聊天机器人,其中不同类型的响应来自服务器,我在聊天屏幕中使用UICollectionView单元格显示响应.根据服务器响应呈现不同类型的单元.当服务器响应播放视频时,我正在呈现包含youtube播放器的单元格.我正在使用
https://github.com/kieuquangloc147/YouTubePlayer-Swift.问题是当我滚动聊天屏幕(collectionView)时,youtube播放器一次又一次地打开.有时它会阻止所有UI元素并停止滚动.我尝试了不同的方法,但无法解决它.这是代码:
PlayerView:
PlayerView:
import UIKit class PlayerView: UIView,YouTubePlayerDelegate { override init(frame: CGRect) { super.init(frame: frame) addYotubePlayer() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } // youtube player lazy var youtubePlayer: YouTubePlayerView = { let viewFrame = UIScreen.main.bounds let player = YouTubePlayerView(frame: CGRect(x: 0,y: 0,width: viewFrame.width - 16,height: viewFrame.height * 1/3)) player.delegate = self return player }() // used as an overlay to dismiss the youtube player let blackView = UIView() // youtube player loader lazy var playerIndicator: UIActivityIndicatorView = { let indicator = UIActivityIndicatorView() indicator.activityIndicatorViewStyle = .whiteLarge indicator.hidesWhenStopped = true return indicator }() // shows youtube player func addYotubePlayer() { if let window = UIApplication.shared.keyWindow { blackView.frame = window.frame self.addSubview(blackView) blackView.backgroundColor = UIColor(white: 0,alpha: 0.5) let tap = UITapGestureRecognizer(target: self,action: #selector(handleDismiss)) tap.numberOfTapsrequired = 1 tap.cancelsTouchesInView = false blackView.addGestureRecognizer(tap) let centerX = UIScreen.main.bounds.size.width / 2 let centerY = UIScreen.main.bounds.size.height / 2 blackView.addSubview(playerIndicator) playerIndicator.center = CGPoint(x: centerX,y: centerY) playerIndicator.startAnimating() blackView.addSubview(youtubePlayer) youtubePlayer.center = CGPoint(x: centerX,y: centerY) blackView.alpha = 0 youtubePlayer.alpha = 0 UIView.animate(withDuration: 0.5,delay: 0,usingSpringWithDamping: 1,initialSpringVelocity: 1,options: .curveEaSEOut,animations: { self.blackView.alpha = 1 self.youtubePlayer.alpha = 1 },completion: nil) } } func play(_ videoID: String) { youtubePlayer.loadVideoID(videoID) } @objc func handleDismiss() { blackView.removeFromSuperview() UIApplication.shared.keyWindow?.viewWithTag(24)?.removeFromSuperview() UIApplication.shared.keyWindow?.removeFromSuperview() } func playerReady(_ videoPlayer: YouTubePlayerView) { self.playerIndicator.stopAnimating() } func playerStateChanged(_ videoPlayer: YouTubePlayerView,playerState: YouTubePlayerState) { } func playerQualityChanged(_ videoPlayer: YouTubePlayerView,playbackQuality: YouTubePlaybackQuality) { } }
YouTubePlayerCell(我在collectionView中显示的母鸡服务器响应视频):
import UIKit class YouTubePlayerCell: ChatMessageCell { var player: PlayerView = PlayerView(frame: UIScreen.main.bounds) override func setupViews() { super.setupViews() setupCell() } func setupCell() { messageTextView.frame = CGRect.zero textBubbleView.frame = CGRect.zero } func loadVideo(with videoID: String) { player.tag = 24 UIApplication.shared.keyWindow?.addSubview(player) player.play(videoID) } override func prepareForReuse() { super.prepareForReuse() player.removeFromSuperview() UIApplication.shared.keyWindow?.viewWithTag(24)?.removeFromSuperview() } }
以下是我在UICollectionView的cellForItemAt方法中呈现YouTubePlayerCell的方法
let message = messages[indexPath.row] if message.actionType == ActionType.video_play.rawValue { if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ControllerConstants.youtubePlayerCell,for: indexPath) as? YouTubePlayerCell { self.resignResponders() if let videoId = message.videoData?.identifier { cell.loadVideo(with: videoId) } return cell } }
完整的源代码可以在这里找到:https://github.com/imjog/susi_iOS/tree/ytplayer