IOS Rxswift использует Kingfisher для предварительной загрузки изображения ячейки - PullRequest
0 голосов
/ 14 октября 2018

Я пытаюсь реализовать функцию предварительной выборки Kingfisher внутри проекта Rxswift.Проблема с этими двумя функциями

collectionView.rx.prefetchItems
collectionView.rx.cancelPrefetchingForItems

Инструкция в Kingfisher github довольно короткая

override func viewDidLoad() {
    super.viewDidLoad()
    collectionView?.prefetchDataSource = self
}

extension ViewController: UICollectionViewDataSourcePrefetching {
    func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) {
        let urls = indexPaths.flatMap { URL(string: $0.urlString) }
        ImagePrefetcher(urls: urls).start()
    }
}

Как мы можем реализовать с помощью Rxswift?в любом случае, чтобы получить models, а затем urls из models из массива indexpath.Спасибо.

1 Ответ

0 голосов
/ 14 октября 2018

Я расскажу вам, как я нашел решение, чтобы помочь вам выяснить будущие решения ...

Я предполагаю, что структура, содержащая строки URL, называется Item, и выУ вас есть Observable<[Item]>, который вы используете в данный момент для загрузки представления коллекции.Я также предполагаю, что у вас есть только один раздел в вашей коллекции.

Во-первых, мы знаем, что что-то должно произойти, когда prefetchItemsAt отправляет событие, поэтому мы начнем с этого:

let foo = collectionView.rx.prefetchItems

Теперь проверьте тип foo и убедитесь, что это ControlEvent<[IndexPath]>.ControlEvent - это вид наблюдаемого.Нам просто нужна часть items IndexPaths, поэтому давайте map, что:

let foo = collectionView.rx.prefetchItems
    .map { $0.map { $0.item } }

(двойная карта является печальным следствием того, что Swift не поддерживает типы с более высоким типом). Теперь проверьте тип foo.Это наблюдаемый массив целых чисел.Эти целые числа являются индексами в нашем массиве items.Таким образом, нам нужен доступ к последним испущенным элементам:

    (as above)
    .withLatestFrom(items) { indexes, elements in
        indexes.map { elements[$0] }
    }

Таким образом, withLatestFrom похож на combineLatest, за исключением того, что он срабатывает только тогда, когда первичная наблюдаемая дает значение, а не когда вторичная наблюдаемая делает.

Теперь проверка типа foo обнаружит, что это наблюдаемый массив предметов.Точные элементы, URL-адреса которых мы хотим отправить ImagePrefetcher.Поэтому нам нужно извлечь urlStrings в URL-адреса.

    (as above)
    .map { $0.compactMap { URL(string: $0.urlString) } }

И с этим у нас есть массив URL-адресов, который мы хотим использовать ImagePrefetcher.Поскольку он потребляет данные, он должен быть упакован в блок подписки.

    (as above)
    .subscribe(onNext: {
        ImagePrefetcher(urls: $0).start()
    })

На этом этапе foo является одноразовым, поэтому его просто нужно собрать в нашей сумке для утилизации ... Здесьэто весь блок кода.

collectionView.rx.prefetchItems
    .map { $0.map { $0.item } }
    .withLatestFrom(items) { indexes, elements in
        indexes.map { elements[$0] }
    }
    .map { $0.compactMap { URL(string: $0.urlString) } }
    .subscribe(onNext: {
        ImagePrefetcher(urls: $0).start()
    })
    .disposed(by: bag)

Последний бит, чтобы очистить все ... Все между prefetchItems и subscribe можно переместить в ViewModel, если у вас есть.

Ключевым моментом здесь является то, что вы можете использовать типы, чтобы направлять вас, и вам нужно знать, какие операторы доступны для манипулирования наблюдаемыми объектами, которые вы можете найти в http://reactivex.io/documentation/operators.html

...