zoukankan      html  css  js  c++  java
  • UIScrollView详解

    UIScrollView继承自:UIView: UIResponder: NSObject

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

    官方API文档对UIScrollView的描述

    1、概述:

         The UIScrollView class provides support for displaying content that is larger than the size of the application’s window. It enables users to scroll within that content by making swiping gestures, and to zoom in and back from portions of the content by making pinching gestures.

          UIScrollView类是滚动条视图,它提供了支持显示比应用程序窗口大得多的内容。它通过轻扫手势使用户滑动内容,并且通过捏合手势来缩放部分内容。

       UIScrollView is the superclass of several UIKit classes including UITableView and UITextView.

         UIScrollView类是包括UITableViewUITextView在内的一些UIKit类的父类

          The central notion of a UIScrollView object (or, simply, a scroll view) is that it is a view whose origin is adjustable over the content view. It clips the content to its frame, which generally (but not necessarily) coincides with that of the application’s main window. A scroll view tracks the movements of fingers and adjusts the origin accordingly. The view that is showing its content “through” the scroll view draws that portion of itself based on the new origin, which is pinned to an offset in the content view. The scroll view itself does no drawing except for displaying vertical and horizontal scroll indicators. The scroll view must know the size of the content view so it knows when to stop scrolling; by default, it “bounces” back when scrolling exceeds the bounds of the content.

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

         The object that manages the drawing of content displayed in a scroll view should tile the content’s subviews so that no view exceeds the size of the screen. As users scroll in the scroll view, this object should add and remove subviews as necessary.

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

         Because a scroll view has no scroll bars, it must know whether a touch signals an intent to scroll versus an intent to track a subview in the content. To make this determination, it temporarily intercepts a touch-down event by starting a timer and, before the timer fires, seeing if the touching finger makes any movement. If the timer fires without a significant change in position, the scroll view sends tracking events to the touched subview of the content view. If the user then drags their finger far enough before the timer elapses, the scroll view cancels any tracking in the subview and performs the scrolling itself. Subclasses can override the touchesShouldBegin:withEvent:inContentView:, pagingEnabled, and touchesShouldCancelInContentView: methods (which are called by the scroll view) to affect how the scroll view handles scrolling gestures.

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

         A scroll view also handles zooming and panning of content. As the user makes a pinch-in or pinch-out gesture, the scroll view adjusts the offset and the scale of the content. When the gesture ends, the object managing the content view should should update subviews of the content as necessary. (Note that the gesture can end and a finger could still be down.) While the gesture is in progress, the scroll view does not send any tracking calls to the subview.

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

        The UIScrollView class can have a delegate that must adopt the UIScrollViewDelegate protocol. For zooming and panning to work, the delegate must implement both viewForZoomingInScrollView: and scrollViewDidEndZooming:withView:atScale:; in addition, the maximum (maximumZoomScale) and minimum ( minimumZoomScale) zoom scale must be different.

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

    2、UIScrollView的属性和方法

         /*  Managing the Display of Content */

        // contentSizeUIScrollView可以滚动的区域,这个和它的Frame是不一样的,只有contentSize的大小大于Frame这样才可以支持滚动。

              例:若 frame = (0, 0, 320, 480) contentSize = (320, 960),代表本UIScrollView可以上下滚动,滚动区域为frame大小的两倍。

        scroll.contentSize = CGSizeMake(XXX, XXX);

        图片解释如下:

        

                 //contentOffsetUIScrollViewframe中显示内容视图的原点相对于frame原点的偏移量

          例如上面的例子如果拉到最下面,则contentOffset就是(0, 480),也就是y偏移了480.

        scroll.contentOffset = CGPointMake(0, 0);// 设置、获取内容视图距离原点的偏移量    

             图片解释如下:

        

        //contentInsetAPI文档的解释是"内容视图嵌入到封闭的滚动视图的距离"。可以理解为内容视图的上下左右四个边扩展出去的大小。

                  contentInset的单位是UIEdgeInsets,默认值为UIEdgeInsetsZero,也就是没有扩展的边

        scroll.contentInset = UIEdgeInsetsMake(0, 10, 0, 10);// 默认是UIEdgeInsetsZero

        图片解释如下:

        

        /*  Managing Scrolling  */

        @property(nonatomic) BOOL bounces;                //当滚动到内容边缘是否发生反弹,default is YES.

        @property(nonatomic) BOOL alwaysBounceHorizontal; //是否只在水平发生反弹,当内容到达边缘。

                                                                                                                                           default is NO,如果要只在水平反弹那么  bounces必须为YES.

        @property(nonatomic) BOOL alwaysBounceVertical;   //当滚动到达边缘时,是否只有垂直边缘才发生反弹。default is no.

        @property(nonatomic) BOOL bouncesZoom; //当在缩放时,到达图片最大缩放倍数(maximumZoomScale)或者是最小缩放倍数( minimumZoomScale)时,为了告诉用户缩放倍数已达极限,是否发生动态反弹的效果来告诉用户。defaults is YES.

        @property(nonatomic) BOOL canCancelContentTouches; //当手指触摸屏幕后,并没有开始拖动,而隔一段时间后再开始拖动,这个属性决定是否scorllView里的图片是否会再继续随着手指的滑动,而图片跟着滑动。defualt is NO,图片会跟着手指滑动而滑动。

        scroll.scrollEnabled = YES;//设置是否能滑动  如果NO 则scrollView将不会接受任何触摸事件

        scroll.directionalLockEnabled = NO;// 设置方向锁 yes是指只能左右、上下滑动 no是指任何方向都能滑动  默认是no

        scroll.scrollsToTop = YES;

        scroll.canCancelContentTouches = YES;

        scroll.pagingEnabled = YES;//是否在拖动图片后,图片翻到scrollView的下一个子视图开始边界. default is NO

            @property(nonatomic) UIScrollViewIndicatorStyle indicatorStyle; //拖动图片时,下面或者右侧的那个滚动进度条显示的风格

                                           

        scroll.showsHorizontalScrollIndicator = NO;//是否显示水平滚动条默认 yes

        scroll.showsVerticalScrollIndicator = NO; // 是否显示竖直滚动条默认 yes

        @property(nonatomic) float maximumZoomScale; //最大缩放倍数

        @property(nonatomic) float minimumZoomScale; //最大缩小倍数

        //通常情况下,最小倍数比scrollViewframe要小,而最大缩放倍数可能与contentSize有关,需要自己算出

        //最大缩放倍数,如:如果想最大缩放倍数为5倍,那么contentSize也应该设置为5scrollViewframe大小。

        //假如想要双击scrollView里的图片放大,或者支持两只手指在屏幕捏放实现图片缩放,必须重写覆盖继承自

        //UIResponder的几个交互方法:

             ﹣(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

             ﹣(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

             ﹣(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;

        

        

        /*Managing the Delegate*/

         // UIScrollView支持处理缩放、滑动的动作 但是必须引用委托<UIScrollViewDelegate>

         @property(nonatomic, assign) id<UIScrollViewDelegate> delegate;  

        

           缩放实现三个代理方法(最后一个方法可实现、可不实现:

           //UIScrollView尝试进行缩放的时候就会调用    这个方法返回的控件就能进行捏合手势缩放操作 

           1- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView; 

           //当正在缩放的时候调用    反复持续调用

           2- (void)scrollViewDidZoom:(UIScrollView *)scrollView{

           //当缩放完毕的时候调用

           3- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale;       

          

           添加属性:(值要不一样)

                     maximumZoomScale

                     minimumZoomScale

                     

           其他常用来缩放方法:

                     - (void)zoomToRect:(CGRect)rect animated:(BOOL)animated  //把从scrollView里截取的矩形区域缩放到整个scrollView当前可视的frame里面。

                     所以     如果截取的区域大于scrollViewframe时,图片缩小,如果截取区域小于frame,会看到图片放大。一般情况下rect需要自己计算出来。

                     比如,要把scrollView原来坐标点为(40,40)的内容周围内容在scrollView里放大一倍,可以求出需要从scrollView里截取图片的frame

                     当然主要是求截取图      片坐标原点,可以想象,内容放大一倍,那么截取图片的大小宽度肯定是scrollViewframe大小一半。如下列方法:

           - (CGRect) getRectWithScale:(float)scale andCenter:(float)center

           {

             CGRect newRect;

             newRect.size.width=scrollView.frame.size.width/scale;

             newRect.size.height=scrollView.frame.size.height.scale;

             newRect.origin.x=center.x-newRect.size.width/2;

             newRect.origin.y=center.y-newRect.size.height/2;

             return newRect;

           }

               滑动实现的代理方法

         //scrollView滚动时,就调用该方法。任何offset值改变都调用该方法。即滚动过程中,调用多次

         1- (void)scrollViewDidScroll:(UIScrollView *)scrollView{ 

                 NSLog(@"scrollViewDidScroll");

                 CGPoint point=scrollView.contentOffset;

                 NSLog(@"%f,%f",point.x,point.y);

                 // 从中可以读取contentOffset属性以确定其滚动到的位置。

                 // 注意:当ContentSize属性小于Frame时,将不会出发滚动    

          }

         // 当开始滚动视图时,执行该方法。一次有效滑动(开始滑动,滑动一小段距离,只要手指不松开,只算一次滑动),只执行一次。

         2- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{

                 NSLog(@"scrollViewWillBeginDragging");

         }

         // 滑动scrollView,并且手指离开时执行。一次有效滑动,只执行一次。

         // pagingEnabled属性为YES时,不调用,该方法

         3- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout           CGPoint *)targetContentOffset{

                 NSLog(@"scrollViewWillEndDragging");

         }

         // 滑动视图,当手指离开屏幕那一霎那,调用该方法。一次有效滑动,只执行一次。

         // decelerate,指代,当我们手指离开那一瞬后,视图是否还将继续向前滚动(一段距离),经过测试,decelerate=YES

         4- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{

               NSLog(@"scrollViewDidEndDragging");

               if (decelerate) {

                   NSLog(@"decelerate");

               }else{

               NSLog(@"no decelerate");

               }

               CGPoint point=scrollView.contentOffset;

               NSLog(@"%f,%f",point.x,point.y);

         }

         // 滑动减速时调用该方法。

         5- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{

                 NSLog(@"scrollViewWillBeginDecelerating");

                 // 该方法在scrollViewDidEndDragging方法之后。

         }

         // 滚动视图减速完成,滚动将停止时,调用该方法。一次有效滑动,只执行一次。

         6- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{

                 NSLog(@"scrollViewDidEndDecelerating");

                 [_scrollView setContentOffset:CGPointMake(0, 500) animated:YES];

         }

         // 当滚动视图动画完成后,调用该方法,如果没有动画,那么该方法将不被调用

         7- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{

                 NSLog(@"scrollViewDidEndScrollingAnimation");

                 // 有效的动画方法为:

                 // - (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated 方法

                 // - (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated 方法

         }

  • 相关阅读:
    2018面试题
    输入对象和数量制造批量假数据
    前端监控和前端埋点方案设计--摘抄
    给页面上所有的a标签增加随机数每次点击保证最新
    给所有ajax请求增加随机数
    打印2018年的日历
    为图片添加文字 canvas
    地图搜索地图定位标注
    地图拖拽定位
    智能搜索地图
  • 原文地址:https://www.cnblogs.com/zbw-fly/p/3675565.html
Copyright © 2011-2022 走看看