【问题标题】:iOS - How to conform to NSItemProviderWriting and NSItemProviderReading protocol on class using GenericsiOS - 如何在使用泛型的类上遵守 NSItemProviderWriting 和 NSItemProviderReading 协议
【发布时间】:2018-09-21 13:06:35
【问题描述】:

我正在使用自定义类 CollectionViewConfigurator 以通用方式处理我的 CollectionViewCell 的配置。

它运行良好,这是示例类:

protocol ConfigurableCell {

    static var reuseIdentifier: String { get }

    associatedtype DataType

    func configure(data: DataType)
}

extension ConfigurableCell {
    static var reuseIdentifier: String { return String(describing: Self.self) }
}

protocol CellConfigurator {
    static var reuseId: String { get }
    func configure(cell: UIView)
    var hash: Int { get }
}

class CollectionViewCellConfigurator<CellType: ConfigurableCell, DataType: Hashable>: CellConfigurator where CellType.DataType == DataType, CellType: UICollectionViewCell {

    static var reuseId: String { return CellType.reuseIdentifier }

    let item: DataType

    init(item: DataType) {
        self.item = item
    }

    func configure(cell: UIView) {
        (cell as! CellType).configure(data: item)
    }

    var hash: Int {
        return String(describing: CellType.self).hashValue ^ item.hashValue
    }
}

extension Int: Diffable {
    public var diffIdentifier: AnyHashable {
        return self
    }
}

注意:我受到了一篇非常好的文章的启发,该文章展示了 UITableView 的相同用法。我在我的UICollectionView 上尝试过,非常棒。

无论如何,我想处理这个UICollectionView中的拖放

为此,如果我正确理解了委托方法,我在 UICollectionView 中的项目需要符合 NSItemProviderWritingNSItemProviderReading 协议。

当我添加协议方法时,出现以下错误:

泛型类型不支持静态存储属性

然后我阅读了这个post 以了解错误并尝试绕过它。

但恐怕我正在深入研究该语言的一个非常复杂的领域。

有人可以解释我如何使用泛型来遵守这些协议吗?

【问题讨论】:

    标签: ios swift generics drag-and-drop protocols


    【解决方案1】:

    链接的文章是一个特例。一般来说,你不需要做太多事情来获得你想要做的事情。唯一的问题是您不能使用存储的属性。您必须使用计算属性。例如,如果你会这样做(一个存储的属性):

    static let writableTypeIdentifiersForItemProvider = ["public.url"]
    

    您只需要这样做(等效的计算属性):

    static var writableTypeIdentifiersForItemProvider: [String] { return ["public.url"] }
    

    链接的文章解决了您需要属性可写的情况,这意味着您需要为其提供存储空间,但这种情况很少见。

    在实践中,如果您希望CellConfigurator 符合NSItemProviderWriting,那么它看起来像:

    protocol CellConfigurator: NSItemProviderWriting { ... }
    

    然后CollectionViewCellConfigurator需要从NSObject继承(才能得到NSObjectProtocol):

    class CollectionViewCellConfigurator<CellType: ConfigurableCell, DataType: Hashable>: NSObject ...
    

    也就是说hash需要加上override

    override var hash: Int { ... }
    

    最后,您将实现 NSItemProviderWriting 方法:

    static var writableTypeIdentifiersForItemProvider: [String] { return [...] }
    
    func loadData(withTypeIdentifier typeIdentifier: String, forItemProviderCompletionHandler completionHandler: @escaping (Data?, Error?) -> Void) -> Progress? {
        // ...
    }
    

    (其中... 是您想要的这种类型)

    NSItemProviderReading 也是如此。

    【讨论】:

    • 好的,我知道了。谢谢你的澄清。但我仍然不知道如何遵守这些协议......
    • 我不明白这个问题。如果这种类型不是通用的,您是否了解如何符合?它是通用的唯一影响应该是需要计算静态属性(如writableTypeIdentifiersForItemProvider)。您在上面列出的错误是您收到的唯一错误吗?
    猜你喜欢
    • 2014-08-18
    • 2022-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-03
    相关资源
    最近更新 更多