IOS Rxswift 使用 Kingfisher 预取单元格图像
IOS Rxswift use Kingfisher to prefetch cell Image
我正在尝试在 Rxswift 项目中实现 Kingfisher
预取功能。问题出在这两个函数
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: [=12=].urlString) }
ImagePrefetcher(urls: urls).start()
}
}
我们如何使用 Rxswift 实现?无论如何要从 indexpath
的数组中获取 models
,然后获取 models
的 urls
。谢谢
我将向您介绍我是如何找到解决方案的,以帮助您找到未来的解决方案...
我假设保存 URL 字符串的结构称为 Item
并且您有一个 Observable<[Item]>
当前用于加载 collection 视图。我还假设您的 collection.
中只有一个部分
首先,我们知道当 prefetchItemsAt
发送事件时需要发生一些事情,所以我们从那开始:
let foo = collectionView.rx.prefetchItems
现在检查 foo
的类型,看看它是 ControlEvent<[IndexPath]>
。 ControlEvent 是一种可观察对象。我们只需要 IndexPaths 的 items
部分,所以让 map
即:
let foo = collectionView.rx.prefetchItems
.map { [=11=].map { [=11=].item } }
(双重映射是 Swift 不支持更高种类类型的不幸结果)现在检查 foo
的类型。它是一个 Observable 整数数组。这些整数是我们 items 数组的索引。所以我们需要访问最近发布的项目:
(as above)
.withLatestFrom(items) { indexes, elements in
indexes.map { elements[[=12=]] }
}
所以 withLatestFrom
类似于 combineLatest
除了它仅在主要可观察对象发出值时触发,而不是在辅助可观察对象发出值时触发。
现在,检查 foo
的类型会发现它是一个 Observable 数组。我们要发送到 ImagePrefetcher 的确切项目的 urls。所以我们需要将 urlStrings 提取到 URLs.
(as above)
.map { [=13=].compactMap { URL(string: [=13=].urlString) } }
这样,我们就有了我们希望 ImagePrefetcher 使用的 URL 数组。由于它消耗数据,因此需要将其包装在订阅块中。
(as above)
.subscribe(onNext: {
ImagePrefetcher(urls: [=14=]).start()
})
在这一点上,foo
是一次性的,所以只需要将其收集到我们的处理袋中...这是整个代码块。
collectionView.rx.prefetchItems
.map { [=15=].map { [=15=].item } }
.withLatestFrom(items) { indexes, elements in
indexes.map { elements[[=15=]] }
}
.map { [=15=].compactMap { URL(string: [=15=].urlString) } }
.subscribe(onNext: {
ImagePrefetcher(urls: [=15=]).start()
})
.disposed(by: bag)
最后一点让一切变得干净...prefetchItems
和 subscribe
之间的一切都可以移到 ViewModel 中,如果你有的话。
这里的关键要点是您可以使用类型来指导您,并且您需要知道可以使用哪些运算符来操作 Observables,您可以在 http://reactivex.io/documentation/operators.html
找到这些运算符
我正在尝试在 Rxswift 项目中实现 Kingfisher
预取功能。问题出在这两个函数
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: [=12=].urlString) }
ImagePrefetcher(urls: urls).start()
}
}
我们如何使用 Rxswift 实现?无论如何要从 indexpath
的数组中获取 models
,然后获取 models
的 urls
。谢谢
我将向您介绍我是如何找到解决方案的,以帮助您找到未来的解决方案...
我假设保存 URL 字符串的结构称为 Item
并且您有一个 Observable<[Item]>
当前用于加载 collection 视图。我还假设您的 collection.
首先,我们知道当 prefetchItemsAt
发送事件时需要发生一些事情,所以我们从那开始:
let foo = collectionView.rx.prefetchItems
现在检查 foo
的类型,看看它是 ControlEvent<[IndexPath]>
。 ControlEvent 是一种可观察对象。我们只需要 IndexPaths 的 items
部分,所以让 map
即:
let foo = collectionView.rx.prefetchItems
.map { [=11=].map { [=11=].item } }
(双重映射是 Swift 不支持更高种类类型的不幸结果)现在检查 foo
的类型。它是一个 Observable 整数数组。这些整数是我们 items 数组的索引。所以我们需要访问最近发布的项目:
(as above)
.withLatestFrom(items) { indexes, elements in
indexes.map { elements[[=12=]] }
}
所以 withLatestFrom
类似于 combineLatest
除了它仅在主要可观察对象发出值时触发,而不是在辅助可观察对象发出值时触发。
现在,检查 foo
的类型会发现它是一个 Observable 数组。我们要发送到 ImagePrefetcher 的确切项目的 urls。所以我们需要将 urlStrings 提取到 URLs.
(as above)
.map { [=13=].compactMap { URL(string: [=13=].urlString) } }
这样,我们就有了我们希望 ImagePrefetcher 使用的 URL 数组。由于它消耗数据,因此需要将其包装在订阅块中。
(as above)
.subscribe(onNext: {
ImagePrefetcher(urls: [=14=]).start()
})
在这一点上,foo
是一次性的,所以只需要将其收集到我们的处理袋中...这是整个代码块。
collectionView.rx.prefetchItems
.map { [=15=].map { [=15=].item } }
.withLatestFrom(items) { indexes, elements in
indexes.map { elements[[=15=]] }
}
.map { [=15=].compactMap { URL(string: [=15=].urlString) } }
.subscribe(onNext: {
ImagePrefetcher(urls: [=15=]).start()
})
.disposed(by: bag)
最后一点让一切变得干净...prefetchItems
和 subscribe
之间的一切都可以移到 ViewModel 中,如果你有的话。
这里的关键要点是您可以使用类型来指导您,并且您需要知道可以使用哪些运算符来操作 Observables,您可以在 http://reactivex.io/documentation/operators.html
找到这些运算符