我有一个 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)
}
}