Swift — Не удается скрыть или отобразить UIView, учитывая, что я его вижу

#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. Да, я это заметил и как раз собирался это исправить. Это была преходящая проблема. Метод делегирования работал отлично, спасибо вам за ваши усилия!