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

iOS15更新后UITableView中UIView.animateKeyframes动画异常与按钮点击失效问题

iOS15下UITableView频繁更新时动画异常、按钮点击失效问题

有一个通过WebSocket和RxSwift实现数据快速更新的UITableView,每次数据更新都会播放闪烁动画效果。该功能在iOS11~iOS14系统上运行完全正常,但升级到iOS15后动画出现异常:大部分动画更新被跳过,有时还会出现所有行同时播放动画的情况。

补充说明

  • 点击单元格内的按钮时无法触发对应事件,往往需要多次点击才能响应,看起来更新过程中按钮无法接收点击事件
  • 存在点击错位问题:点击单元格1的按钮,却触发了单元格2的对应事件

(出于保密需求,单元格相关信息已隐藏)

效果演示动图
从动图可以看到,左侧运行在iOS11~iOS14的设备动画播放流畅,右侧iOS15设备的动画被跳过。

原有实现代码

闪烁动画实现

func flash()->Observable<Void>{
    return Observable.create { (observer) -> Disposable in
        UIView.animateKeyframes(withDuration: 0.5, delay: 0, options: []){
            UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.5) {
                self.background.alpha = 0
            }
            UIView.addKeyframe(withRelativeStartTime: 0.25, relativeDuration: 0.5) {
                self.background.alpha = 0.2
            }
            UIView.addKeyframe(withRelativeStartTime: 1, relativeDuration: 0.5) {
                self.background.alpha = 0
            }
        }
        return Disposables.create()
    }
}

动画调用逻辑

someBehaviorRelay.subscribe { [unowned self] value in
    flash().subscribe().disposed(by: disposeBag)
}

注:没有主动dispose someBehaviorRelay因为会中断动画

单元格复用处理

override func prepareForReuse() {
    disposeBag = DisposeBag()
}
解决方案

iOS15及以上系统更新UITableView时,使用reconfigureRows(at:)代替reloadData()即可:

// if iOS15
let indexPaths = tableView.indexPathsForVisibleRows!
if !indexPaths.isEmpty {
    tableView.reconfigureRows(at: indexPaths)
} else {
    tableView.reloadData()
}

内容的提问来源于stack exchange,提问作者vyppN

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 13:24:06