我正在使用自定义类 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
中处理拖放。
为此,如果我正确理解委托(delegate)方法,我在 UICollectionView 中的项目需要符合 NSItemProviderWriting
和 NSItemProviderReading
协议(protocol)。
当我添加协议(protocol)方法时,出现以下错误:
Static stored properties not supported in generic types
然后我读了这个post了解错误并尝试绕过它。
但恐怕我正在深入研究该语言的一个非常复杂的领域。
有人可以向我解释如何使用泛型让我的类符合这些协议(protocol)吗?
最佳答案
链接的文章是一个特例。通常,您不需要做太多事情来获得您想要做的事情。唯一的问题是您不能使用存储的属性。您必须使用计算属性。因此,例如,如果您这样做(存储的属性):
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
。
关于iOS - 如何使用泛型在类上遵守 NSItemProviderWriting 和 NSItemProviderReading 协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52444462/