UICollectionViewDataSource

UICollectionViewDataSource

当我尝试快速创建一个实现的通用类UICollectionViewDataSource 时,它说我的类不符合协议(protocol)(有时Xcode崩溃)。

这是否意味着我们无法为UICollectionView创建通用数据提供程序,而必须复制代码?

这是通用代码:

// Enum protocol
protocol OptionsEnumProtocol
{
    typealias T
    static var allValues:[T] {get set}
    var description: String {get}
    func iconName() -> String
}

// enum : list of first available options
enum Options: String, OptionsEnumProtocol
{
    typealias T = Options

    case Color = "Color"
    case Image = "Image"
    case Shadow = "Shadow"

    static var allValues:[Options] = [Color, Image, Shadow]

    var description: String {
        return self.rawValue
    }

    func iconName() -> String
    {
        var returnValue = ""

        switch(self)
        {
            case .Color: returnValue = "color_icon"
            case .Image: returnValue = "image_icon"
            case .Shadow: returnValue = "shadow_icon"
        }

        return returnValue
    }
}

// class to use as the uicollectionview datasource and delegate
class OptionsDataProvider<T>: NSObject, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
{
    private let items = T.allValues

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

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
    {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(OptionsCellReuseIdentifier, forIndexPath: indexPath) as! GenericIconLabelCell

        let item = self.items[indexPath.row]
        // Configure the cell
        cell.iconFileName = item.iconName()
        cell.labelView.text = item.description

        return cell
    }
}

但是因为失败了,所以我不得不改用这种非通用形式:
enum Options: String
{
    case Color = "Color"
    case Image = "Image"
    case Shadow = "Shadow"

    static var allValues:[Options] = [Color, Image, Shadow]

    var description: String {
        return self.rawValue
    }

    func iconName() -> String
    {
        var returnValue = ""

        switch(self)
        {
            case .Color: returnValue = "color_icon"
            case .Image: returnValue = "image_icon"
            case .Shadow: returnValue = "shadow_icon"
        }

        return returnValue
    }
}

class OptionsDataProvider: NSObject, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
{
    private let items = Options.allValues

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

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
    {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(OptionsCellReuseIdentifier, forIndexPath: indexPath) as! GenericIconLabelCell

        let item = self.items[indexPath.row]
        // Configure the cell
        cell.iconFileName = item.iconName()
        cell.labelView.text = item.description

        return cell
    }
}

这使我有义务为我拥有的每个枚举类型重复该类。

确切错误:

最佳答案

没错,不可能编写泛型类。但是,我找到了一种解决方法。它不使用枚举,因此也许您觉得它不是很有用。但是,它可以实现所需的功能-您将获得一个集合 View 数据源,该数据源可以与提供必要数据的不同类一起使用。这是代码:

protocol OptionsProviderProtocol
{
    func allValues() -> [OptionsItem]
}

class OptionsItem:NSObject {
    let itemDescription:String
    let iconName:String

    init(iconName:String,description:String) {
        self.itemDescription = description
        self.iconName = iconName
    }
}

// class stores first available options
class Options: NSObject, OptionsProviderProtocol
{

    let color = OptionsItem(iconName: "color_icon", description: "Color")
    let image = OptionsItem(iconName: "image_icon", description: "Image")
    let shadow = OptionsItem(iconName: "shadow_icon", description: "Shadow")

    func allValues() -> [OptionsItem] {
        return [color, image, shadow]
    }
}

// class to use as the uicollectionview datasource and delegate
class OptionsDataProvider: NSObject, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
{
    private var items:[OptionsItem] = []

    convenience init(optionsProvider:OptionsProviderProtocol) {
        self.items = optionsProvider.allValues()
    }

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

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
    {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(OptionsCellReuseIdentifier, forIndexPath: indexPath) as! GenericIconLabelCell

        let item = self.items[indexPath.row]
        // Configure the cell
        cell.iconFileName = item.iconName()
        cell.labelView.text = item.description

        return cell
    }
}

如果您有任何疑问,请告诉我。

关于ios - 从Swift继承自UICollectionViewDataSource的泛型类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31209235/

10-10 13:57