【发布时间】:2019-01-29 15:14:57
【问题描述】:
我正在使用 VIPER 架构构建一个带有 RxSwift 和 RxDataSource 的 iOS 应用程序。我想更改 UICollectionView 的内容,因为演示者的值发生变化(当用户在 searchBar 中输入一些字母时,collectionView 应该显示所有以字母开头的用户的个人资料),但它不能作为我想要它。
通过尝试debug() 函数,在我在searchBar 中输入一些字母后,ViewController 中presenter.section 的值(它保存了CollectionView 的内容)发生了变化。但是,collectionView 并未反映更改。
以下是代码的主要部分。
ViewController的代码
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white
self.presenter.section
.drive(self.searchedFriendsCollectionView.rx.items(dataSource: self.dataSource))
.disposed(by: self.disposeBag)
self.searchedFriendsCollectoinView.rx
.setDelegate(self)
.disposed(by: self.disposeBag)
}
Presenter 代码
init(view: SearchFriendsViewInterface, interactor:
SearchFriendsInteractorInterface, wireframe:
SearchFriendsWireframeInterface) {
self.view = view
self.interactor = interactor
self.wireframe = wireframe
let allUsers = self.interactor.allUsers().asObservable()
self.view.searchText
.debounce(0.5)
.filterNil()
.distinctUntilChanged()
.filterEmpty()
.asObservable()
.flatMap { text -> Observable<[SearchFriendsSection]> in
// get all users starting with "text"
allUsers.mapSections(query: text)
}
.bind(to: self.section)
.disposed(by: self.disposeBag)
}
extension Observable where E == [User] {
fileprivate func mapSections(query: String) -> Observable<[SearchFriendsSection]> {
return self.map {
$0.filter { $0.userDisplayName.hasPrefix(query) || $0.username.hasPrefix(query) }
}
.map { users -> [SearchFriendsSection] in
let items = users.map { user in
SearchFriendsItem(icon: user.profileImageURL, displayName: user.userDisplayName)
}
return [SearchFriendsSection(items: items)]
}
}
}
我如何定义dataSource
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
self.searchedFriendsCollectoinView = UICollectionView(frame: .init(), collectionViewLayout: self.searchedFriendsCollectionViewFlowLayout)
let dataSource = RxCollectionViewSectionedReloadDataSource<SearchFriendsSection> (configureCell: {(_, collectionView, indexPath, item) -> UICollectionViewCell in
collectionView.register(SearchFriendsCell.self, forCellWithReuseIdentifier: "SearchFriendsCell")
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SearchFriendsCell", for: indexPath) as! SearchFriendsCell
cell.item = item
return cell
})
self.dataSource = dataSource
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
- ViewController 有 Presenter 的实例,而 Presenter 有一个名为
section的实例。这个section包含用户名以特定字母开头的用户列表。
你能帮帮我吗?如果我有任何不清楚的地方,请在评论中告诉我。
更新:debug() 的输出
2019-02-01 10:22:27.610: values -> subscribed
2019-02-01 10:22:27.611: values -> Event next([])
--after typed in some letters in the searchBar--
2019-02-01 10:22:41.494: values -> Event
next([AppScreen.SearchFriendsSection(items:
[AppScreen.SearchFriendsItem(....),
AppScreen.SearchFriendsItem(....),
AppScreen.SearchFriendsItem(....)])])
【问题讨论】:
-
如果您将
debug()调用放在绑定/驱动/订阅表视图本身的数据源之前。它的输出是什么? -
Daniel T. 看起来
self.dataSource在我输入了一些字母后也没有改变,它被处理掉了。但是self.dataSource跟UICollectionView的内容有关系吗? -
如果驱动/绑定到你的数据源的链被释放,那么它就不能再发出新的值了。您的链中的 Observable 正在发送停止事件(完成/错误),或者正在从绑定/订阅/驱动器调用一次性的 dispose()。
-
抱歉
self.dataSource没有改变(因为它是let)但是当我在ViewController 中将debug()放在drive()之前,新元素被发射了。你知道为什么 CollectionView 的内容没有改变吗? -
我想我不是很清楚...在视图控制器中的
self.presenter.section行和.drive(self.searchedFriendsCollectionView.rx.items(dataSource: self.dataSource))行之间放置一个.debug("values"),并将该调试的输出发布到您的问题。
标签: swift uicollectionview rx-swift viper-architecture rxdatasources