带有导航栏大标题的 UITableView 奇怪的滚动行为,顶部的弹跳效果在滚动到顶部时自动切断/生涩

Posted

技术标签:

【中文标题】带有导航栏大标题的 UITableView 奇怪的滚动行为,顶部的弹跳效果在滚动到顶部时自动切断/生涩【英文标题】:UITableView weird scroll behaviour with navigation bar large title, bounce effect at the top auto cut off / jerky when scroll to top 【发布时间】:2019-04-01 02:11:18 【问题描述】:

我有一个UITableView,其中包含多个带有标题的部分,可折叠/可展开。还有一个带有自定义UIView的tableHeaderView。

使用自定义部分标题UIView 和自定义UITableViewCell

当所有部分和行完全展开时,会出现这种奇怪的滚动行为,当我滚动到顶部(向下滚动)时,当我到达最顶部时,大导航栏标题应该跟随我的向下滚动手势并沿其方向设置动画(反弹效果)。但是,在这种情况下,弹跳效果并没有发生,当我滚动到顶部并尝试滚动更多的弹跳效果时,滚动自动被切断,导航栏自动变成一个小标题。

令人惊讶的是,当我折叠第一部分的所有行时,滚动行为恢复正常。

这是一个显示我的屏幕录制的 gif。

https://i.imgur.com/WwXmpmZ.gifv

我已将以下内容设置为我的UITableView

self.tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 15, right: 0)
self.tableView.estimatedRowHeight = 0 
self.tableView.estimatedSectionHeaderHeight = 0
self.tableView.estimatedSectionFooterHeight = 0

我也试过了:

self.tableView.contentInsetAdjustmentBehavior = .never

这确实解决了奇怪的滚动行为,但是它导致我的部分标题和行与我的 tableHeaderView 重叠。

我处理折叠/展开的方式。如果对象属性isCollapsed 为真,我只需为该部分返回 0 行:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

    if section == self.scheduleCount 
        //Last section
        return self.dataSource.count
    

    guard let schedule = self.itineraryDataSource?.schedule[section] else  return 0 

    if schedule.isCollapsed 
        return 0
     else 
        return schedule.items.count
    

这些都是高度代表,最后一部分有不同的UITableViewCell,因此高度不同。

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat 

    if section == self.scheduleCount 
        //Last section
        return 40
    

    return 64


func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
    if indexPath.section == self.scheduleCount 
        //Last section
        return 112
     else 
        return 76
    

【问题讨论】:

如何插入新的表格视图行?上传相同的代码。 @SachinVas 我已经编辑了我的帖子,以包含更多关于我如何管理折叠/展开以及高度代表的代码。每当点击部分标题以折叠/展开时,我都会执行这些操作:self.tableView.reloadSections([section], with: .fade) 【参考方案1】:

设法解决了这个问题。

原来我为我的viewForHeaderInSection 返回UIView 而我没有使用tableView.dequeueReusableHeaderFooterView。每次滚动 tableView 时,我都会初始化一个新的 xib UIView,这会导致它自动调整内容插入,因此会导致滚动不顺畅。

因此,我为我的部分标题视图创建了新的自定义 xib,类型为 UITableViewHeaderFooterView,并简单地将其返回到 viewForHeaderInSection

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? 
    let dayHeaderView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "ItineraryDayHeaderView") as? ItineraryDayHeaderView

    // Configure View...

    return dayHeaderView

【讨论】:

以上是关于带有导航栏大标题的 UITableView 奇怪的滚动行为,顶部的弹跳效果在滚动到顶部时自动切断/生涩的主要内容,如果未能解决你的问题,请参考以下文章

如何将导航栏大标题转换为多行,居中对齐

带有 UITableView 的 UIPageViewController 有奇怪的大小

带有 iAd 横幅的 UITableView 上的奇怪溢出

粘性导航栏可变大小更改滚动位置

带有大标题导航的 UITableView UIRefreshControl 不会停留在顶部 - 它会移动

带有 UISearchController 的 UITableView 在进入结果视图并返回时进入导航栏