今天面试被鄙视了不过确实平时没观察到!知其然知其所以然
UIScrollView是用来在屏幕上显示那些在有限区域内放不下的内容。例如,在手机屏幕上显示内容丰富的网页或者很大的图片。在这种情况下,需要用户对屏幕内容进行拖动或缩放来查看屏幕或窗口区域外的内容。
所以,ScrollView应该首先有一个窗口,用来显示内容,其次,还要有内容本身。这里的这个显示窗口就是UIScrollView,这个窗口可以是整个手机屏幕,也可以只是手机屏幕的一部分区域(屏幕其他部分可以显示些别的东西)。内容则是你需要查看的图片或者网页等信息视图。通常,其大小会超过这个屏幕,正因为如此,我们才要使用UIScrollView来查看。
使用方法
建立scrollView
先来看如何使用UIScrollView
在小窗口中显示一副大图。
假定ViewConroller已经设置了属性@property UIScrollView * scrollView;
- (void)viewDidLoad{
[super viewDidLoad];
//1. 建立UIScrollView窗口,我们只打算用手机的上半屏显示图像,(这一步也可以在storyboard里完成)
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320 , 300)];
//2.建立内容视图
UIImageView * view = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"tesla.jpg"]];
//3.将内容视图作为scrollView的子视图
[self.scrollView addSubview: view];
//4.当然了,还得把scrollView添加到视图结构中
[self.view addSubview: self.scrollView];
}
运行一下看看,发现窗口正常显示了图片的左上角。但是根本拖不动,看不了图片的其他部分。这是怎么回事呢?因为我们没有为scrollView设置要显示的内容大小。而scrollView的contenSize大小默认是0。
内容展示:contentSize
contentOffset
contentInset
contentSize
描述了有多大范围的内容需要使用scrollView的窗口来显示,其默认值为CGSizeZero,也就是一个宽和高都是0的范围。
当contentSize小于当前scrollView的大小时,意味着用户要显示的内容在窗口范围内是可以全部显示的,这个时候,通常
内容视图是拖不动的(有内容没有显示出来才要拖嘛,都显示得出来)。之所以说是“通常”,是因为通过某些设置,还是可以拖得动的,后边回弹机制里会解释。所以要让视图可以拖动,我们得设置一个contentSize。在前面这个简单的这个例子里,我们当然就设置成imageView的大小就好了啊。所以在第2步之后添加一句:
self.scrollView.contentSize = view.bounds.size;
这样,就可以显示图片的全部内容。
但是如果你只想在窗口显示图片的的一部分,也是可以的,就把contentSize设置得小一点就好了。除了contentSize,还有contentOffset,contentInset也可以结合起来使用。需要注意的是,contentSize的范围是以scrollView的位置为基准的。所以,如果内容视图的frame.origin不是(0,0),则需要仔细计算内容视图能被显示的范围。
contentOffset: 描述了内容视图相对于scrollView窗口的位置(当然是向上向左的偏移量咯)。默认值是CGPointZero,也就是(0,0)。当视图被拖动时,系统会不断修改该值。也可以通过setContentOffset:animated:方法让图片到达某个指定的位置。
scrollRectToVisible:animated:与setContentOffset:animated:类似,只不过是将scrollView坐标系内的一块指定区域移到scrollView的窗口中,如果这部分已经存在于窗口中,则什么也不做。
contentInset: 表示scrollView的内边距,也就是内容视图边缘和scrollView的边缘的留空距离,默认值是UIEdgeInsetsZero,也就是没间距。这个属性用的不多,通常在需要刷新内容时才用得到。
好了,图片现在可以拖动了。为了更清楚的进行描述,我们换一张图片。大小为550*350的网格。
我们发现,当将图片拖到边缘的时候,图片还是可以继续被拖动的,会显示contenSize之外的内容。
如果contentSize设置为图片的大小,拖动到边缘后仍然可以继续拖动,视图显示出一定的弹性,显示出空白,一旦松手,内容视图会回弹,空白不会显示在scrollView窗口中。
如果contentSize设置得比图片的大小还小,拖动到contentSize指定的大小后仍然可以继续拖动,显示内容视图的更多部分,但一旦松手,内容视图也会回弹,超过contentSize的那部分不会显示在scrollView窗口中。
如果contentSize设置得比图片的大小更大,拖动到图片的边缘后仍然可以继续拖动,显示空白,直到超过contentSize的范围,才会产生弹性,松手后,视图回弹,静止状态下我们可以看到scrollView可以显示出contentSize范围内图片范围外的空白。
也就是说scrollView窗口在手指释放的时候后的静止状态下,只会显示contentSize范围内的内容。
scrollView的这种回弹机制,是可以设置的,相关的属性为:bounces,alwaysBounceHorizontal,alwaysBounceVertical,decelerationRate。
在拖动的过程中,我们还发现水平方向和垂直方向还显示出状态条,状态条的显示也是可以设置的。相关属性为:indicatorStyleshowsHorizontalScrollIndicator showsVerticalScrollIndicatorscrollIndicatorInsets flashScrollIndicators
回弹机制:bounces
alwaysBounceHorizontal
alwaysBounceVertical
bounces
:描述的当scrollview的显示超过内容区域的边缘以及返回时,是否有弹性,默认值为YES。值为YES的时候,意味着到达contentSize所描绘的的边界的时候,拖动会产生弹性。值为No的时候,拖动到达边界时,会立即停止。所以,如果在上面的例子当中,将bounces设置为NO时,窗口中是不会显示contentSize范围外的内容的。
alwaysBounceHorizontal
:默认值为NO,如果该值设为YES,并且bounces也设置为YES,那么,即使设置的contentSize比scrollView的size小,那么也是可以拖动的。
alwaysBounceVertical
:默认值为NO,如果该值设为YES,并且bounces也设置为YES,那么,即使设置的contentSize比scrollView的size小,那么也是可以拖动的。
状态条显示indicatorStyle
showsHorizontalScrollIndicator
showsVerticalScrollIndicator
scrollIndicatorInsets
flashScrollIndicators
根据我们的实际需要,我们可以对状态条进行各种设置。
indicatorStyle
: 状态条的风格,默认值为UIScrollViewIndicatorStyleDefault。除此之外,还有UIScrollViewIndicatorStyleBlack, UIScrollViewIndicatorStyleWhite两种其他风格。可以用来和环境配色。
showsHorizontalScrollIndicator
: 当处于跟踪状态(tracking)时是否显示水平状态条,默认值为YES。下一节说明什么是跟踪状态。
showsVerticalScrollIndicator
: 当处于跟踪状态(tracking)时是否显示垂直状态条,默认值为YES。
scrollIndicatorInsets
: 状态条和scrollView边距的距离(暂时还没想明白为什么要有这个)。
flashScrollIndicators
: 短暂的显示一下状态条,当你将scrollView调整到最上面时,需要调用一下该方法。
状态跟踪
之前提到过跟踪状态(tracking)。相关的属性有三个:tracking
dragging
decelerate
,这三个属性表明了当前视图的滚动状态。
tracking
: 只读,一旦用户开始触摸视图(也许还没有开始拖动),该属性值为YES
dragging
: 只读,当用户开始拖动(手指已经在屏幕上滑动一段距离了),该属性值为YES
decelerate
: 只读,当用户松开手指,但视图仍在滚动时,该值返回YES
zooming
: 只读,用户是否正在进行缩放手势。
zoomBouncing
:只读,当缩放超过最大或者最小范围的时候,回弹到最大最小范围的过程中,该值返回YES。
缩放
上一节我们看到了zooming属性,scrollView除了支持拖动之外,还支持缩放。
maximumZoomScale
: 最大放大比例,默认值为1,不得小于minimumZoomScale
minimumZoomScale
: 最小放大比例,默认值为1,不得大于maxmumZoomScale
bouncesZoom
: 描述在缩放超过缩放比例时,是否bounce,默认值为YES。如果值为NO,则达到最大或最小缩放比例时会立即停止缩放。否则,产生弹簧效果。
zoomScale
: 当前的缩放比例。系统会根据缩放过程调整此值。
setZoomScale:animated:
: 程序设置缩放大小。
zoomToRect:animated:
将内容视图缩放到指定的Rect中。
panGestureRecognizer
pinchGestureRecognizer
其他设置
delegate
: scrollView的委托对象,该委托对象必须实现UIScrollViewDelegate协议,这些方法会在合适的时候被调用。
scrollEnabled
:视图是否可被拖动,默认值为YES。一旦该值设置为NO,则scrollView不再接受触屏事件,会直接传递响应链。
scrollToTop
:是否启动“滚动至顶端”手势,默认值为YES。当用户使用了“滚动至顶端”手势(轻击状态栏)时,系统会要求离状态栏最近的scrollView滚动到顶端,如果scrollToTop设置为NO,则该scrollView的delegate的scrollViewShouldScrollToTop:
方法会返回NO,不会滚动到顶端。否则,则会滚动到顶端。滚动到顶端之后,会给delegate发送scrollViewDidScrollToTop:消息。需要注意的是,在iphone上,如果有多个scrollview的scrollToTop参数设置为YES的时候,“滚动至顶端”手势会失效。
delaysContentTouches
:是否推迟触屏手势处理,默认值为YES。设置为YES的时候,系统在确定是否发生scroll事件之后,才会处理触屏手势,否则,则会立即调用touchesShouldBegin:withEvent:inContentView:
方法。
directionalLockEnabled
:是否锁定某个特定方向的滚动,默认值为NO。设置为YES时,一旦用户向水平或竖直方向拽动时,另一个方向的滚动则被锁定了。但是如果首次拽动是斜着的,那么则不会锁定方向。
keyboardDismissMode
: 当拖动发生时,键盘的消失模式,默认值是不消失。
pagingEnabled
:是否使用分页机制,默认值为NO。当设置为YES时,会按照scrollView的宽度对内容视图进行分页。
decelerationRate
: 手指滑动后抬起,页面的减速速率。可以使用UIScrollViewDecelerationRateNormal
和UIScrollViewDecelerationRateFast
常量值来设置合理的减速速率。