#ios #swift #uiview
Вопрос:
У меня есть проект из двух файлов для приложения для плеера подкастов. Моя цель состоит в том, чтобы, когда пользователь нажимает кнопку воспроизведения (загружается в ячейку пера), будет показан подкастплеер (добавлен в раскадровку в контроллере просмотра) с воспроизведением/паузой.
.
├── _DetailViewController.swift
│ ├── AVPlayer
│ ├── PodcastPlayerView (full-screen player view)
│ └── setupPodcastPlayer (setting player's URL amp; hide/unhide PodcastPlayerView)
│
├── _PodcastViewCell.swift (File Owner of the nib)
│ ├── url (Podcast URL of the cell)
└── └── @IBAction playPodcast (the play button in a cell)
Это большая часть кода, выполняемого в PodcastViewCell.swift. Получает идентификатор элемента ячейки, находит ссылку на ее подкаст, затем передает ее контроллеру представления.
protocol PodcastViewCellDelegate {
func podcastButtonClicked(podcastUrl: String)
}
class PodcastViewCell: UICollectionViewCell {
weak var delegate: PodcastViewCellDelegate?
@IBAction func playPodcast(_ sender: Any) {
if let itemOffset = allItems?.itemListv2.firstIndex(where: {$0.itemId == itemAuthor?.itemId}) {
podcastLink = allItems?.itemListv2[itemOffset].podcastsound
}
let url = podcastLink ?? " "
delegate?.podcastButtonClicked(podcastUrl: URL)
}
}
Это код контроллера представления, который содержит UIView проигрывателя подкастов, проигрыватель AVPlayer, представление коллекции для ячеек PodcastViewCells и т.д. Я также добавил строки, в которых я могу и не могу скрывать/показывать просмотр подкастплеера в коде. Когда я запускаю приложение, когда представление не скрыто, оно видно и находится там, где должно быть. Но я все еще не могу показать это в той строке, где я это упомянул. Это похоже на то, как вид загружается и уничтожается…
class DetailViewController: BaseViewController {
@IBOutlet weak var collectionView: UICollectionView!
@IBOutlet weak var podcastPlayerView: UIView!
var podcastLink: String = ""
static var itemId = "0"
var player: AVPlayer?
var playerItem: AVPlayerItem?
var timeObserverToken: Any?
var played = false
override func viewDidLoad() {
super.viewDidLoad()
self.podcastPlayerView.isHidden = false "<-------- Unhiding/hiding process successful in this step"
}
override func viewWillDisappear(_ animated: Bool) {
showPodcastButton = false
player?.pause()
player?.replaceCurrentItem(with: nil)
player = nil
}
func setupPodcastPlayer(link: String) {
player?.pause()
player?.replaceCurrentItem(with: nil)
player = nil
if !played {
if link != "" {
playerItem = AVPlayerItem( url:NSURL( string:link )! as URL )
player = AVPlayer(playerItem:playerItem)
player!.rate = 1.0;
player!.play()
played = true
podcastPlay()
} else {
"link empty"
}
} else {
player?.replaceCurrentItem(with: nil)
played = false
}
}
func podcastPlay() {
self.podcastPlayerView.isHidden = false "<---- If I try to unhide here, app crashes."
"Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value"
}
}
extension DetailViewController: PodcastViewCellDelegate {
func podcastButtonClicked(podcastUrl: String) {
podcastPlayerView.isHidden = false
setupPodcastPlayer(link: podcastUrl)
}
}
Спасибо вам за любой совет и хорошего дня!
Ответ №1:
Проблема здесь
DetailViewController().setupPodcastPlayer(link: url)
Это DetailViewController()
новый экземпляр , не представленный, подключите реальный показанный и измените его атрибут по мере необходимости с помощью делегата или уведомления, если вам нужно
Изменить: внутри ячейки
weak var delegate: DetailViewController?
и установите его в cellForRowAt
cell.delegate = self
Комментарии:
1. Спасибо вам за ваш комментарий! Тогда что я должен сделать, это передать URL-адрес с делегатом, а ЗАТЕМ изменить видимость представления, верно?
2. Я обновил код с изменениями делегата. На этот раз мой плеер вообще перестал играть, я думаю, потому что setupPodcastPlayer просто вообще не запускается.
3. Добавьте точки останова и отследите свой код, как и ожидалось, КСТАТИ, это еще одна проблема, на ваш вопрос теперь дан ответ
4. Неужели
cell.delegate = self
?? внутриcellForRowAt
?5. Да, я это заметил и как раз собирался это исправить. Это была преходящая проблема. Метод делегирования работал отлично, спасибо вам за ваши усилия!