IOS Rxswift 使用 Kingfisher 预取单元格图片 [英] IOS Rxswift use Kingfisher to prefetch cell Image

查看:79
本文介绍了IOS Rxswift 使用 Kingfisher 预取单元格图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 Rxswift 项目中实现 Kingfisher 预取功能.问题在于这两个函数

I'm trying to implement Kingfisher prefetch feature inside an Rxswift project. The problem is with these 2 function

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 实现?无论如何要从 indexpath 数组中获取 modelsmodelsurls.谢谢.

How can we implement with Rxswift? anyway to get the models and then the urls of models from array of indexpath. Thank.

推荐答案

我将带您了解我是如何找到解决方案的,以帮助您找出未来的解决方案...

I will walk you thru how I figured out the solution to help you figure out future solutions...

我假设保存 URL 字符串的结构称为 Item 并且您有一个 Observable<[Item]> 您当前正在使用它加载集合视图.我还假设您的收藏中只有一个部分.

I'm assuming that the struct that holds the URL strings is called Item and that you have an Observable<[Item]> that you are currently using to load up the collection view. I'm also assuming that you only have one section in your collection.

首先,我们知道当 prefetchItemsAt 发送一个事件时需要发生一些事情,所以我们从那个开始:

First, we know that something needs to happen when the prefetchItemsAt sends an event so we start with that:

let foo = collectionView.rx.prefetchItems

现在检查 foo 的类型,看它是 ControlEvent<[IndexPath]>.ControlEvent 是一种可观察的.我们只需要 IndexPaths 的 items 部分,所以让 map :

Now inspect the type of foo to see that it is a ControlEvent<[IndexPath]>. A ControlEvent is a kind of observable. We just need the items part of the IndexPaths, so lets map that:

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

(双映射是 Swift 不支持更高级类型的不幸结果)现在检查 foo 的类型.它是一个可观察的整数数组.这些整数是我们 items 数组的索引.所以我们需要访问最近发布的项目:

(The double map is an unfortunate consequence of Swift not supporting higher kinded types) Now inspect the type of foo. It is an Observable array of ints. Those ints are indexes into our items array. So we need access to the most recently emitted items:

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

所以 withLatestFrom 就像 combineLatest 不同之处在于它只在主要 observable 发出值时触发,而不是在次要 observable 发出值时触发.

So withLatestFrom is like combineLatest except it only fires when the primary observable emits a value, not when the secondary observable does.

现在,检查 foo 的类型会发现它是一个 Observable 的 Items 数组.我们要发送到 ImagePrefetcher 的确切项目的 url.所以我们需要将urlStrings提取成URLs.

Now, inspecting the type of foo will find that it's an Observable array of Items. The exact items who's urls' we want to send to the ImagePrefetcher. So we need to extract the urlStrings into URLs.

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

这样,我们就有了希望 ImagePrefetcher 使用的 URL 数组.由于它消耗数据,因此需要将其包装在订阅块中.

And with that, we have the array of URLs we want ImagePrefetcher to consume. Since it consumes data, it needs to be wrapped it in a subscribe block.

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

在这一点上,foo 是一次性的,所以它只需要收集在我们的处理袋中......这是整个代码块.

At this point, foo is a disposable so it just needs to be collected in our dispose bag... Here is the entire block of code.

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)

最后一点让一切变得干净...... prefetchItemssubscribe 之间的一切都可以移动到 ViewModel 中(如果你有的话).

One last bit to make everything clean... Everything between prefetchItems and the subscribe can be moved into the ViewModel if you have one.

这里的关键是你可以使用类型来指导你,你需要知道哪些操作符可以用来操作 Observables,你可以在 http://reactivex.io/documentation/operators.html

The key takeaway here is that you can use the types to guide you, and you need to know what operators are available to manipulate Observables which you can find at http://reactivex.io/documentation/operators.html

这篇关于IOS Rxswift 使用 Kingfisher 预取单元格图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆