【问题标题】:How to throttle observable until a condition becomes true如何限制 observable 直到条件变为真
【发布时间】:2020-02-01 20:10:21
【问题描述】:

我的应用中有一个集合视图,当有新内容或删除时,它会以动画形式刷新。但是,我不希望它在用户滚动时刷新,因为它会导致抽搐。我只想在用户完成滚动/不滚动时刷新集合视图。

所以我有一个数据源驱动程序,我尝试使用filter 让它等到它变成真的但没有运气。

这是我传递给ViewModel的滚动驱动程序

let isScrollViewScrollingDriver = Observable.merge(
            gridCollectionView.rx.willBeginDragging.map { _ in true },
            gridCollectionView.rx.didEndDragging.map { _ in false }
        ).asDriver(onErrorJustReturn: false).startWith(false).distinctUntilChanged()

我在视图控制器中的 ViewModel 初始化

viewModel = ViewModel(
            photoLibraryService: PhotoLibraryService.shared,
            isGridViewScrolling: isScrollViewScrollingDriver,
            disposeBag: disposeBag
        )

我的视图模型

let assetDriver = photoLibraryService.albumDriver.asObservable()
                .withLatestFrom(
                    isGridViewScrolling.asObservable().filter { $0 == false }
                ) { (arg0, arg1) in
                    return arg0
                }.flatMapLatest { libraryAlbum -> Observable<[LibraryAsset]> in
                    return photoLibraryService.convert(album: libraryAlbum)
                }.asDriver(onErrorJustReturn: []).startWith([]).distinctUntilChanged()

然后我将assetDriver 映射到驱动我的集合视图的dataSourceDriver。

我可以对assetDriver 进行哪些更改以使其等待isGridViewScrolling 变为false?谢谢。

【问题讨论】:

  • 试试我几年前在 .NET 中提供的这个答案。没有使用 rx-swift 所以一些运营商可能有不同的名字,但我认为它可以满足你的需要:stackoverflow.com/questions/23431018/…
  • 谢谢!!我会试着把它翻译回 Swift 看看它是否有效!

标签: ios swift system.reactive rx-swift rx-cocoa


【解决方案1】:

听起来你需要我的stallUnless(_:initial:) 运算符。 https://gist.github.com/danielt1263/2b624d7c925d8b7910ef2f1e5afe177b


    /**
     Emits values immediately if the boundary sequence last emitted true, otherwise collects elements from the source sequence until the boundary sequence emits true then emits the collected elements.
     - parameter boundary: Triggering event sequence.
     - parameter initial: The initial value of the boundary
     - returns: An Observable sequence.
     */
    func stallUnless<O>(_ boundary: O, initial: Bool) -> Observable<Element> where O: ObservableType, O.Element == Bool {
        return Observable.merge(self.map(Action.value), boundary.startWith(initial).distinctUntilChanged().materialize().map(Action.trigger).takeUntil(self.takeLast(1)))
            .scan((buffer: [Element](), trigger: initial, out: [Element]()), accumulator: { current, new in
                switch new {
                case .value(let value):
                    return current.trigger ? (buffer: [], trigger: current.trigger, out: [value]) : (buffer: current.buffer + [value], trigger: current.trigger, out: [])
                case .trigger(.next(let trigger)):
                    return trigger ? (buffer: [], trigger: trigger, out: current.buffer) : (buffer: current.buffer, trigger: trigger, out: [])
                case .trigger(.completed):
                    return (buffer: [], trigger: true, out: current.buffer)
                case .trigger(.error(let error)):
                    throw error
                }
            })
            .flatMap { $0.out.isEmpty ? Observable.empty() : Observable.from($0.out) }
    }
}

【讨论】:

    【解决方案2】:

    你可以使用 combineLatest:

        let assetDriver = Driver
            .combineLatest(
                photoLibraryService.albumDriver,
                isGridViewScrolling
            )
            .filter { !$1 }
            .map { $0.0 }
            .flatMapLatest { libraryAlbum -> Driver<[LibraryAsset]> in
                photoLibraryService.convert(album: libraryAlbum)
                    .asDriver(onErrorJustReturn: [])
            }
            .startWith([])
            .distinctUntilChanged()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-09
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 2021-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多