ios UIScrollView代理方法追踪 及使用
。。。。。。。。。文明看帖转载是对自己的尊重也是对别人的鼓励,欢迎批评讨论。。。。。。。。。
一 .UIScrollView简介
1.UIScrollView继承自UIView,它的主要作用是用来承载更多的可见视图,它和UIView的最大区别是多了一个ContentSize属性,当你初始化UIScrollView时,不指定ContentSize时,UIScrollView和UIView的作用没什么区别,UIView所能承载的范围是它的bounds,而UIScrollView能承载子视图的范围是ContentSize的范围,这样的话你想要通过bounds的范围去看比它还大的contentsize的内容的话就通过手势识别器根据手势的移动来显示contentSize部分内容,contentOffset+bounds决定了UIScrollView的可视范围:
二.UIScrollView代理方法的追踪
note:UIScrollView的代理方法的追踪主要是使用函数:NSLog(@"%s----%d",__FUN__,trackTag)//其中__FUN__为编译层面上的宏,它的作用时把调用的函数的名字字符串可视化,trackTag是自己定义的全局静态整形变量,用来标示调用顺序,在每个代理方法中调用,这样就可以根据其输出来判断各个动作能引起什么样的代理方法调用,从而掌握UI ScrollView的UI动作特性,才能真正的在App中灵活的应用
1.下面为要跟踪的代理方法,ios的UIKit框架遵循的是MVC模式设计,在View层中关于可视控件的操作都通过代理或者Action-target的语法释放出来,如UIButton通过Action-target,点击UIButton会触发target的指定方法,今天讨论的UIScrollView 就是通过代理的语法方式把所有的触摸手势动作映出,自己通过触摸事件改变自己的外观,下面为代理方法- (void)scrollViewDidScroll:(UIScrollView *)scrollView; //只要contentOffset发生了改变都会触发改方法及简单的注释
- (void)scrollViewDidZoom:(UIScrollView *)scrollView; //只要缩放比例发生了改变就会触发改方法 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView; //开始移动 - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset //将要结束移动 - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;//结束移动和是否要减速,后面有详细说明 - (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView; //将要开始减速
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView; //结束减速
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView; //结束了滚动动画 - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView; //返回一个贴在UIScrollview上的子视图用来做缩放
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view//指定缩放的view将要开始缩放
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale; //指定缩放的view缩放到scale级别了 - (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView; //scrollView是否滚动到顶部
- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView; //scrollview滚动到顶部了
下面为跟踪代码
1.新建一个single view project
2.在现有的viewController视图控制器的实现文件中定义一个静态的全局int类型的trackTag变量
static int trackTag=0; @interface ViewController ()<UIScrollViewDelegate> @end @implementation ViewController{ UIView *subView; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. UIScrollView *scroll =[[UIScrollView alloc]initWithFrame:CGRectMake(0, 100, 200, 400)]; scroll.contentSize = CGSizeMake(400, 800); //contentSize比bounds大两倍 scroll.backgroundColor = [UIColor brownColor]; scroll.delegate = self; [self.view addSubview:scroll]; NSLog(@"%@",NSStringFromCGPoint(scroll.contentOffset)); NSLog(@"%@",NSStringFromCGSize(scroll.contentSize)); }
3.在viewController中实现UI ScrollView的代理方法并在代理方法中输入NSLog(@"%s----%d",__FUN__,trackTag++),这样当对UIScrollView操作时就会输出代理方法的调用顺序,如:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
NSLog(@"%s ------ %d",__func__,trackTag++);
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView{
NSLog(@"%s ------ %d",__func__,trackTag++);
}
。
。
。剩下的代理方法
4.结果分析
a.第一种情况:当手指触摸到UIScrollview时没有任何移动时,UIScrollView的代理方法没有一个被触发,当手指移动之后停下但是手指不离开UI ScrollView界面及离开屏幕的代理方法的调用结果如下(这个手势可以理解为Pan手势:触摸-移动-离开屏幕):
2014-12-20 15:46:15.471 gcd[1109:69214] -[ViewController scrollViewWillBeginDragging:] ------ 0 //并没有移动只是touch上去
2014-12-20 15:46:15.502 gcd[1109:69214] -[ViewController scrollViewDidScroll:] ------ 1 //移动之后就会改变contentOffset所以就会调用改方法
2014-12-20 15:46:15.519 gcd[1109:69214] -[ViewController scrollViewDidScroll:] ------ 2
2014-12-20 15:46:15.551 gcd[1109:69214] -[ViewController scrollViewDidScroll:] ------ 3
2014-12-20 15:46:15.586 gcd[1109:69214] -[ViewController scrollViewDidScroll:] ------ 4
2014-12-20 15:46:15.619 gcd[1109:69214] -[ViewController scrollViewDidScroll:] ------ 5
2014-12-20 15:46:15.653 gcd[1109:69214] -[ViewController scrollViewDidScroll:] ------ 6
2014-12-20 15:46:15.669 gcd[1109:69214] -[ViewController scrollViewDidScroll:] ------ 7
2014-12-20 15:46:15.696 gcd[1109:69214] -[ViewController scrollViewDidScroll:] ------ 8
///
手指停止移动但是没有离开屏幕
///
//手指离开屏幕之后屏幕并没有移动就只会调用下面的两个方法,
2014-12-20 15:46:24.736 gcd[1109:69214] -[ViewController scrollViewWillEndDragging:withVelocity:targetContentOffset:] ------ 9
2014-12-20 15:46:24.736 gcd[1109:69214] -[ViewController scrollViewDidEndDragging:willDecelerate:] ------ 10
b.触摸移动离开一个连贯的动作,可以理解为Swipe的扫动动作结果如下:
2014-12-20 16:13:25.477 gcd[1146:76145] -[ViewController scrollViewWillBeginDragging:] ------ 0
2014-12-20 16:13:25.477 gcd[1146:76145] -[ViewController scrollViewDidScroll:] ------ 1
2014-12-20 16:13:25.515 gcd[1146:76145] -[ViewController scrollViewDidScroll:] ------ 2
2014-12-20 16:13:25.532 gcd[1146:76145] -[ViewController scrollViewDidScroll:] ------ 3
2014-12-20 16:13:25.565 gcd[1146:76145] -[ViewController scrollViewWillEndDragging:withVelocity:targetContentOffset:] ------ 4
2014-12-20 16:13:25.565 gcd[1146:76145] -[ViewController scrollViewDidEndDragging:willDecelerate:] ------ 5
//前面的动作和a情况一样
//比一样的调用如下,a情况时手离开屏幕时没有移动的速度,b情况时手离开屏幕时有速度
2014-12-20 16:13:25.566 gcd[1146:76145] -[ViewController scrollViewWillBeginDecelerating:] ------ 6 //因为有速度将要减速
2014-12-20 16:13:25.582 gcd[1146:76145] -[ViewController scrollViewDidScroll:] ------ 7 //减速时的屏幕出现content Offset改变
2014-12-20 16:13:25.599 gcd[1146:76145] -[ViewController scrollViewDidScroll:] ------ 8
2014-12-20 16:13:25.616 gcd[1146:76145] -[ViewController scrollViewDidScroll:] ------ 9
2014-12-20 16:13:26.349 gcd[1146:76145] -[ViewController scrollViewDidScroll:] ------ 10
2014-12-20 16:13:26.353 gcd[1146:76145] -[ViewController scrollViewDidEndDecelerating:] ------ 11//屏幕停止
至于其他的代理方法读者可以通过相同的方法写例子
总结:在实际的开发过程种上面的代理方法调用的时间点是非常有用的,因为UITableview和UICollectionView都是继承UI ScrollView的,UITableView和UICollectionView在实际开发中又是无处不在的,通过这些代理方法的调用时间点,可以通过contentOffset来控制自己的显示区域。