iOS之UIScrollView的使用详解

/**

     scrollView中的内容滚动就必须要设置滚动范围

     

     contentSize : 子控件的大小限定滚动的范围

     

     contentSize 在设置的时候一定要比scrollView size 要大

     

     如果size 中的 宽度 设为 0 , 就表示在 横向中不能滚动

     */

    

    _scrollView.contentSize = self.imageView.frame.size;

    

    

    /**

     Horizontal : 水平

     Vertical  : 垂直

     是否隐藏滚动指示器

     */

    _scrollView.showsHorizontalScrollIndicator = NO;

    _scrollView.showsVerticalScrollIndicator = NO;

    

    /**

     bounces : 弹簧效果 ,默认是YES 一般是不关闭

     */

    

    _scrollView.bounces = YES;

    

    

    /**

     不设置contentSize的时候弹簧效果开启依然看不到

     

     即使不设置contentSize , 在水平和垂直方向上依然有弹簧效果

     前提是:  scrollView.bounces = YES;

     alwaysBounceHorizontal

     alwaysBounceVertical

     */

    

    _scrollView.alwaysBounceHorizontal = YES;

    _scrollView.alwaysBounceVertical = YES;

    

    

    /**

     没有设置contentInset的时候拖动后imageView默认会停留在初始位置

     contentInset : 拖动后会停留在设置 的内边距的位置(imageView边界距离scrollView的边距)

     

     变相的增加了 滚动的范围

      top, left, bottom, right

     */

    

    _scrollView.contentInset = UIEdgeInsetsMake(10203040);

    

    

    /**

     contentOffset :  offset 偏移量 , 滚动到了某个位置

     */

    

    _scrollView.contentOffset = CGPointMake



    /**

     scrollView 不能滚动的原因

     1. contentSize  scrollViewsize 

     2. _scrollView.userInteractionEnabled = NO;

     3. _scrollView.scrollEnabled = NO;

     */


// 设置contentOffset的时候有动画效果

    [_scrollView setContentOffset:offset animated:YES];

    


// scrollView内容滚动的时候就会调用只要在滚动就会调用

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

    

    NSLog(@"滚动的时候调用 %@",NSStringFromCGPoint(scrollView.contentOffset));

}


// Drag : 拖拽 开始拖拽的时候调用, 是只会调用一遍

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

    NSLog(@"开始拖拽的时候调用");

}


// 停止拖拽 , 调用一次(停止减速的时候调用,手动停止的时候调用)

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

    NSLog(@"停止拖拽的时候调用");

}


//用代码的方式停止滚动的时候调用这个方法
-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{

}
=============================

缩放:

- (void)viewDidLoad {

    [super viewDidLoad];

    /**

      minimumZoomScale;   --> 最小的缩小倍数

       maximumZoomScale;  --> 最大的放大倍数

     */

    

    _scrollView.minimumZoomScale = 0.3;

    _scrollView.maximumZoomScale = 3;

    

    // 设置控制器成为scrollView的代理

    _scrollView.delegate = self;

    

}

// 返回的view将被拉伸(缩放)

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {

    return _imageView;

}


// 只要图片在放大/缩小的过程中都会一直调用

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

    NSLog(@"scrollViewDidZoom");

}


// 开始缩放的时候调用

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view {

    NSLog(@"scrollViewWillBeginZooming");

}


// 结束的时候调用

// withView: 进行缩放的view

// atScale: 缩放的倍数

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {

    NSLog(@"scrollViewDidEndZooming");

}


1.==============UISCrollView 在自动布局中的使用注意

   //autolayout下,会在viewDidAppear之前根据subviewconstraint重新计算scrollviewcontentsize 这就是为什么,在viewdidload里面手动设置了contentsize没用。因为在后面,会再重新计算一次,前面手动设置的值会被覆盖掉。

//    解决办法就是:

//    1.去除autolayout选项,自己手动设置contentsize

//    2.如果要使用autolayout,要么自己设置完subviewconstraint,然后让系统自动根据constraint计算出contentsize 要么就在viewDidAppear里面自己手动设置contentsize

    self.baseScrollView.contentSize=CGSizeMake(0self.view.frame.size.height*2-300);//basescrollView的滚动范围


scrollview布局的注意事项:

首先,我们需要添加一个UIView类型的控件成为UIScrollView的唯一子控件,并设置其上下左右间距都为0,这时候我们发现设置完四个约束后仍然会报错,这里我们就来解释一下UIScrollView的特殊性:其实UIScrollView要想实现滚动,必须设置其滚动区域contentSize,而这里UIScrollView的滚动区域是由其子控件的内容决定的,所以这里我们先添加一个UIView成为UIScrollView的唯一子控件,并设置其上下左右约束均为0,然后设置UIView的宽度为300(这个高度就是UIScrollView的内容宽度: contentSize.weight),在设置垂直居中,然后运行程序就会看到UIScrollView可以左右滚动了.


上下滚动就将UIView的高度约束设置成300(这个高度就是UIScrollView的内容高度: contentSize.height),水平居中就可以了.
如果要想上下左右都可以滚动,那么就将宽高约束都设置为300.不用设置水平和垂直居中.

4.接下来所有的控件都添加到UIView中即可利用自动布局来设置约束.





问题的关键在于如何给scrollView内部的子控件添加约束.

scrollView内部子控件约束的添加需要遵循两个原则:

1、scrollView内部子控件的尺寸不能以scrollView的尺寸为参照
2、scrollView内部的子控件的约束必须完整

首先,子控件的尺寸不能以scrollView的尺寸为参照,那么我们有两种选择:

  • 提供一个具体值的约束(比如200)
  • 子控件的尺寸可以参照scrollView以外其它的控件的尺寸(如控制器的view的尺寸)

其次,约束"完整"的意思是说:子控件在水平及竖直方向上的约束要把scrollView"撑满".

也就是说,在水平方向上,我们需要设置:

  • 子控件左侧与父控件的距离
  • 子控件自身的宽度
  • 子控件右侧距父控件的距离.

竖直方向上也一样,要设置:

  • 子控件顶部距父控件的距离
  • 子控件的高度
  • 子控件底部距父控件的距离.
为什么scrollView如此隔路(隔路:特殊,与众不同)呢?

这是因为,scrollView需要根据添加在其内部的子控件的宽高及与四周的距离计算出它的contentSize.

举个栗子:
一个添加在scrollView内部的imageView的宽高为{80, 50}, imageView距离上左下右的距离分别为:100, 200, 300, 400,那么不需要用代码赋值contentSize,我们就可以打印出scrollView的contentSize为{680, 450}.
如图:


IB添加约束的原理

如果理解起来还是有困难,我们可以把scrollView的contentSize的范围想象成一块UIView(上图中的蓝色区域),暂且叫它Container(实际是没有这个东西的).当我们在storyboard或xib中设置子控件与scrollView之间约束时,实际上设置的是子控件与container之间的约束.

也就是说,子控件的约束决定了container的尺寸(contentSize).
这就说明了为什么我们要在水平和竖直方向用约束"撑满".如果不撑满,container不知道它自己应该多大.

也正是因为container的尺寸由子控件的约束决定,所以子控件的尺寸不能再反过来参照container的尺寸.不然你等于我,我等于你,那到底是多少呢?如果你是Xcode你也会抓狂.(再次强调那个container不是真的,只是为了方便理解)

理论部分解释完毕,回到一开始的案例上.

imageView有了上下左右四个约束,还缺少宽高,我们再添加个固定宽高的约束(可以大一点,太小了看不到滚动效果),问题就可以解决了.

强调一下, 用代码给scrollView添加约束(包括使用Masonry的情况)是一样的.

-------------UIScrollView的代理方法-----

/**

 在开始拖拽的时候,把计时器停止

 

 invalidate 无效的意思

 */

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

    // 让计时器无效

    [self.timer invalidate];

    self.timer=nil;

    NSLog(@"定时器无效1");

}

//手指离开scrollview的时候

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

    NSLog(@"停止拖拽");

}

/**

 当停止加速的时候,让计时器开始工作

 手指离开scrollView的时候

 */

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

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

    

    NSLog(@"停止加速");

        [self NSTimers];

   

}


//正在滚动的时候

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

   

}

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

    NSLog(@"结束滚动");

    NSInteger pageIndex=self.headerScroll.contentOffset.x/self.headerScroll.frame.size.width;

    self.pageCtrl.currentPage=pageIndex;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值