@Claude31 my problem here is I have declared my player in ViewCell, not in ViewContoller. So every cell has its player currently, thus I can't reach another cell's player when a player starts.
Post
Replies
Boosts
Views
Activity
Thank you for all of your efforts!
This was my first attempt to work with xibs and it went a little bit messy. I'd like to hear advice for view level player way too.
For now, I will try the second way. How can I achieve exploring all the cells available?
I cannot work with cell.superview.tableView.visibleCells in play button action which is in ViewCell file, it gives cannot find in scope error.
I still get the cannot find in scope error for "cell". I tried to declare tableView in and out of play button action but no chance. My cells awake in CollectionView, not in TableView.
I have found that this way I can get the visible cells:
let visibleIndexPaths = collectionView.indexPathsForVisibleItems
But I don't know what to do with it..
The problem is still here, I get the same error: "Can't find 'cell' in scope." when I use the code. For more information, here is the file I'm working on:
PodcastCellView: (Where I declare the player, player view's button and button action. But CollectionView is declared in ViewController.)
swift
I get the same error even I use the code in PodcastViewController.
After replacing the cell with self in line 2, I get another error on line 5.
Value of type 'UICollectionViewCell' has no member 'player'
If I replace that cell. with self., code compiles successfully. But nothing changes on the application side. When I click another play button while a stream playing, the second stream starts playing.
My player declared as player in PodcastViewCell
swift
var player: AVPlayer?
This is the complete code for PodcastViewCell
swift
import UIKit
import AVKit
import AVFoundation
class PodcastViewCell: UICollectionViewCell {
// UILabels
@IBOutlet weak var categoryLabel: UILabel!
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var dateLabel: UILabel!
@IBOutlet weak var podcastUnavailableLbl: UILabel!
// Constraints
@IBOutlet weak var linehg: NSLayoutConstraint!
@IBOutlet weak var categoryLabelHeight: NSLayoutConstraint!
@IBOutlet weak var podcastBtnWd: NSLayoutConstraint!
// UISliders
@IBOutlet weak var slider: UISlider!
// UIViews
@IBOutlet weak var podcastView: UIView!
// UIButtons
@IBOutlet weak var playPauseBtn: UIButton!
@IBOutlet weak var podcastBtn: UIButton!
var player: AVPlayer?
var playerItem: AVPlayerItem?
var timeObserverToken: Any?
var urlString: String?
var podcastLink: String?
var played = false
override func awakeFromNib() {
super.awakeFromNib()
podcastViewVisibility()
slider.value = 0
}
var item: News? {
didSet {
if let news = item {
titleLabel.text = news.title ?? ""
categoryLabel.text = news.category?.title ?? ""
dateLabel.text = news.publishDate ?? ""
}
}
}
func prepareCell(news: News?) {
item = news
}
func prepareCellAuthor(author: AuthorSubList?) {
itemAuthor = author
}
var itemAuthor: AuthorSubList? {
didSet {
if let column = itemAuthor {
titleLabel.text = column.title ?? ""
categoryLabel.text = ""
categoryLabelHeight.constant = 0
dateLabel.text = column.publishDate ?? ""
}
}
}
@IBAction func selectItem(_ sender: Any) {
if let news = item {
if let id = news.itemId {
delegate?.selectItemAction(itemId: id)
delegate?.selectPopularNews(news: news, index: tag)
}
}
else if let author = itemAuthor {
if let id = author.itemId {
delegate?.selectItemAction(itemId: id)
}
}
}
@IBAction func playPodcast(_ sender: Any) {
if let collectionView = self.superview as? UICollectionView {
let visibleCells = collectionView.visibleCells
for cell in visibleCells where cell is PodcastViewCell {
if cell.player != nil { }
}
}
if played == false {
NotificationCenter.default.addObserver(self, selector: #selector(playerItemDidReachEnd), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)
if let itemOffset = allItems?.itemListv2.firstIndex(where: {$0.itemId == itemAuthor?.itemId}) {
podcastLink = allItems?.itemListv2[itemOffset].podcastsound
}
let url = podcastLink ?? " "
if url != "" {
let playerItem = AVPlayerItem( url:NSURL( string:url )! as URL )
player = AVPlayer(playerItem:playerItem)
player!.rate = 1.0;
podcastView.isHidden = false
player!.play()
playPauseBtn.setImage(UIImage(systemName: "pause.fill"), for: .normal)
player?.addProgressObserver { progress in
self.slider.setValue(Float(progress), animated: true)
}
played = true
} else {
podcastUnavailableLbl.isHidden = false
}
} else {
podcastView.isHidden = true
player?.replaceCurrentItem(with: nil)
slider.value = 0
played = false
}
}
deinit {
NotificationCenter.default.removeObserver(self)
}
@IBAction func playPause(_ sender: Any) {
if player?.timeControlStatus == .playing {
player?.pause()
playPauseBtn.setImage(UIImage(systemName: "play.fill"), for: .normal)
} else {
player?.play()
playPauseBtn.setImage(UIImage(systemName: "pause.fill"), for: .normal)
}
}
}
extension AVPlayer {
func addProgressObserver(action:@escaping ((Double) - Void)) - Any {
return self.addPeriodicTimeObserver(forInterval: CMTime.init(value: 1, timescale: 1), queue: .main, using: { time in
if let duration = self.currentItem?.duration {
let duration = CMTimeGetSeconds(duration), time = CMTimeGetSeconds(time)
let progress = (time/duration)
action(progress)
}
})
}
}
The error on line 93 gone and I compiled the code successfully. This is the output:
debugger
cell is PodcastViewCell
podCell.player NOT found
cell is PodcastViewCell
podCell.player NOT found
cell is PodcastViewCell
podCell.player NOT found
cell is PodcastViewCell
podCell.player found
cell is PodcastViewCell
podCell.player NOT found
cell is PodcastViewCell
podCell.player NOT found
cell is PodcastViewCell
podCell.player NOT found
cell is PodcastViewCell
podCell.player NOT found
Stop when another start function still not working for information.
This is the output with the latest print:
First click (to show/play)
debugger
cell is PodcastViewCell
podCell.player NOT found
cell is PodcastViewCell
podCell.player found
cell is PodcastViewCell
podCell.player NOT found
cell is NOT PodcastViewCell
cell is PodcastViewCell
podCell.player found
cell is PodcastViewCell
podCell.player NOT found
New player for https://podcast.link
Second click on same button (to hide/stop):
debugger
cell is PodcastViewCell
podCell.player NOT found
cell is PodcastViewCell
podCell.player found
cell is PodcastViewCell
podCell.player NOT found
cell is NOT PodcastViewCell
cell is PodcastViewCell
podCell.player found
cell is PodcastViewCell
podCell.player NOT found
Sorry for the late reply. How are you lately? I hope everything going great!
I tried to add the latest print but got an error.
swift
print("Title", self.title) ----------------- "Value of type 'PodcastViewCell' has no member 'title'"
It is surprising in the first run that you have 2 found, as none has yet been created
I pressed different play buttons while other players are active, so this should why there are "player found" outputs shown.
There is also a case cell is NOT PodcastViewCell What cell is this ?
I rerun the code with prints and didn't get any NOT values. I will debug and notify you when I get NOT values. This is the output I got:
debugger
cell is PodcastViewCell
podCell.player NOT found
cell is PodcastViewCell
podCell.player NOT found
cell is PodcastViewCell
podCell.player NOT found
cell is PodcastViewCell
podCell.player NOT found
cell is PodcastViewCell
podCell.player NOT found
cell is PodcastViewCell
podCell.player NOT found
cell is PodcastViewCell
podCell.player NOT found
cell is PodcastViewCell
podCell.player NOT found
cell is PodcastViewCell
podCell.player NOT found
Thank you for all of your efforts but I am really giving up on this idea. Instead, I'll try to accomplish it in another way. When the user clicks the "play button", I'll show "podcast view" with a blurry background and a player. When the user wants to close, I'll stop the player and then hide the view. I am now looking into how can I create on PodcastViewCell file but show a full-screen view out of the fixed-size cell.
I am open to advice but I'd totally understand if you say "meh that's all from me" 😇
I am having issues with presenting the nib cell. I want to show the player view when the play button pressed. But couldn’t get how to reach that nib.
Yeah, this is actually my question.
I still have "PodcastViewCell" as Table View Cell, like in my previous question. Now, I want to show "PlayerViewCell" (a full-screen player view I recently added) when the "Play" button in the "PodcastViewCell" nib is pressed.
Or should I just add a View to the storyboard then just change its visibility? Or should I do something else?
I've achieved to play my player outside of the xib, in my view controller as you suggested earlier. Thanks for the idea again!
Then I created a container view for the playerViewCell nib on my storyboard for the player and marked it as hidden. When I try to unhide it with swift
podcastView.isHidden = false
I always get
debugger
"Unexpectedly found nil while implicitly unwrapping an Optional value"
I don't know why it isn't loaded even tho the controller's other elements (like play button, etc.) on the screen.
(Even tried to use dummy UIView and just unhide it but still got the same error.)
I am able to hide/unhide the view in general when I try to do it on most functions. But I get the error when I try to do it on one specific function: the function I call from nib file. I don’t know what is the issue but I think this usually happens if I try to change an element’s properties before loading it. But all of the other elements are loaded when I call the function, like play button or podcast title label.