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

Swift中BottomSheetUIView分页加载时自动收起问题求助

Swift BottomSheet分页加载自动收起问题修复

问题现象

BottomSheetUIView分页加载新数据时会自动收起,仅在加载成功时触发该问题,加载失败时可正常保持展开状态。

核心原因

  1. scrollViewDidScroll触发逻辑不合理:未判断加载状态,且滚动阈值设置不当,数据更新后contentSize变化会导致该方法重复触发,干扰BottomSheet位置
  2. tableView重载数据时未保留滚动偏移:reloadData后contentOffset会被重置,间接引发BottomSheet位置异常
  3. layoutSubviews强制重置位置逻辑过于激进:每次视图布局都会强制设置BottomSheet的origin.y,导致不必要的位置调整

修复方案

1. 优化滚动加载触发逻辑

修改scrollViewDidScroll方法,增加加载状态判断,调整滚动阈值避免误触发:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    guard !isFetching, !allDataFetched else { return }
    
    let offsetY = scrollView.contentOffset.y
    let contentHeight = scrollView.contentSize.height
    let scrollViewHeight = scrollView.frame.size.height
    // 提前100px触发加载,避免滚动到底部才加载,同时防止重复触发
    let triggerThreshold = contentHeight - scrollViewHeight - 100
    
    if offsetY >= triggerThreshold {
        currentPage += 1
        fetchBarsData(page: currentPage) { [weak self] _ in
            guard let self = self else { return }
            self.setNeedsLayout()
        }
    }
}

2. 重载数据时保留滚动偏移

在fetchBarsData的成功回调中,保存并恢复tableView的contentOffset:

DispatchQueue.main.async {
    UIView.performWithoutAnimation {
        // 保存当前滚动偏移
        let currentOffset = self.tableView.contentOffset
        self.barsData = newBarsData
        self.tableView.reloadData()
        // 恢复滚动偏移
        self.tableView.contentOffset = currentOffset
    }
    self.isFetching = false
}

3. 调整布局重置逻辑

修改layoutSubviews,仅在位置偏差较大时才调整BottomSheet位置:

override func layoutSubviews() {
    super.layoutSubviews()
    if isExpanded {
        let targetY = UIScreen.main.bounds.height - sheetMaxHeight
        // 仅当位置偏差超过1px时才调整,避免频繁修改
        if abs(self.frame.origin.y - targetY) > 1 {
            self.frame.origin.y = targetY
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 04:09:53