Arrayのメソッドを持っていて、保持している要素が変化したときにはメッセージを投げる配列っぽいものをつくりました。
最新のRxSwift 2.2に対応しており、PodとCarthageで利用可能です。
基本的な使いかた
こんな感じで宣言します。
var array: ObservableArray<String> = ["foo", "bar", "buzz"]
ObservableArray
には、Rxのメッセージ用のメソッドrx_elements()
とrx_events()
を持っています。
func rx_elements() -> Observable<[Element]> // 要素全体 func rx_events() -> Observable<ArrayChangeEvent> // 差分によるイベント
通常のRxSwiftのようにsubscribe
して使えます。
array.rx_events().subscribeNext { print($0) }
rx_events
は変化した後の配列の要素すべてを投げますので、ここから、次のようにメソッドを呼ぶと、
array.append("coffee") array[2] = "milk" array.removeAll()
次のような結果が表示されるはずです。
["foo", "bar", "buzz", "coffee"] ["foo", "bar", "milk", "coffee"] []
UITableViewでの表示
rx_itemsWithCellIdentifier
と組み合わせると、次のような感じで使えるようになるはずです。
model.rx_elements() .observeOn(MainScheduler.instance) .bindTo(tableView.rx_itemsWithCellIdentifier("MySampleCell")) { (row, element, cell) in guard let c = cell as? MySampleCell else { return } c.model = self.model[row] return } .addDisposableTo(disposeBag)
rx_events
rx_events
は変化の差分の情報を配列を投げます。
ArrayChangeEvent(insertedIndeces: [3], deletedIndeces: [], updatedIndeces: []) ArrayChangeEvent(insertedIndeces: [], deletedIndeces: [], updatedIndeces: [2]) ArrayChangeEvent(insertedIndeces: [], deletedIndeces: [0, 1, 2, 3], updatedIndeces: [])
この結果を見ればわかるように、インデックスベースでの結果が返されます。
なので、UITableView
のinsertRowsAtIndexPaths
、deleteRowsAtIndexPaths
、reloadRowsAtIndexPaths
などを使ってアニメーションも頑張ればできます。
func toIndexSet(array: [Int]) -> [NSIndexPath] { return array.map { NSIndexPath(forRow: $0, inSection: 0) } } self.beginUpdates() self.insertRowsAtIndexPaths(toIndexSet(event.insertedIndeces), withRowAnimation: .Automatic) self.deleteRowsAtIndexPaths(toIndexSet(event.deletedIndeces), withRowAnimation: .Automatic) self.reloadRowsAtIndexPaths(toIndexSet(event.updatedIndeces), withRowAnimation: .Automatic) self.endUpdates()
完全な例はGitHubのReadmeを参照してください。
ちなみに、rx_itemsWithCellIdentifier
が内部でreloadData()
を呼んでしまうので、
アニメーションをしたければrx_itemsWithCellIdentifier
と絡めて利用できませんのでご注意を。
その他
CollectionType
準拠していたりするのでsort
なども使えます。
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。