如何在RxSwift中对RxKeyboard实例调用debounce?解决重复回调问题
RxKeyboard visibleHeight 触发两次回调导致视图跳动的问题解决
问题原因
iOS键盘弹出过程中,系统会分两次(甚至多次)发送键盘高度变化通知:第一次是键盘开始弹出时的初始高度(比如你遇到的291),第二次是键盘完全展开后的最终高度(336)。RxKeyboard的visibleHeight序列只是转发了系统的键盘高度变化事件,所以会触发两次回调。
你之前用debounce没生效,是因为drive方法只能接收Driver类型的序列,而debounce返回的是Observable,直接拼接在drive前会因类型不兼容而无法生效,必须先把Observable转成Driver才行。
解决办法
给你几个可行的方案,按需选择:
方案1:正确使用debounce(转成Driver)
补全类型转换步骤,让debounce生效,过滤掉短时间内的重复事件:
RxKeyboard.instance.visibleHeight .debounce(.milliseconds(150), scheduler: MainScheduler.instance) .distinctUntilChanged() .asDriver(onErrorJustReturn: 0) .drive(onNext: { [weak self] value in // 处理键盘高度变化 }) .disposed(by: disposeBag)
方案2:只监听键盘完全显示的事件
如果只需要键盘完全弹出后的最终高度,直接监听didShow事件即可,它只会触发一次:
RxKeyboard.instance.didShow .map { $0.height } .drive(onNext: { [weak self] height in // 处理最终键盘高度 }) .disposed(by: disposeBag)
方案3:过滤小幅度高度变化
通过distinctUntilChanged忽略波动很小的高度值,只处理明显的高度变化:
RxKeyboard.instance.visibleHeight .distinctUntilChanged { previous, current in abs(current - previous) < 10 // 忽略小于10的高度差 } .asDriver(onErrorJustReturn: 0) .drive(onNext: { [weak self] value in // 处理键盘高度 }) .disposed(by: disposeBag)
内容的提问来源于stack exchange,提问作者kunass2
相关产品推荐
相关产品推荐

