ObservableArray-RxSwift 0.2.0

ObservableArray-RxSwift 0.2.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最后发布2017年11月
SwiftSwift 版本4.0
SPM支持 SPM

MATSUMOTO Yuji 维护.



  • 作者
  • MATSUMOTO Yuji

ObservableArray-RxSwift

ObservableArray 是一个数组,在修改时会发出元素和差异的消息。

用法

ObservableArray 有两个 Observable

func rx_elements() -> Observable<[Element]>
func rx_events() -> Observable<ArrayChangeEvent>

rx_elements

rx_elements() 在修改时发出自己的元素。

var array: ObservableArray<String> = ["foo", "bar", "buzz"]
array.rx_elements().subscribeNext { print($0) }

array.append("coffee")
array[2] = "milk"
array.removeAll()

这将打印

["foo", "bar", "buzz"]
["foo", "bar", "buzz", "coffee"]
["foo", "bar", "milk", "coffee"]
[]

请注意,由于它通过使用 BehaviorSubject 实现,当它已订阅时,rx_elements() 会首先发出当前项。

rx_elements 可以与 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

var array: ObservableArray<String> = ["foo", "bar", "buzz"]
array.rx_events().subscribeNext { print($0) }

array.append("coffee")
array[2] = "milk"
array.removeAll()

这将打印

ArrayChangeEvent(insertedIndices: [3], deletedIndices: [], updatedIndices: [])
ArrayChangeEvent(insertedIndices: [], deletedIndices: [], updatedIndices: [2])
ArrayChangeEvent(insertedIndices: [], deletedIndices: [0, 1, 2, 3], updatedIndices: [])

ArrayChangeEvent 定义为

struct ArrayChangeEvent {
    let insertedIndices: [Int]
    let deletedIndices: [Int]
    let updatedIndices: [Int]
}

这些索引可以与表视图方法一起使用,例如 insertRowsAtIndexPaths(_:withRowAnimation:)。例如,以下代码将在源数组修改时启用单元格动画。

extension UITableView {
    public func rx_autoUpdater(source: Observable<ArrayChangeEvent>) -> Disposable {
        return source
            .scan((0, nil)) { (a: (Int, ArrayChangeEvent!), ev) in
                return (a.0 + ev.insertedIndices.count - ev.deletedIndices.count, ev)
            }
            .observeOn(MainScheduler.instance)
            .subscribeNext { sourceCount, event in
                guard let event = event else { return }

                let tableCount = self.numberOfRowsInSection(0)
                guard tableCount + event.insertedIndices.count - event.deletedIndices.count == sourceCount else {
                    self.reloadData()
                    return
                }

                func toIndexSet(array: [Int]) -> [NSIndexPath] {
                    return array.map { NSIndexPath(forRow: $0, inSection: 0) }
                }

                self.beginUpdates()
                self.insertRowsAtIndexPaths(toIndexSet(event.insertedIndices), withRowAnimation: .Automatic)
                self.deleteRowsAtIndexPaths(toIndexSet(event.deletedIndices), withRowAnimation: .Automatic)
                self.reloadRowsAtIndexPaths(toIndexSet(event.updatedIndices), withRowAnimation: .Automatic)
                self.endUpdates()
            }
    }
}

您可以在视控制器中使用 rx_autoUpdater(_:)bindTo(_:)

model.rx_events()
    .observeOn(MainScheduler.instance)
    .bindTo(tableView.rx_autoUpdater)
    .addDisposableTo(disposeBag)

不幸的是,由于它内部使用 reloadData()rx_autoUpdaterrx_itemsWithCellIdentifier(_:source:configureCell:cellType:) 绑定的 rx_elements() 无法一起工作。

支持的方法

ObservableArray 实现了以下方法和属性,它们的工作方式与 Array 的等效方法相同。您还可以使用在协议扩展中定义的附加 Array 方法,例如 sortreverseenumerate

init()
init(count:Int, repeatedValue: Element)
init<S : SequenceType where S.Generator.Element == Element>(_ s: S)
init(arrayLiteral elements: Element...)

var startIndex: Int
var endIndex: Int
var capacity: Int

func reserveCapacity(minimumCapacity: Int)
func append(newElement: Element)
func appendContentsOf<S : SequenceType where S.Generator.Element == Element>(newElements: S)
func appendContentsOf<C : CollectionType where C.Generator.Element == Element>(newElements: C)
func removeLast() -> Element
func insert(newElement: Element, atIndex i: Int)
func removeAtIndex(index: Int) -> Element
func removeAll(keepCapacity: Bool = false)
func insertContentsOf(newElements: [Element], atIndex i: Int)
func replaceRange<C : CollectionType where C.Generator.Element == Element>(subRange: Range<Int>, with newCollection: C)
func popLast() -> Element?

var description: String
var debugDescription: String

subscript(index: Int) -> Element
subscript(bounds: Range<Int>) -> ArraySlice<Element>

安装

手动安装

只需将 ObservableArray.swift 复制到您的项目中即可。

许可证

MIT