2016-04-04 14 views
1

私はRXSwiftとMVVMを使ってiPad用のアプリケーションを作っています。UICollectionViewControllerのための適切なMVVMアーキテクチャは何ですか

私はcollectionViewのためのデータソースとデリゲートとして機能しUICollectionViewとのViewModelとのUIViewControllerを持っています。

コレクションセルの機能の一部は、ボタンをタップしてポップオーバーを提示するときの機能です。今度はiOS 9の新しいポップオーバー機能(以前のバージョン)では、通常はビューコントローラ内でビューを表示し、popoverPresentationControllerを変更する必要があります。

は今、私の知る限り承知しているとして、あなたはUICollectionViewCellからのUIViewControllerを提示することができません。意味をなさない

私はこれを行うと思った唯一の方法は、ViewControllerを指すデリゲートを持つことです。

クラス図(添付)を見ると、viewModelはセルのデキュー時にデリゲートを設定する必要があります。これを行うには、ViewModelはどのViewControllerをデリゲートとして設定するかを知っていなければならないでしょう。私はかなり確信していますが、viewModelのポイントに逆らっています。 MVVM(iOSの場合)によれば、ビューモデルはビューコントローラについて知ってはいけません。ビューコントローラは、ビューモデルについて知ることができます。

そして私の質問は、MVVMの後にこれを行うための最良の方法は何でしょうか? dataSource/Delegateを別のクラスに移動する必要がある場合は、それをすべて行います。

UML Diagram

答えて

1

私は、ビューモデルは、すべてのタップされているボタンを認識すべきではないと思います。タッチイベントの処理は、ビューレイヤに属し、ポップオーバーを提示します。

また、これはあなたのビューモデルはおそらくUICollectionViewDataSourceすべきではないことを示しています。したがって、これはビューであるRootCollectionViewCellと結合されています。 AppleがUICollectionViewDataSourceをこのように設計したため、このカップリングは避けがたいです。別のクラスをデータソースとして抽出するか、データソースメソッドをビューコントローラ(iOSのMVVMのビューレイヤに属します)に残します。 RxCocoaを使用して

、あなたもまったくUICollectionViewDataSourceのメソッドを実装避けることができます。 UICollectionView+Rxの内線番号をご覧ください。 example in RxSwift repository(コレクションビューを含むテーブルビューセル)もあります。

ビューコントローラのボタンのタップを渡すためには、観測rx_tapを使用することができますし、セルのインターフェイスでそれを公開します。次に、ビューコントローラに(又は別のデータソースクラスで)得Observableを購読することができ:

//in the cell class 
var buttonTapped : ControlEvent<Void> { 
    return button.rx_tap 
} 

//in the data source 
cell.buttonTapped.subscribeNext { 
    //show the popover 
}.addDisposableTo(cell.disposeBag) 

this answerで説明したように、セルを再利用するときに、同じ観測に何回も加入避けるべきです。そのため、上記のコードでcell.disposeBagが使用されています。 prepareForReuseメソッドでセルのdisposeBagも再作成する必要があります。

class RootCollectionViewCell: UICollectionViewCell { 

    var disposeBagCell:DisposeBag = DisposeBag() 

    ... 

    override func prepareForReuse() { 
     disposeBagCell = DisposeBag() 
    } 

} 
関連する問題