IOS Rxswift 使用 Kingfisher 预取单元格图片 [英] IOS Rxswift use Kingfisher to prefetch cell Image
问题描述
我正在尝试在 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
数组中获取 models
和 models
的 urls
.谢谢.
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)
最后一点让一切变得干净...... prefetchItems
和 subscribe
之间的一切都可以移动到 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屋!