Pu sh NavigationController из UIViewControllerRepresentable - PullRequest
1 голос
/ 19 июня 2020

У меня есть SwiftUI View, который отображает UIViewControllerRepresentable, заключенный в NavigationView. У меня все работает так, как я хочу, хотя теперь я хочу иметь возможность pu sh из коллекции просматривать другое представление, когда пользователь нажимает на ячейку. Проблема, с которой я столкнулся, заключается в том, что у координатора нет доступа к контроллеру навигации. Есть ли лучшая реализация для этого?

Это начальное представление SwiftUI

    import SwiftUI

    struct ExploreView: View {

        @ObservedObject var exploreViewVM = ExploreViewViewModel()

        var body: some View {
            NavigationView {
                CollectionView(products: exploreViewVM.products)
            }
        }
    }

    struct ExploreView_Previews: PreviewProvider {
        static var previews: some View {
            ExploreView()
        }
    }

Это оболочка collectionView. Как вы можете видеть в функции didSelectItemAt, я пытаюсь обернуть представление в HostingController. Я знаю, что нет никакого смысла создавать экземпляр контроллера навигации с помощью root хост-контроллера, а затем pu sh к нему. Хотя я не уверен, как go об этом, и был бы признателен за любую помощь.

    import SwiftUI
    import SDWebImage

    struct CollectionView: UIViewControllerRepresentable {

        var products: [Product]
        let cellId = "cellId"

        typealias UIViewControllerType = UICollectionViewController

        func makeUIViewController(context: Context) -> UICollectionViewController {
            let collectionView = UICollectionViewController(collectionViewLayout: createLayout())
            collectionView.collectionView.backgroundColor = .white
            collectionView.collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: cellId)

            collectionView.collectionView.dataSource = context.coordinator
            collectionView.collectionView.delegate = context.coordinator
            return collectionView
        }

        func createLayout() -> UICollectionViewCompositionalLayout {
            return UICollectionViewCompositionalLayout { sectionNumber, env in
                let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(0.3333), heightDimension: .fractionalWidth(0.3333)))
                    item.contentInsets.trailing = 1
                    item.contentInsets.bottom = 1

                let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .estimated(500)), subitems: [item])
                    group.contentInsets.leading = 1
                    let section = NSCollectionLayoutSection(group: group)

                    return section
            }
        }

        func updateUIViewController(_ uiViewController: UICollectionViewController, context: Context) {

        }

        class Coordinator: NSObject, UICollectionViewDataSource, UICollectionViewDelegate {
            func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
                return parent.products.count
            }

            func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: parent.cellId, for: indexPath)

                let imageView = UIImageView()
                imageView.contentMode = .scaleAspectFill
                imageView.layer.masksToBounds = true
                imageView.sd_setImage(with: URL(string: parent.products[indexPath.item].imageUrl)) { (image, _, _, _) in
                    imageView.image = image
                }

                cell.backgroundView = imageView
                return cell
            }

            func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
                let controller = UIHostingController(rootView: ProductView(product: parent.products[indexPath.item]))
                let navigation = UINavigationController(rootViewController: controller)
            navigation.pushViewController(controller, animated: true)
            }

            let parent: CollectionView

            init(_ parent: CollectionView) {
                self.parent = parent
            }

        }

        func makeCoordinator() -> Coordinator {
            Coordinator(self)
        }
    }

...