3

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(....)])])
4

3 に答える 3