您的当前位置:首页正文

“不求甚解”之UIScrollView

来源:华佗小知识

Inheritance: UIView

是所有滑动视图的基类, 如UITableView, UICollectionView, UITextView


理解UIScrollView, 必须理解以下三点:

  1. 对 UIScrollView 的 content 理解:

    • 滚动、缩放都是相对于 ScrollView 中的内容的,相当于 ScrollView 是一个窗口,里面的内容被各种缩放、滚动改变位置,我们看到的窗口所在的位置没有发生改变,改变的只是里面的内容。
    • UIScrollView 中的缩放是缩放 contentSize
    • 设置 UIScrollView 中子 View 的 frame 时,是相对于 UIScrollView 的 frame 的,和 contentSize 无关。
  2. 对delegate生命周期的理解

    (1) tracking = YES
    (2) dragging = YES,scrollViewWillBeginDragging:
    (3) 改变contentOffset,scrollViewDidScroll:
    (4) 手指离开 UIScrollView, tracking = YES,
    scrollViewDidEndDragging:willDecelerate:
    (5) 如果decelerate = YES,发送scrollViewWillBeginDecelerating: 否则直接到第6步
    (6) decelerating = NO,scrollViewDidEndDecelerating:,所有步骤完成!

知道了 delegate 在什么时候发送什么消息,我们就可以根据实际需求在特定的方法里写代码了.


ok. 下面我们就来看看UIScrollView的属性和方法

  • 重要的属性:
属性 说明
@property (nonatomic) CGPoint contentOffset; 内容偏移量,当前显示的内容的顶点相对此控件顶点的x、y距离,默认为CGPointZero (屏幕左上角距离坐标原点的偏移量)
@property (nonatomic) CGSize contentSize; 内容大小. 想要出现滚动效果, UIScrollView 的此属性必须大于其Fame属性
@property (nonatomic, assign) id <UIScrollViewDelegate> delegate; UIScrollView 的代理, 其中定义了视图滚动、缩放、触摸等操作方法
property (nonatomic) UIEdgeInsets contentInset; 控件四周边距,在scroll周围添加了一段额外的滚动范围, 注意边距不作为其内容的一部分,默认为UIEdgeInsetsZero
  • 其他属性
属性 说明
@property (nonatomic) BOLL bounces; 是否启用弹簧效果, 启用弹簧效果后拖动到边缘可以看到内容后面的背景, 默认为YES
@property (nonatomic, getter = isPagingEnabled) BOOL pagingEnabled; 是否分页 (按页翻) , 默认为NO
@property (nonatomic, getter = isScrollEnabled) BOOL scrollEnabled; 是否启用滚动, 默认为YES
@property (nonatomic) UIScrollViewIndicatorStyle indicatorStyle; 设置滚动条样式
@property (nonatomic) BOOL showsHorizontalScrollIndicator; 是否显示横向滚动条, 默认为YES
@property (nonatomic) BOOL showsVerticalScrollIndicator; 是否显示纵向滚动条, 默认为YES
@property (nonatomic) CGFloat minimumZoomScale; 最小缩放倍数,默认为1.0
@property (nonatomic) CGFloat maximumZoomScale; 最大缩放倍数(只有maximumZoomScale大于minimumZoomScale才有可能缩放), 默认为1.0
@property(nonatomic,readonly,getter=isTracking) BOOL tracking; (状态)是否正在被追踪,手指按下去并且还没有拖动时是YES,其他情况均为NO
@property (nonatomic, readonly, getter=isDragging) BOOL dragging; 是否正在被拖拽
@property (nonatomic, readonly, getter=isDecelerating) BOOL decelerating; 是否正在减速
@property (nonatomic, readonly, getter=isZooming) BOOL zooming; 是否正在缩放
@property (nonatomic) BOOL delaysContentTouches; 布尔类型,当值是 YES 的时候,用户触碰开始,scrollView要延迟一会,看看是否用户有意图滚动。假如滚动了,那么捕捉 touch-down 事件,否则就不捕捉。假如值是NO,当用户触碰, scrollView 会立即触发 touchesShouldBegin:withEvent:inContentView:,默认是 YES
@property (nonatomic) BOOL canCancelContentTouches; 当值是 YES 的时候,用户触碰后,在一定时间内没有移动,scrollView 发送 tracking events,然后用户移动手指足够长度触发滚动事件,这个时候,scrollView 发送了 touchesCancelled:withEvent: 到 subview,然后 scroView 开始滚动。假如值是 NO,scrollView 发送 tracking events 后,就算用户移动手指,scrollView 也不会滚动。默认是YES
  • 常用方法
方法 说明
- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated; 将视图中的内容以动画
- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated; 滚动并显示指定区域的内容,第二个参数表示是否启用动画效果
  • 代理方法
滚动代理方法 说明
- (void)scrollViewDidScroll:(UIScrollView *)scrollView; (任何偏移量的改变都会调用此方法), 滚动过程中会一直循环执行
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView; 开始拖拽
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate; 结束拖拽
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView; 开始减速
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView; 减速结束, scroll静止
缩放代理方法 说明
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view; 开始缩放
- (void)scrollViewDidZoom:(UIScrollView *)scrollView; 缩放完成
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView; 返回缩放视图,注意只有实现这个代理方法才能进行缩放,此方法返回需要缩放的视图



UIPageControl 通常配合UIScrollView使用, 注意以下两点:

  • 继承UIControl, 说明他和UIButton一样可以添加事件, 但是, 他得事件触发使用的不是UIControlEventsTouchUpInside而是 UIControlEventsValueChanged
  • 在与UIScrollView配合使用中, 通过偏移量的改变来设置currentPage

还有两个例子没说, 一个是相册, 实现了无限循环(重用), 以及放大缩小等功能, 一个是用UIScrollView实现的简单抽屉效果, 未完待续...

Reference