Как Pu sh ViewController из indexPath didSelectItemAt на UICollectionViewController? - PullRequest
0 голосов
/ 16 февраля 2020

Что происходит, я получаю черный экран, а не детальный вид, который я ожидаю. Что странно, это работало, прежде чем я переключился на DiffableDataSource. Во время выполнения произошла фиолетовая ошибка с восклицательным знаком, приложенная фотография показывает результат. Это единственный XIB в проекте, и нет очевидных отсутствующих выходных соединений, предупреждений об автоматическом размещении или даже тех вещей, которые выглядят неправильно. Вы можете видеть, что я пробовал делегатов, DispathQueue.main.asyn c и просто используя свойство navigationController. Тот же результат каждый раз, когда черный экран.

    import UIKit

protocol GifCollectionDelegate: AnyObject
{
    func push(screen: UIViewController)
}

class GifCollection: UICollectionViewController
{
    let favorites: Favorites
    weak var delegate: GifCollectionDelegate?

    init(layout: GifsLayout, favorites: Favorites) {
        self.favorites = favorites
        super.init(collectionViewLayout: layout)
        collectionView.register(GifCell.self, forCellWithReuseIdentifier: GifCell.cellId) //FIXME: Remove static
        collectionView.backgroundColor = .gray
        collectionView.delegate = self
    }
    required init?(coder: NSCoder) { fatalError() }

    override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        guard delegate != nil else { fatalError() }
        //FIXME: Remove Casting, framework is the cause
        guard let cell = collectionView.cellForItem(at: indexPath) as? GifCell else { fatalError() }

        print("didSelectItemAt Index")
        print("cell.contentView.frame: \(cell.contentView.frame)")
        print("GifCollection.frame: \(view.frame)")

        //FIXME: Scene of the Crime
        //guard parent.navigationController?.pushViewController(, animated: true) != nil else { fatalError() }

//        DispatchQueue.main.async {
//            self.parent?.navigationController?.pushViewController(GifDetailScreen(gif: gif, favorites: self.favorites), animated: true)
//        }
        let gifDetailScreen = GifDetailScreen(gif: cell.localGif(), favorites: favorites)
        delegate?.push(screen: gifDetailScreen)
    }
}

Вот экран трендов, в который встроен CollectionViewController. Этот TrendingScreen является в настоящее время тем, что толкает detailScreen с помощью метода делегата.

import UIKit

class TrendingScreen: UIViewController
{
    let searchEngine: SearchEngine
    let gifsScreen: GifCollection
    let data: TrendingScreenData
    let apiKey: String

    init(searchEngine: SearchEngine, gifsScreen: GifCollection, data: TrendingScreenData, apiKey: String) {
        self.searchEngine = searchEngine
        self.gifsScreen = gifsScreen
        self.data = data
        self.apiKey = apiKey
        super.init(nibName: nil, bundle: nil)
        guard let tornado = UIImage(systemName: "tornado") else { fatalError() }
        tabBarItem = UITabBarItem(title: "Trending", image: tornado, tag: 1)
        title = "Trending"
        navigationItem.searchController = searchEngine
        navigationItem.hidesSearchBarWhenScrolling = false
        searchEngine.searchBar.delegate = self  //FIXME: Confirm
        gifsScreen.delegate = self
    }
    required init?(coder: NSCoder) { fatalError("Son, Just don't") }

    override func viewDidLoad() {
        super.viewDidLoad()
        embed(viewController: gifsScreen, inContainerView: view)
    }
}

extension TrendingScreen: GifCollectionDelegate
{
    func push(screen: UIViewController) {
        navigationController?.pushViewController(screen, animated: true)
    }
}

Вот источник данных для collectionView. инициализатор уникален для DiffableDataSource.

import UIKit

class TrendingScreenData
{
    let diffableData: UICollectionViewDiffableDataSource<Section, LocalGif>
    let gyphyURL: GyphyUrl
    let gifsScreen: GifCollection

    init(gyphyURL: GyphyUrl, gifsScreen: GifCollection, favorites: Favorites) {
        self.gyphyURL = gyphyURL
        self.gifsScreen = gifsScreen
        self.diffableData = UICollectionViewDiffableDataSource<Section, LocalGif>(collectionView: gifsScreen.collectionView) {
            (collectionView, indexPath, gif) -> UICollectionViewCell? in
                guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: GifCell.cellId, for: indexPath) as? GifCell else { fatalError() }//FIXME: Remove Static
                let gifPlayer = GifPlayer(bounds: cell.contentView.bounds, gif: gif, favorites: favorites)
                gifsScreen.embed(viewController: gifPlayer, inContainerView: cell.contentView)
                cell.gifPlayer = gifPlayer  //FIXME: Be Immutable, this is gross

                return cell
        }
    }

    func start() {
        let url = gyphyURL.url()    //FIXME: Naming
        let request = URLRequest(url: url)
        let session = URLSession.shared
        let decoder = JSONDecoder()
        decoder.keyDecodingStrategy = .convertFromSnakeCase
        let gyphyResponseDownload = session.dataTask(with: request) { data, response, error in
            do {
                guard let data = data else { fatalError() }
                let gyphyResponse = try decoder.decode(GyphyResponse.self, from: data)
                var snapshot = NSDiffableDataSourceSnapshot<Section, LocalGif>() //FIXME: Be Immutable
                let gifs = gyphyResponse.gifs
                var localGifs = [LocalGif]()    //FIXME: Vars
                for gif in gifs { localGifs.append(LocalGif(gif: gif)) }
                snapshot.appendSections([.main])
                snapshot.appendItems(localGifs)
                self.diffableData.apply(snapshot, animatingDifferences: true, completion: nil)
            }
            catch {
                print(error.localizedDescription)
                fatalError()
            }
        }
        gyphyResponseDownload.resume()
    }
}

Здесь все построено ...

import UIKit

class GyphsApp: BlackTabScreen
{
    let apiKey: String
    let favorites: Favorites

    init(apiKey: String, favorites: Favorites) {
        self.favorites = favorites
        self.apiKey = apiKey
        super.init()
        viewControllers = [trendingScreen(), favoritesScreen()]
        selectedIndex = 0
    }
    required init?(coder: NSCoder) { fatalError() }

    func trendingScreen() -> UINavigationController {
        let trendingURL = GyphyTrendingUrl(limit: 10, rating: .G, apiKey: apiKey)
        let gifsScreen = GifCollection(layout: GifsLayout(junk: 1), favorites: favorites) //FIXME: remove junk
        let data = TrendingScreenData(gyphyURL: trendingURL, gifsScreen: gifsScreen, favorites: favorites)
        data.start() //FIXME: Fragile Api
        let sE = SearchEngine(searchResultsScreen: nil)
        let trendingScreen = TrendingScreen(searchEngine: sE, gifsScreen: gifsScreen, data: data, apiKey: apiKey)
        let nav = BlackNav(screen: trendingScreen)
        return nav
    }

    func favoritesScreen() -> UINavigationController {
        let gifsScreen = GifCollection(layout: GifsLayout(junk: 1), favorites: favorites) //FIXME: remove junk
        let data = FavoriteScreenData(favorites: favorites, gifsScreen: gifsScreen)
        data.start()                //FIXME: Fragile Api
        favorites.delegate = data   //FIXME: Delegate gets set here
        let favsScreen = FavoritesScreen(gifsScreen: gifsScreen, data: data) //Delegate is still set
        let nav = BlackNav(screen: favsScreen)
        return nav
    }
}

Пожалуйста, сообщите.

...