Swift中BottomSheetUIView分页加载时自动收起问题求助
Swift BottomSheet分页加载自动收起问题修复
问题现象
BottomSheetUIView分页加载新数据时会自动收起,仅在加载成功时触发该问题,加载失败时可正常保持展开状态。
核心原因
scrollViewDidScroll触发逻辑不合理:未判断加载状态,且滚动阈值设置不当,数据更新后contentSize变化会导致该方法重复触发,干扰BottomSheet位置- tableView重载数据时未保留滚动偏移:reloadData后contentOffset会被重置,间接引发BottomSheet位置异常
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
相关产品推荐
相关产品推荐

