pujiaxin33 / JXSegmentedView

A powerful and easy to use segmented view (segmentedcontrol, pagingview, pagerview, pagecontrol, categoryview) (腾讯新闻、今日头条、QQ音乐、网易云音乐、京东、爱奇艺、腾讯视频、淘宝、天猫、简书、微博等所有主流APP分类切换滚动视图)
MIT License
2.69k stars 370 forks source link

页面生命周期未调用 #127

Open LinBowen9656 opened 3 years ago

LinBowen9656 commented 3 years ago

当滑动listContainer时,滑动后不立刻松手,并停在scrollview paging的临界点后松手,最后显示界面的viewDidAppear等生命周期方法未被调用,或者当页面较多时非常快速滑动多页后停下来也可以触发此BUG

rainedAllNight commented 1 year ago

遇到同样的问题,在快速滑动或者paging临界值快速松手会出现生命周期未按预期调用的问题,如tab 页面从左到右顺序为 A 、B,当滑动到B后,尝试向左滑到A,滑动一点距离后快速松手,由于paging的作用会回到B,这时候预期的生命周期应该是 A:WillAppear -> B: WillDisAppear, A: WillDisAppear, B:WillAppear ; 实际上会有很大概率的变成 A:WillAppear -> B: WillDisAppear, 缺少后续的生命周期调用,项目里多处使用JXSegmentedView的地方都能复现,麻烦帮忙确认下

rainedAllNight commented 1 year ago

大概查到了原因,JXSegmentedListContainerView中有针对滑动取消的兼容逻辑,但是只处理了取消时手放开走减速的情况,当最后取消时,通过手指拉动回来让滑动停止时,scrollViewDidEndDecelerating不会调用,因为这个时候是通过Dragging让其停止的。

public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { //滑动到一半又取消滑动处理 if willAppearIndex != -1 || willDisappearIndex != -1 { listWillDisappear(at: willAppearIndex) listWillAppear(at: willDisappearIndex) listDidDisappear(at: willAppearIndex) listDidAppear(at: willDisappearIndex) willDisappearIndex = -1 willAppearIndex = -1 } }

修复建议:DidEndDragging方法也添加兼容处理,但是需要评估是否会影响其他正常的滑动逻辑 public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { if decelerate { return } if willAppearIndex != -1 || willDisappearIndex != -1 { listWillDisappear(at: willAppearIndex) listWillAppear(at: willDisappearIndex) listDidDisappear(at: willAppearIndex) listDidAppear(at: willDisappearIndex) willDisappearIndex = -1 willAppearIndex = -1 } }

rainedAllNight commented 1 year ago

这个只能处理临界点后松手的场景,快速滑动仍然有问题,初步判断原因是在快速滑动时,index会计算错误,导致scrollViewDidEndDecelerating里执行取消逻辑时执行的是错误的index