美文网首页
UIScrollView的底层实现原理

UIScrollView的底层实现原理

作者: 明若晴空 | 来源:发表于2020-01-13 19:18 被阅读0次

UIScrollView,是我们平时开发UI最常用的控件之一。并且我们常用的UITextView、UITableView、UICollectionView等等这些可滚动的控件,都是继承自UIScrollView来实现的。那么了解UIScrollView的滚动原理就十分必要了。

UIScrollView滚动的原理

frame和bounds

从UIScrollView的官方文档,我们可以知道,UIScrollView本质就是一个contentView的原点(origin)可调节的UIView,它会根据手指的移动,来相应的调节origin的值。
说到这里,我们先了解一些,UIView的frame和bounds属性,及其区别。

  • frame:在父view的坐标系中的位置和尺寸。
  • bounds: 在自己的坐标系中的位置和尺寸。默认bounds的origin为(0,0)。size和frame的size相同。

修改frame和bounds

而当我们更改frame和bounds的origin值时,会发生什么呢?
我们先创建三个view,分别是contentView、subView1、subView2。其中,subView1和subView2是contentView的两个子视图。其原始位置如下图:


原始位置

我们来看一下修改subView1的bounds的origin,和subView2的frame的origin,如下图:

    //更改subView1的bounds的origin
    CGRect bounds = self.subView1.bounds;
    bounds.origin = CGPointMake(20, 50);
    self.subView1.bounds = bounds;
    
    //更改subView2的frame的origin
    CGRect frame = self.subView2.frame;
    frame.origin = CGPointMake(20, 300);
    self.subView2.frame = frame;

修改subView1的bounds的origin,和subView2的frame的origin

从图中,我们可以看到,subView2的frame的origin后,subView2的位置发生了改变,而修改subView1的bounds的origin的值,并不会影响subView1的位置。因为修改bounds的origin的值,改变的是subView1自身的坐标系,应该影响的是位于subView1自身的坐标系上的其子view。
那么,我们再修改contentView的bounds的origin的值,看看是否会影响contentView的子view的位置:

    //更改contentView的bounds的origin
    CGRect boundsContent = self.contentView.bounds;
    boundsContent.origin = CGPointMake(0, -30);
    self.contentView.bounds = boundsContent;
修改contentView的bounds的origin

可以发现,通过contentView的bounds的origin,改变了其上子view的位置,看起来好像是将子view向下滚动了。
由此可以看出,UIScrollView滚动就是通过改变其contentView的bounds的origin的值,使得contentView上的子视图有了滚动的效果。

UIScrollView如何判断是滑动还是子视图的点击的?

在触摸按下时,还会临时启动一个计时器,在计时器触发之前,看看触摸的手指是否有移动过。
如果计时器触发时,没有明显的位置改变,UIScrollView就会将事件传递给被触摸的子view。
如果计时器触发时,用户拖动手指足够远,UIScrollView就会取消给子view传递事件,并开始滚动。

相关文章

网友评论

      本文标题:UIScrollView的底层实现原理

      本文链接:https://www.haomeiwen.com/subject/wjynactx.html