Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift:尝试添加多单元格支持的通用可重用集合视图_Swift_Uitableview_Uicollectionview - Fatal编程技术网

Swift:尝试添加多单元格支持的通用可重用集合视图

Swift:尝试添加多单元格支持的通用可重用集合视图,swift,uitableview,uicollectionview,Swift,Uitableview,Uicollectionview,我跟随几辆车创建了collectionViewDataSource,我对结果非常满意: let dataSource = CollectionViewDataSourceProvider(items: domains, cell: EditDomainsCollectionViewCell.self) { indexPath, item, cell in cell.setup(with: item) }.registerCell(for:

我跟随几辆车创建了collectionViewDataSource,我对结果非常满意:

        let dataSource = CollectionViewDataSourceProvider(items: domains, cell: EditDomainsCollectionViewCell.self) { indexPath, item, cell in
            cell.setup(with: item)
        }.registerCell(for: domainsCollectionView)

        self.datasource = dataSource
        domainsCollectionView.dataSource = datasource
        domainsCollectionView.delegate = datasource
这里是我的dataSourceProvider类:

class CollectionViewDataSourceProvider<Item, Cell: UICollectionViewCell & NibLoadableView>: NSObject, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

    typealias CellConfigurator = (_ indexPath: IndexPath, _ item: Item, _ cell: Cell) -> ()
    typealias SizeConfigurator = (_ indexPath: IndexPath, _ item: Item) -> CGSize
    typealias WidthConfigurator = (_ section: Int) -> CGFloat
    typealias InsetConfigurator = (_ section: Int) -> UIEdgeInsets
    typealias SelectConfigurator = (_ indexPath: IndexPath, _ item: Item) -> ()

    private let items: [Item]
    private let cell: Cell.Type
    private let cellConfigurator: CellConfigurator
    private var sizeConfigurator: SizeConfigurator?
    private var minimumLineSpacingForSectionAtConfigurator: WidthConfigurator?
    private var minimumInteritemSpacingForSectionAt: WidthConfigurator?
    private var insetForSectionAt: InsetConfigurator?
    private var didSelectItemAt: SelectConfigurator?


    init(items: [Item], cell: Cell.Type, cellConfigurator: @escaping CellConfigurator) {
        self.items = items
        self.cell = cell
        self.cellConfigurator = cellConfigurator
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return items.count
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let model = items[indexPath.row]
        let cell = loadNIB()
        return sizeConfigurator?(indexPath, model) ?? cell.frame.size
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return minimumInteritemSpacingForSectionAt?(section) ?? (collectionView.collectionViewLayout as? UICollectionViewFlowLayout)?.minimumLineSpacing ?? 1
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return insetForSectionAt?(section) ?? (collectionView.collectionViewLayout as? UICollectionViewFlowLayout)?.sectionInset ?? UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        didSelectItemAt?(indexPath, items[indexPath.row])
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return minimumLineSpacingForSectionAtConfigurator?(section) ?? (collectionView.collectionViewLayout as? UICollectionViewFlowLayout)?.minimumLineSpacing ?? 1
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let model = items[indexPath.row]
        let cell: Cell = collectionView.dequeueReusableCell(forIndexPath: indexPath)

        cellConfigurator(indexPath, model, cell)
        return cell
    }

    private func loadNIB() -> Cell {
        return Bundle(for: Cell.self as AnyClass).loadNibNamed(String(describing: Cell.self), owner: nil, options: nil)![0] as! Cell
    }

}

extension CollectionViewDataSourceProvider {

    func registerCell(for collectionView: UICollectionView, flowLayout: UICollectionViewFlowLayout? = nil) -> CollectionViewDataSourceProvider {
        collectionView.register(cell)

        if let flowLayout = flowLayout {
            collectionView.setCollectionViewLayout(flowLayout, animated: true)
        }

        return self
    }

    func heightForRow(config: @escaping SizeConfigurator) -> CollectionViewDataSourceProvider {
        sizeConfigurator = config
        return self
    }

    func minimumLineSpacingForSectionAt(config: @escaping WidthConfigurator) -> CollectionViewDataSourceProvider {
        minimumLineSpacingForSectionAtConfigurator = config
        return self
    }

    func minimumInteritemSpacingForSectionAt(config: @escaping WidthConfigurator) -> CollectionViewDataSourceProvider {
        minimumInteritemSpacingForSectionAt = config
        return self
    }

    func insetForSectionAt(config: @escaping InsetConfigurator) -> CollectionViewDataSourceProvider {
        insetForSectionAt = config
        return self
    }

    func didSelectedAt(config: @escaping SelectConfigurator) -> CollectionViewDataSourceProvider {
        didSelectItemAt = config
        return self
    }

}
NibLoadableView协议就是根据这一要点设计的,它可以方便地保存单元格

我希望我的collectionViewDataSourceProvider能够在init中接收UICollectionView单元的数组,如果有多个单元,则为多个单元实现协议逻辑。但我做不到

例如,我试图在数据源中将协议设置为通用参数,但它告诉我该协议不从IUCollectionView继承

我不知道该怎么做谢谢你的帮助

enum CellType {
    case typeOne, typeTwo

   var identifier: String {
       switch self {
           case .typeOne:
               return NSStringFromClass(CellOne.self)
           case .typeTwo:
               return NSStringFromClass(CellTwo.self)
       }
   }
}

protocol CustomElement {
    var type: CellType { get }
}

class MyFirstObject: CustomElement {
    var type: CellType { .typeOne}
}

class MySecondObject: CustomElement {
    var type: CellType { .typeTwo}
}


protocol CellElement where Self: UICollectionViewCell & NibLoadableView {
    func configure(with object: CustomElement)
}

class CellOne: UICollectionViewCell, CellElement, NibLoadableView {
    func configure(with object: CustomElement) {
        guard let object = object as? MySecondObject else { return }
        //
    }
}

class CellTwo: UICollectionViewCell, CellElement, NibLoadableView {
    func configure(with object: CustomElement) {
        guard let object = object as? MyFirstObject else { return }
        //
    }
}