如何实现类似设置APP的单元素可滚动视图?
实现无足够内容仍可滚动的UIScrollView(Storyboard版)
没错,系统设置里这类「无足够内容仍可滚动」的视图就是用UIScrollView实现的,你之前没达到效果大概率是配置细节没做对。以下是Storyboard环境下的具体实现步骤:
基础布局搭建
- 在Storyboard中拖入UIScrollView,设置约束让它完全铺满父视图(比如ViewController的view),上下左右边距都设为0。
- 在UIScrollView内部添加一个UIView作为contentView(所有实际内容都放在这个容器里)。
- 给contentView设置约束:上下左右分别和UIScrollView的
contentLayoutGuide对齐,同时添加「contentView宽度等于UIScrollView的frameLayoutGuide宽度」的约束(避免出现横向滚动)。
强制开启滚动的核心配置
默认UIScrollView只有当contentSize大于自身frame时才允许滚动,要实现目标效果,需要通过代码强制让contentSize的高度略大于滚动视图的实际高度:- 保持UIScrollView的
bounces属性为YES(默认就是开启状态,这是弹性滚动的前提)。 - 在ViewController的
viewDidLayoutSubviews方法中添加逻辑:
这样UIScrollView会认为存在可滚动空间,结合- (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; CGFloat scrollViewHeight = self.scrollView.frame.size.height; CGFloat contentHeight = self.contentView.frame.size.height; // 若内容高度小于滚动视图高度,强制让contentSize高度多1pt if (contentHeight < scrollViewHeight) { self.scrollView.contentSize = CGSizeMake(self.scrollView.contentSize.width, scrollViewHeight + 1); } }bounces属性,就能实现和系统设置页面一致的「无内容仍可拖动回弹」效果。
- 保持UIScrollView的
Swift版本对应代码
如果你的项目用Swift,对应的实现代码如下:override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() let scrollViewHeight = scrollView.frame.height let contentHeight = contentView.frame.height if contentHeight < scrollViewHeight { scrollView.contentSize = CGSize(width: scrollView.contentSize.width, height: scrollViewHeight + 1) } }额外注意事项
- 不要给contentView设置固定高度约束,让它的高度由内部内容自动撑开。
- 确保UIScrollView的
isScrollEnabled属性处于开启状态(默认开启)。
内容的提问来源于stack exchange,提问作者Will Conrad
相关产品推荐
相关产品推荐

