VIPER アーキテクチャを使用して RxSwift と RxDataSource で iOS アプリを構築しています。プレゼンターの値が変更されたときに UICollectionView の内容を変更したい (ユーザーが searchBar にいくつかの文字を入力したため、collectionView はその文字で始まるすべてのユーザーのプロファイルを表示する必要があります) が、次のようには機能しません。したかった。
debug()
関数を試すとpresenter.section
、searchBar にいくつかの文字を入力した後、ViewController (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)
}
プレゼンターのコード
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 のインスタンスがあり、プレゼンターには というインスタンスがあります
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(....)])])