在iOS中将UICollectionView和UITableView放入UIScrollView是否为最佳实践?
把 TableView/CollectionView/FlatList 放进 ScrollView:到底是不是最佳实践?
嘿,我太懂你这种困惑了!之前搜相关问题的时候,满屏都是“为什么我的列表放进滚动视图后卡成狗”“滑动冲突怎么解决”,很少有人聊这么做到底对不对——今天就来掰扯清楚。
先给结论:99%的场景下,这都不是最佳实践
不管是iOS的UITableView/UICollectionView,还是React Native的FlatList,它们本身就是带滚动能力的高性能组件,核心设计就是用来处理大量列表数据的:
- 它们自带单元格复用机制,不会一次性渲染所有内容,能极大节省内存;
- 内部已经处理了滑动手势、滚动逻辑,甚至像
FlatList还内置了无限滚动、下拉刷新这些常用功能。
而把它们塞进UIScrollView或者RN的ScrollView里,相当于给一个已经会跑的人套了个跑步机:
- 首先会出现滑动手势冲突:两个滚动组件抢着响应滑动操作,一会列表滑不动,一会外层滚动乱跳,就是你说的“奇怪问题”;
- 其次会彻底废掉列表组件的性能优化:外层ScrollView会强制让列表一次性渲染所有内容,数据量大的时候直接卡成PPT;
- 还有无限滚动的逻辑会彻底混乱:列表的滚动位置监听、加载触发条件都会和外层ScrollView的滚动状态打架,你之前遇到的无限滚动问题大概率就是这么来的。
那如果我真的需要“列表+其他固定内容”的布局怎么办?
很多人想这么做,其实是想要一个页面里既有头部固定内容,又有滚动的列表——这时候根本不需要嵌套滚动组件!
针对iOS(UITableView/UICollectionView)
- 用
UITableView的tableHeaderView/tableFooterView来放头部/尾部的固定内容,列表部分就是正常的cell; - 如果是
UICollectionView,可以直接自定义布局,把固定内容作为一个单独的section或者补充视图(supplementary view),和列表内容放在同一个collection view里。
针对React Native(FlatList)
- 用
FlatList的ListHeaderComponent和ListFooterComponent属性,把需要放在列表上方/下方的内容直接传进去; - 如果是更复杂的混合布局,比如中间插固定内容,也可以把固定内容作为一个单独的item混在数据源里,通过
renderItem判断类型来渲染——完全不需要嵌套ScrollView!
聊聊你遇到的FlatList嵌套ScrollView的无限滚动问题
我之前也踩过这个坑!当时为了快速凑页面,把FlatList塞进ScrollView里做无限滚动,结果出现了:
- 明明滚动到底部了,却不触发加载更多;
- 有时候刚进页面就疯狂触发加载;
- 滑动的时候列表突然“跳帧”回到顶部。
后来才明白,这是因为外层ScrollView接管了滚动事件,FlatList根本拿不到准确的滚动位置信息,判断“是否到底部”的逻辑完全失效了。解决的办法就是把所有内容都放进FlatList里:把原来ScrollView里的其他内容作为ListHeaderComponent,然后用FlatList自带的onEndReached来做无限滚动,瞬间所有问题都消失了。
内容的提问来源于stack exchange,提问作者K.Wu
相关产品推荐
相关产品推荐

