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
相关产品推荐
相关产品推荐

