iOS开发UIScrollView内UIImageView动态高度异常、页面非预期滚动问题
问题说明
实现UIImageView动态高度效果时未达到预期,当前页面视图层级如下:
[UIView] [UIScrollView] [UIImageView] [UILabel] [UILabel] [UITextField] [UIButton] [UIButton]
预期布局要求
- 除UIImageView外的所有控件都是固定高度,始终从屏幕底部开始固定排布
- UIImageView自动占满屏幕剩余空间,高度适配屏幕顶部到“Enter your mobile number”标签之间的区域
- 页面默认状态不可滚动,添加UIScrollView的唯一作用是键盘弹出时,用户能滚动看到输入框内容
现存异常
- UIImageView高度被设置得异常偏大
- 页面默认状态下就出现非预期滚动

修复方案
问题本质是UIScrollView的布局约束逻辑写错,把本来应该固定在可视区域的控件算进了滚动内容范围,直接按下面的约束规则改就行:
- 先搭UIScrollView自身的约束:上下左右四边完全贴合根UIView的安全区域,不要给ScrollView设置固定高度。
- 区分ScrollView的
frameLayoutGuide(可视区域布局参照)和contentLayoutGuide(滚动内容布局参照),两类控件分别绑定对应约束:- 底部固定的那组控件(两个UILabel、输入框、两个按钮):所有垂直方向约束全部挂到
frameLayoutGuide上——最底部的按钮底部对齐frameLayoutGuide底部,往上依次按设计间距设置相邻控件的垂直约束,每个控件固定高度;水平方向左右对齐frameLayoutGuide,宽度和ScrollView可视宽度一致,保证这部分控件永远固定在屏幕底部,不会跟着滚动。 - UIImageView:顶部对齐
frameLayoutGuide顶部,左右对齐frameLayoutGuide,底部对齐“Enter your mobile number”标签的顶部,间距设为0,图片显示模式设为scaleAspectFit避免变形,这样它的高度会自动被限制在顶部和第一个标签之间,不会出现异常偏大的问题。
- 底部固定的那组控件(两个UILabel、输入框、两个按钮):所有垂直方向约束全部挂到
- ScrollView基础属性配置:把
alwaysBounceVertical设为false,默认状态下滚动内容高度和可视区域高度完全一致,就不会出现无意义的可滚动状态。 - 键盘适配单独处理:监听键盘弹出/收起的系统通知,键盘弹出时把ScrollView的
contentInset.bottom设为键盘高度,键盘收起时重置为0,就能满足键盘弹出时可滚动查看输入内容的需求。
踩坑提醒:要是把底部固定控件的垂直约束挂到
contentLayoutGuide上,AutoLayout会自动把这些控件的高度算进ScrollView的滚动内容总高度,直接把UIImageView的高度撑爆,这就是你现在遇到的两个异常的核心原因。
内容的提问来源于stack exchange,提问作者Hyder
相关产品推荐
相关产品推荐

