I have set up the UICollectionView
with the DetailMediaCell
XIB. If multiple answers are available, then a sub UICollectionView
is shown, already set up in the XIB.
Everything works fine, but when we open the view controller and check if there's a video, it should start playing from the beginning. However, it always starts from the first index automatically.
Additionally, when the video finishes, I've set up the scrollToItem function, but it's not working in my case. I suspect it's due to the size of the cell, which prevents it from scrolling to the first index.
For more details, please refer to the attached screenshot and code.
Code:-
import UIKit
import AVFoundation
class DetailMediaCell: UICollectionViewCell {
@IBOutlet weak var mainVideoVwForPlay: UIView!
@IBOutlet weak var vwForAnswerCollectionVw: UIView!
@IBOutlet weak var heightAnswerCollectionVw: NSLayoutConstraint!
@IBOutlet weak var answerCollectionVw: UICollectionView!
var arrPlayer:[AudioPlayer] = []
var subIndex:Int = 0
var mainIndex:Int = -1
var media: String?
var playerItem: CachingPlayerItem?
var player:AudioPlayer = AudioPlayer()
var playerLayer:AVPlayerLayer = AVPlayerLayer()
var subAnswerArray = [String]()
override func awakeFromNib() {
super.awakeFromNib()
registerUserAnswersCollectionView()
}
func registerUserAnswersCollectionView(){
answerCollectionVw.register(UINib(nibName: "MultiCell", bundle: nil), forCellWithReuseIdentifier: "MultiCell")
answerCollectionVw.dataSource = self
answerCollectionVw.delegate = self
}
func getAnswersForQuestion() {
heightAnswerCollectionVw.constant = subAnswerArray.count != 0 ? 110 : 0
self.arrPlayer = subAnswerArray.map({ hpmr in
return AudioPlayer()
})
playZeroIndexItemIfContainsMedia()
}
}
extension DetailMediaCell {
func initCell(media: String,audioPlayer:AudioPlayer,subIndexs:Int,mainIndexs:Int) {
mainIndex = mainIndexs
subIndex = subIndexs
player = audioPlayer
self.setupVideoPlayer(media: media)
}
func setupVideoPlayer(media: String?) {
if(player.playerItem == nil) {
if media != "" {
player.startPlayback(with: URL.init(string: media ?? "")!)
playerItem = player.playerItem
playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.bounds
mainVideoVwForPlay.layer.sublayers?.forEach({ ccc in
ccc.removeFromSuperlayer()
})
mainVideoVwForPlay.layer.addSublayer(playerLayer)
let recordingSession:AVAudioSession = AVAudioSession.sharedInstance()
do {
try recordingSession.overrideOutputAudioPort(.speaker)
try recordingSession.setActive(true)
} catch {
print(error.localizedDescription)
}
NotificationCenter.default.addObserver(self, selector: #selector(self.didPlayToEnd), name: .AVPlayerItemDidPlayToEndTime, object: player.currentItem)
}
} else {
playerLayer.frame = self.bounds
}
}
func playerStart(mainIndexs:Int,subIndexs:Int) {
mainIndex = mainIndexs
subIndex = subIndexs
self.player.isMuted = LocalStore.shared.isMutePressed
self.player.play()
}
func playerInvalidate() {
if(player.rate == 1) {
player.pause()
self.player.seek(to: .zero)
}
}
func playerInvalidateWithnil() {
if(player.rate == 1) {
player.pause()
player = AudioPlayer()
}
}
@objc func didPlayToEnd(notification: NSNotification) {
if let item = notification.object as? AVPlayerItem, let currentItem = player.currentItem, item == currentItem {
self.player.pause()
self.player.seek(to: .zero)
DispatchQueue.main.asyncAfter(deadline: .now()+0.1, execute: { [self] in
if subAnswerArray.count > 0 {
playerItemFinish(isMediaUrl: media ?? "", mainIndexs: mainIndex, subIndexs: subIndex)
}
})
}
}
}
extension DetailMediaCell : UICollectionViewDataSource , UICollectionViewDelegate,UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return subAnswerArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MultiAnswersCell", for: indexPath) as! MultiAnswersCell
if subIndex == indexPath.item {
cell.vwForHighlight.isHidden = false
}else{
cell.vwForHighlight.isHidden = true
}
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 85, height: collectionView.frame.height)
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let firstVisibleCellIndexPath = answerCollectionVw.indexPathsForVisibleItems.first
if let firstVisibleCellIndexPath = firstVisibleCellIndexPath {
DispatchQueue.main.async { [self] in
subIndex = firstVisibleCellIndexPath.item
print("Visible Index = ",subIndex)
}
}
}
func playZeroIndexItemIfContainsMedia() {
DispatchQueue.main.asyncAfter(deadline: .now()+0.3, execute: { [self] in
playerItemFinish(isMediaUrl: media ?? "", mainIndexs: mainIndex, subIndexs: subIndex)
})
}
}
extension DetailMediaCell {
func playerItemFinish(isMediaUrl: String, mainIndexs: Int, subIndexs: Int) {
let item = subIndexs + 1
let indexPath = IndexPath(item: subIndexs, section: 0)
if item < answerCollectionVw.numberOfItems(inSection: 0) {
subIndex = item
answerCollectionVw.scrollToItem(at: indexPath, at: .top, animated: false)
}
}
}