1

我必须用 a 替换现有SwiftUI List的视图UICollectionView(因为应用程序设计已更新,新设计对于 SwiftUI 来说非常复杂,因此必须作为自定义实现UICollectionViewFlowLayout

所以视图(现在将是(或一部分)UICollectionViewCell)已经在 SwiftUI 中实现,我不想在 Swift 中重新编写它们。该视图在编写布局代码方面很复杂,使用 SwiftUI 显然很容易。

我可以找到一些帮助来包装像这样的集合视图,但很少了解如何在 UICollectionViewCell 中托管现有的 swift ui 视图

任何帮助/建议/链接将不胜感激。

谢谢

4

1 回答 1

2

我确实做到了。但不确定这是否是正确的解决方案。如果有人有更好的解决方案,请添加您的答案。所以我创建了一个UICollectionViewCell子类。

final class HostingCollectionViewCell: UICollectionViewCell {
    func host<Content: View>(_ hostingController: UIHostingController<Content>) {
        backgroundColor = .clear
        hostingController.view.translatesAutoresizingMaskIntoConstraints = false
        hostingController.view.backgroundColor = .clear
        addSubview(hostingController.view)

        let constraints = [
            hostingController.view.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0),
            hostingController.view.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 0),
            hostingController.view.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0),
            hostingController.view.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: 0),
        ]
        NSLayoutConstraint.activate(constraints)
    }
}

并像使用它一样..

func makeUIView(context: Context) -> UICollectionView {
     let collectionView = UICollectionView(
         frame: .zero,
         collectionViewLayout: MyCustomCollectionViewLayout()
     )
     collectionView.register(HostingCollectionViewCell.self, forCellWithReuseIdentifier: "HostingCell")

     let dataSource = UICollectionViewDiffableDataSource<Section, Member>(collectionView: collectionView) { collectionView, indexPath, member in
         let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HostingCell", for: indexPath) as? HostingCollectionViewCell
         for subview in cell?.contentView.subviews ?? [] {
             subview.removeFromSuperview()
         }

        let swiftUIView = SomeSwiftUIView()
            .onTapGesture {
                // Equivalent of didTapItemAt...
            }

        cell?.host(UIHostingController(rootView: firefighterView))
        return cell
    }

    context.coordinator.dataSource = dataSource
    collectionView.clipsToBounds = false
    collectionView.backgroundColor = .clear
    collectionView.showsVerticalScrollIndicator = false

    // Populated Datasource 

    return collectionView
}

makeUIViewstruct SwiftUICollectionView: UIViewRepresentable观点的一部分。

于 2020-05-20T15:03:53.883 回答