1

我有一个 SwiftUI 视图,它显示一个 UIViewControllerRepresentable,它包含在 NavigationView 中。我已经完成了所有工作,但现在我希望能够在用户点击单元格时从集合视图推送另一个视图。我面临的问题是协调器无权访问导航控制器。有更好的实现吗?

这是最初的 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 中。我知道用宿主控制器的根实例化导航控制器然后推送到它没有任何意义。虽然我不知道该怎么做,但如果有任何帮助,我将不胜感激。

    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)
        }
    }

4

0 回答 0