iOS - 如何使用泛型在类上遵守 NSItemProviderWriting 和 NSItemProviderReading 协议(protocol)

标签 ios swift generics drag-and-drop protocols

我正在使用自定义类 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 中的项目需要符合 NSItemProviderWritingNSItemProviderReading 协议(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/

相关文章:

iPhone 从 iPod 应用程序获取视频

ios - 考虑到操作系统会在 30 秒内关闭应用程序,Whatsapp 的网络版本如何在 iOS 设备上运行?

ios - 扩展 SDWebImage 缓存大小

Java 泛型不一致的行为?

scalac 在 org.squeryl.Table 中找不到正确的插入方法

iphone - 将 JSON 属性响应转换为 BOOL

ios - tapGestureRecognizer.location 在 UICollectionView 中带来 nil

ios - 在点击手势时显示 UIPickerView

c# - 将类型传递给方法以在泛型中使用

ios - 如何安装react-native-track-player