UIScrollView
UIScrollView继承自UIView,它的作用是通过滑动来扩展边界。
分析
我们知道UIView的bounds属性的作用是以自身为参考坐标系,来描述自己的大小和位置。如下如所示:

通过上图可知,修改控件自身bounds属性的origin值,内部的子控件的位置就会发生相应的变化。
因为UIScrollView继承自UIView,所以它是利用了bounds属性的特点,来实现滑动的特性的。
实现原理
通过模拟系统UIScrollView,实现自定义的CustomScrollView控件,来了解UIScrollView的底层实现原理。
1 | @interface CustomScrollView : UIView |
根据以上代码可得出控件滚动是因为bounds.origin值的不断修改。
滑动原理:UIScrollView通过自身的Pan拖拽手势,可以获取手指移动的方向和距离,然后根据移动的方向和距离再去修改自身的bounds.origin值。
contentInset
contentInset的作用是扩展内容区域。
1 | scrollView.contentInset = UIEdgeInsetsMake(88.f, 0.f, 0.f, 0.f); |
打印的信息:scrollView bounds {{0, -88}, {375, 667}}
根据打印的信息可知contentInset的实现原理是修改bounds.origin值。
从iOS11开始废弃了控制器的 automaticallyAdjustsScrollViewInsets属性。使用 UIScrollView的contentInsetAdjustmentBehavior属性替代。
当
automaticallyAdjustsScrollViewInsets = YES的时候,内容区域向下偏移 导航栏高度 + 状态栏高度 的距离。此时scrollView.contentInset = {64, 0, 0, 0},scrollView.contentOffset = {0, -64}。当
contentInsetAdjustmentBehavior = Automatic/Always的时候,内容区域向下偏移 导航栏高度 + 状态栏高度 的距离。此时 非刘海屏scrollView.contentInset = {0, 0, 0, 0},scrollView.contentOffset = {0, -64},scrollView.adjustedContentInset = {64, 0, 0, 0}, 刘海屏scrollView.contentInset = {0, 0, 0, 0},scrollView.contentOffset = {0, -88},scrollView.adjustedContentInset = {88, 0, 34, 0}。
UITableView
UITableView继承自UIScrollView,它通过列表来展示信息。