You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 04:30:01