iOS - Как соответствовать протоколам NSItemProviderWriting и NSItemProviderReading в классе с использованием Generics - PullRequest
0 голосов
/ 21 сентября 2018

Я использую пользовательский класс 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
    }
}

NB: Меня вдохновила очень хорошая статья, демонстрирующая то же использование для UITableView.Я попробовал это на своем UICollectionView, и это фантастика.

В любом случае, я бы хотел обработать Drag and Drop в этом UICollectionView.

.поэтому, если я правильно понимаю методы делегата, мои элементы в UICollectionView должны соответствовать протоколу NSItemProviderWriting и NSItemProviderReading.

Когда я добавил методы протокола, возникла ошибка:

Статические сохраненные свойства не поддерживаются в универсальных типах

Затем я прочитал post , чтобы понять ошибку и попытаться обойти это.

Но я боюсь, что копаюсь в очень сложной области языка.

Может кто-нибудь объяснить мне, как соответствовать этим протоколам с моим классом, используя Generics?

1 Ответ

0 голосов
/ 21 сентября 2018

Связанная статья является частным случаем.Как правило, вам не нужно делать так много, чтобы получить то, что вы пытаетесь сделать.Единственная проблема заключается в том, что вы не можете использовать сохраненные свойства.Вы должны использовать вычисленные свойства.Так, например, если бы вы сделали это (сохраненное свойство):

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...