博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS之UIScrollView的使用详解
阅读量:4289 次
发布时间:2019-05-27

本文共 5485 字,大约阅读时间需要 18 分钟。

/**

     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(上图中的蓝色区域),暂且叫它(实际是没有这个东西的).当我们在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;

}

你可能感兴趣的文章
CAS原子操作实现无锁及性能分析
查看>>
太上老君为何不能将孙悟空炼化
查看>>
Linux 互斥锁、原子操作实现原理
查看>>
搭建简单hls直播测试服务
查看>>
共享内存的数据同步
查看>>
LVS-入门试用
查看>>
Cache和Buffer的区别
查看>>
50个sql语句
查看>>
MYSQL sql 语句性能分析
查看>>
C++操作Redis数据库
查看>>
python yield用法
查看>>
python pipe模块用法
查看>>
安装完 MySQL 后必须调整的 10 项配置
查看>>
开发者必备的 12 个 JavaScript 库
查看>>
http错误码
查看>>
python 多线程
查看>>
sipp命令 各参数含义
查看>>
搜集的动植物分类、检索网站
查看>>
ffmpeg源码分析之媒体打开过程
查看>>
Ubuntu/centos/redhat/SUSE sipp安装(带rtp支持,3.5.1版本)
查看>>