UIScrollView是iphone中的一个重要的视图,它提供了一个方法,让你在一个界面中看到所有的内容,从而不必担心因为屏幕的大小有限,必须翻到下一页进行阅览。确实对于用户来说是一个很好的体验。但是又是如何把所有的内容都加入到scrollview,是简单的addsubView。假如是这样,岂不是scrollView界面上要放置很多的图形,图片。移动设备的显示设备肯定不如PC,怎么可能放得下如此多的视图。所以在使用scrollView中一定要考虑这个问题,当某些视图滚动出可见范围的时候,应该怎么处理,是不管它那,还是进行内存回收或者重利用。苹果公司的UITableView就很好的展示了在UIScrollView中如何重用可视的空间,减少内存的开销。

    首先还是看官方API如何解释UIScrollView,一下是翻译官方UIScrollView的帮助文档。

    UIScrollView类支持显示比屏幕更大的应用窗口的内容。它通过挥动手势,能够使用户滚动内容,并且通过捏合手势缩放部分内容。

    UIScrollView是UITableView和UITextView的超类。

    UIScrollView的核心理念是,它是一个可以在内容视图之上,调整自己原点位置的视图。它根据自身框架的大小,剪切视图中的内容,通常框架是和应用程序窗口一样大。一个滚动的视图可以根据手指的移动,调整原点的位置。展示内容的视图,根据滚动视图的原点位置,开始绘制视图的内容,这个原点位置就是滚动视图的偏移量。ScrollView本身不能绘制,除非显示水平和竖直的指示器。滚动视图必须知道内容视图的大小,以便于知道什么时候停止;一般而言,当滚动出内容的边界时,它就返回了。

    某些对象是用来管理内容显示如何绘制的,这些对象应该是管理如何平铺显示内容的子视图,以便于没有子视图可以超过屏幕的尺寸。就是当用户滚动时,这些对象应该恰当的增加或者移除子视图。

    因为滚动视图没有滚动条,它必须知道一个触摸信号是打算滚动还是打算跟踪里面的子视图。为了达到这个目的,它临时中断了一个touch-down的事件,通过建立一个定时器,在定时器开始行动之前,看是否触摸的手指做了任何的移动。假如定时器行动时,没有任何的大的位置改变,滚动视图就发送一个跟踪事件给触摸的子视图。如果在定时器消失前,用户拖动他们的手指足够的远,滚动视图取消子视图的任何跟踪事件,滚动它自己。子类可以重载touchesShouldBegin:withEvent:inContentView:,pagingEnabled,和touchesShouldCancelInContentView:方法,从而影响滚动视图的滚动手势。

    一个滚动视图也可以控制一个视图的缩放和平铺。当用户做捏合手势时,滚动视图调整偏移量和视图的比例。当手势结束的时候,管理视图内容显示的对象,就应该恰当的升级子视图的显示。当手势在处理的过程中,滚动视图不能够给子视图,发送任何跟踪的调用。

    UIScrollView类有一个delegate,需要适配的协议是UIScrollViewDelegate。为了缩放和平铺工作,代理必须实现viewForZoomingInScrollView:和scrollViewDidEndZooming:withView:atScale:方法。另外,最大和最小缩放比例应该是不同的。

    重要的提示:在UIScrollView对象中,你不应该嵌入任何UIWebView和UITableView。假如这样做,会出现一些异常情况,因为2个对象的触摸事件可能被混合,从而错误的处理。

    这些都是官方API的解释,重点是理解UIScrollView怎么来控制手势的。可以由canCancelContentTouches这个方法的运用来解释UIScrollView如何控制手势的。

    假如你设置canCancelContentTouches为YES,那么当你在UIScrollView上面放置任何子视图的时候,当你在子视图上移动手指的时候,UIScrollView会给子视图发送touchCancel的消息。而如果该属性设置为NO,ScrollView本身不处理这个消息,全部交给子视图处理。

    那么这里就有疑问了,既然该属性设置未来NO了,那么岂不是UIScrollView不能处理任何事件了,那么为何在子视图上快速滚动的时候,UIScrollView还能移动那。这个一定要区分前面所说的UIScrollView中断touch-Down事件,开启一个定时器。我们设置的这个cancancelContentTouches属性为NO时,只是让UIScrollView不能发送cancel事件给子视图。而前面所说的时,中断touch-down事件,和取消touch事件是俩码事,所以当快速在子视图上移动的时候,当然可以滚动。但是如果你慢速的移动的话,就可以区分这个属性了,假如设定为YES,在子视图上慢速移动也可以滚动视图,但是如果为NO 。因为UIScrollView,发送了cancel事件给子视图处理了,自己当然滚动不了了。