使用contentInset实现文本垂直居中仅负偏移生效问题咨询
问题原因及修复方案
你遇到的正值contentInset不生效、负值反而生效的问题,主要由以下几个原因导致:
- 仅设置top方向内边距,未同步设置bottom方向
UIScrollView(含UITextView等子类)默认在contentSize高度小于自身bounds高度时,会将内容贴靠顶部显示。你仅给top设置正内边距、bottom保持为0时,系统会忽略你设置的topInset,维持内容顶部分布的逻辑。负值的topInset会主动修改内容的可视区域偏移,打破默认分布逻辑,所以反而能看到效果。
正确的写法是同时给top和bottom设置相等的内边距,修改后代码如下:
override func alignCenterVertical() { let fittingSize = CGSize(width: bounds.width, height: CGFloat.greatestFiniteMagnitude) let size = sizeThatFits(fittingSize) let verticalOffset = max(0, (bounds.size.height - size.height * zoomScale) / 2) contentInset = UIEdgeInsets(top: verticalOffset, left: 0, bottom: verticalOffset, right: 0) }
- 方法调用时机错误
如果在视图未完成布局的阶段(如viewDidLoad、视图初始化方法)调用该方法,此时拿到的bounds是未完成最终计算的错误值,导致偏移计算不符合预期,看起来像正偏移未生效。你需要在布局完成的回调中调用该方法,比如UIViewController的viewDidLayoutSubviews方法,或者UIView的layoutSubviews方法。 - 系统自动调整内边距的干扰
如果滚动视图添加在UIViewController内,系统默认会根据导航栏、状态栏、标签栏的高度自动修改contentInset,覆盖你手动设置的值。可以通过关闭自动调整逻辑解决:
// iOS 11 及以上版本 scrollView.contentInsetAdjustmentBehavior = .never // iOS 11 以下版本 viewController.automaticallyAdjustsScrollViewInsets = false
- 阈值设置逻辑问题
你当前代码用max(1, topOffset)强制将偏移最小设为1,如果实际需要的偏移小于1,该逻辑会导致计算结果不符合需求,可将阈值改为0即可。
内容的提问来源于stack exchange,提问作者Juliette Destang
相关产品推荐
相关产品推荐

