У меня есть 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)
}
}