如何使用 UIViewControllerRepresentable 在 SwiftUI 中呈现 UICollectionView

Posted

技术标签:

【中文标题】如何使用 UIViewControllerRepresentable 在 SwiftUI 中呈现 UICollectionView【英文标题】:How to present a UICollectionView in SwiftUI with UIViewControllerRepresentable 【发布时间】:2020-04-25 11:06:42 【问题描述】:

首先,我知道有一些选项可以使用 SwiftUI 列表等...获得类似的效果。但我需要 UICollectionView 的自动滚动功能,所以我真的很想实现一个“老派”版本。我什至不想要理想的组合布局版本。

我当前的代码如下所示:

import SwiftUI

struct CollectionView: UIViewControllerRepresentable 

private var isActive: Binding<Bool>
private let viewController = UIViewController()
private let collectionController: UICollectionView

init(_ isActive: Binding<Bool>) 
    self.isActive = isActive
    self.collectionController = UICollectionView(frame: CGRect(x: 0, y: 0, width: 100, height: 200), collectionViewLayout: UICollectionViewFlowLayout())

func makeUIViewController(context: UIViewControllerRepresentableContext<CollectionView>) -> UIViewController 
    return viewController


func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<CollectionView>) 
    if self.isActive.wrappedValue && collectionController.delegate == nil  // to not show twice
        collectionController.delegate = context.coordinator
        collectionController.dataSource = context.coordinator
    


func makeCoordinator() -> Coordintor 
    return Coordintor(owner: self)


final class Coordintor: NSObject, UICollectionViewDelegate, UICollectionViewDataSource 
    weak var viewController:UIViewController?
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return 3
    
    var cellId = "Cell"
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath)
        return cell
    
    // works as delegate
    let owner: CollectionView
    init(owner: CollectionView) 
        self.owner = owner

    


不幸的是,我得到的只是预览中的空白屏幕。现在,如果我可以显示大量红色方块,我可以滚动浏览并自动滚动到底部 onAppear,那将是理想的。

谢谢!

【问题讨论】:

【参考方案1】:

这是最小的可运行演示。 (注意:如果一切都以编程方式完成,则必须注册单元

class MyCell: UICollectionViewCell 


struct CollectionView: UIViewRepresentable 
    func makeUIView(context: Context) -> UICollectionView 
        let view = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
        view.backgroundColor = UIColor.clear
        view.dataSource = context.coordinator

        view.register(MyCell.self, forCellWithReuseIdentifier: "myCell")
        return view
    

    func updateUIView(_ uiView: UICollectionView, context: Context) 
    

    func makeCoordinator() -> Coordinator 
        Coordinator()
    

    class Coordinator: NSObject, UICollectionViewDataSource 
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
            3
        

        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "myCell", for: indexPath) as! MyCell
            cell.backgroundColor = UIColor.red
            return cell
        
    


struct TestUICollectionView_Previews: PreviewProvider 
    static var previews: some View 
        CollectionView()
    

【讨论】:

以上是关于如何使用 UIViewControllerRepresentable 在 SwiftUI 中呈现 UICollectionView的主要内容,如果未能解决你的问题,请参考以下文章

如何使用本机反应创建登录以及如何验证会话

如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]

如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?

如何使用laravel保存所有行数据每个行名或相等

如何使用 Math.Net 连接矩阵。如何使用 Math.Net 调用特定的行或列?

WSARecv 如何使用 lpOverlapped?如何手动发出事件信号?