iOS-个人整理10 - UIControl与子类:UIScrollView滚动视图

一、UIScrollView

UIScrollView是所有滚动视图的基础,很重要,主要用于轮播图,相册等功能
当内容超过一个屏幕时,为了将内容完整呈现,就可以使用UIScrollView

重要属性
1.设置滚动范围:contentSize:返回值为CGSize
2.设置分页效果:(BOOL)pagingEnabled
3.偏移量:contentOffset:返回值为CGPoint,改变偏移量可以切换子视图
4.设置滚动条是否显示:
showsHorizontalScrollIndicator 水平方向
showsVerticallndicator 垂直方向
5.反弹效果:(BOOL)bounces

和缩放相关的属性
1.最小缩放比例:minimumZoomScale:返回值CGFloat
2.最大缩放比例:maximumZoomScale:返回值CGFloat
3.当前的缩放比例:zoomScale

重要的位置属性:automaticallyAdjustsScrollViewInsets
当视图上有导航栏的时候,会比较麻烦,这个属性不是ScrollView的属性,是视图控制器的属性

当 automaticallyAdjustsScrollViewInsets 为 NO 时,滚动视图就不会随便延展
automaticallyAdjustsScrollViewInsets为 YES 时,滚动视图会自动延伸

 

#define WIDTH self.view.frame.size.width  
#define HEIGHT self.view.frame.size.height  
  
-(void)viewDidLoad  
{  
      
#pragma mark UIScroll  
      
    //滚动视图学习,当内容超过一个屏幕时,为了将内容完整呈现  
    UIScrollView *myScrollView = [[UIScrollView alloc]initWithFrame:self.view.frame];  
      
    //设置滚动区域,这个属性控制着能滚动的服务,这里设置为3倍屏幕宽度  
    myScrollView.contentSize = CGSizeMake(WIDTH*3, HEIGHT);  
      
    //设置分页效果  
    myScrollView.pagingEnabled = YES;  
  
    //滚动条样式  
    myScrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;  
      
    //隐藏水平/垂直滚动条  
    myScrollView.showsHorizontalScrollIndicator = NO;  
    myScrollView.showsVerticalScrollIndicator = NO;  
      
    //设置tag  
    myScrollView.tag = 1001;  
      
    //设置反弹效果  
    myScrollView.bounces = YES;  
  
    //设置代理  
    myScrollView.delegate = self;  
      
    //偏移量,相对滚动视图的原点的位置,屏幕从偏移量这个点开始显示滚动视图的内容  
    myScrollView.contentOffset = CGPointMake(WIDTH,0);  
      
    //为滚动视图添加子视图  
    for (int i = 0; i < 3; i++) {  
        UIView *myView = [[UIView alloc]initWithFrame:CGRectMake(WIDTH*i, 0, WIDTH, HEIGHT)];  
          
        myView.backgroundColor = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:1];  
       // [myScrollView addSubview:myView];  
    }  
      
    for (int i = 0; i < 3; i++) {  
        UILabel *myLabel = [[UILabel alloc]initWithFrame:CGRectMake(WIDTH*i, 0, WIDTH, HEIGHT)];  
        myLabel.font = [UIFont systemFontOfSize:220];  
        myLabel.text = [NSString stringWithFormat:@"第%d页",i];  
        //让字体根据Label的width适应大小  
        myLabel.adjustsFontSizeToFitWidth = YES;  
  
        //颜色随机  
        myLabel.backgroundColor = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:1];  
        [myScrollView addSubview:myLabel];  
    }  
      
    //添加滚动视图到父视图  
   [self.view addSubview:myScrollView];  
}  

这样就生成了三个页面UILabel,可以通过手势拖拽进行交换

二、UIScrollView的代理方法

UIScrollView的代理方法主要实现两部分内容:

1.监视视图的滚动状态

首先看看监视视图的缩放

//开始拖拽视图,只有触摸对象滑动才会触发  
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView  
{  
   // NSLog(@"开始拖拽");  
}  
  
//停止拖拽  
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate  
{  
   // NSLog(@"拖拽停止");  
}  
  
//拖拽结束,松开的时候  
-(void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset  
     
  
//正在滚动  
-(void)scrollViewDidScroll:(UIScrollView *)scrollView  
  
//视图结束减速  
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView  
  
  
//将要开始减速  
-(void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView  
     
  
//拖动到了顶端  
-(void)scrollViewDidScrollToTop:(UIScrollView *)scrollView  
2.控制视图的缩放
//返回需要缩放的视图,必须为scrollView的子视图
-(UIView*)viewForZoominglnScrollView:(UIScrollView*)scrollView:

//缩放结束  
-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale  
  
//变换中  
-(void)scrollViewDidZoom:(UIScrollView *)scrollView  
        
//将要开始变形  
-(void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view  

三、一个比较复杂的实例

现在要实现一个简单的相册功能,每个照片还可以通过捏合来进行缩放,切换图片之后之前的图片要恢复原比例
同时添加了一个UIPageControl控件,与UIScrollView配合切换视图
这里总共有三张图片,加了第四张与第一张相同,用来模拟循环状态

#define WIDTH (self.view.frame.size.width)  
#define HEIGHT (self.view.frame.size.height)  
  
#import "SecondViewController.h"  
#import "PhotoScrollView.h"  
  
  
@interface SecondViewController ()<UIScrollViewDelegate>  
  
  
@property (nonatomic,retain)UIScrollView *albumScrollView;//相册滚动视图  
@property (nonatomic,retain)UIPageControl *albunPageControl;//页数小白点  
@property (nonatomic,retain)NSMutableArray *photoArray;//照片数组  
  
@end  
  
@implementation SecondViewController  
  
//_albumScrollView懒加载  
-(UIScrollView *)albumScrollView  
{  
    if (!_albumScrollView) {  
        _albumScrollView = [[UIScrollView alloc]initWithFrame:self.view.frame];  
        _albumScrollView.contentSize = CGSizeMake(WIDTH*5, HEIGHT);  
        //翻页设置  
        _albumScrollView.pagingEnabled = YES;  
    }  
    return _albumScrollView;  
}  
-(UIPageControl *)albunPageControl  
{  
    if (!_albunPageControl) {  
        _albunPageControl = [[UIPageControl alloc]initWithFrame:CGRectMake(0, 600, WIDTH, 50)];  
        //添加方法  
       // [_albunPageControl addTarget:self action:@selector(pageControlChangeView:) forControlEvents:UIControlEventValueChanged];  
    }  
    return _albunPageControl;  
}  
//数组懒加载  
-(NSMutableArray *)photoArray  
{  
    if (!_photoArray) {  
        _photoArray = [[NSMutableArray alloc]initWithCapacity:2];  
    }  
    return _photoArray;  
}  
  
-(void)viewDidLoad  
{  
    //添加滚动图并设置代理  
    [self.view addSubview:self.albumScrollView];  
    _albumScrollView.delegate = self;  
      
    //添加PageControl  
    [self.view addSubview:self.albunPageControl];  
    //设置PageControl的页数  
    _albunPageControl.numberOfPages = 3;  
      
    //给pageControl添加方法  
    [_albunPageControl addTarget:self action:@selector(pageControlChangeView:) forControlEvents:UIControlEventValueChanged];  
     
  
    //添加三张图片  
    [self.photoArray addObject:[self addPhoto:CGRectMake(0, 0, WIDTH, HEIGHT) Image:[UIImage imageNamed:@"s1.png"]Tag:1000]];  
    [self.photoArray addObject:[self addPhoto:CGRectMake(WIDTH, 0, WIDTH, HEIGHT) Image:[UIImage imageNamed:@"s2.png"]Tag:1001]];  
    [self.photoArray addObject:[self addPhoto:CGRectMake(WIDTH*2, 0, WIDTH, HEIGHT) Image:[UIImage imageNamed:@"s3.png"]Tag:1002]];  
  
    //添加一张与第一张重复的图片,制造循环效果  
    [self addPhoto:CGRectMake(WIDTH*3, 0, WIDTH, HEIGHT) Image:[UIImage imageNamed:@"s1.png"]Tag:1003];  
  
}  
  
//添加图片函数  
-(UIScrollView*)addPhoto:(CGRect)frame Image:(UIImage*)image Tag:(NSInteger)tag  
{  
    //创建UIScrollView  
    UIScrollView *photoScrollView =[[UIScrollView alloc]initWithFrame:frame];  
    //创建UIimageView  
    UIImageView *photoImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, WIDTH, HEIGHT)];  
    photoImageView.image = image;  
      
    //设置代理  
    photoScrollView.delegate = self;  
      
    //添加视图缩放范围,没有这个缩放不了 找了半天。。。。。。。。。。。。。。。。。。。。。。。  
    photoScrollView.minimumZoomScale = 0.3;  
    photoScrollView.maximumZoomScale = 3;  
  
    //添加到父视图  
    [photoScrollView addSubview:photoImageView];  
    [self.albumScrollView addSubview:photoScrollView];  
      
    return photoScrollView;  
}  
  
//pageControl点击时进行滚动  
-(void)pageControlChangeView:(UIPageControl*)sender  
{  
    //根据页数设置偏移量,加动画  
    [_albumScrollView setContentOffset:CGPointMake(sender.currentPage*WIDTH, 0)animated:YES];  
}  
  
#pragma mark 代理  
  
//实现代理缩放方法  
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView  
{  
  
    for (id item in scrollView.subviews) {  
        if ([item isKindOfClass:[UIImageView class]]) {  
            return item;  
        }  
    }  
    return nil;  
}  
  
//在左右拖拽时实现方法  
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView  
{  
      
//1.进行循环设置  
      
    //得到当前的偏移量  
    CGFloat offset_X = _albumScrollView.contentOffset.x;  
      
    //偏移到第四张之后,手动设置偏移量为0  
    if (offset_X >= WIDTH*3) {  
        _albumScrollView.contentOffset = CGPointMake(0, 0);  
        _albunPageControl.currentPage = 0;  
    }  
    else  
    {  
        //使PageControl与Scroll同步  
        _albunPageControl.currentPage = offset_X/WIDTH;  
    }  
      
    //在切换图片的时候使照片恢复原来大小  
    //找到当前偏移值对应的数组index,但是向左右拨动又不一样,有点麻烦  
    int index = (int)(offset_X/WIDTH)-1;  
    NSLog(@"index = %d",index);  
    // PhotoView *tempView = _photoArray[index];  
    //遍历数组全修改了  
    for (UIScrollView *tempView in _photoArray) {  
        tempView.transform = CGAffineTransformMakeScale(1, 1);  
    }  
      
//2.进行缩放恢复设置  
      
    //根据偏移量得到当前page  
    int numPage = offset_X/WIDTH;  
      
    //用数组要考虑越界问题  
    if (numPage > 0 && numPage < 2) {  
        UIScrollView *leftScrollView = _photoArray[numPage-1];  
        UIScrollView *rightScrollView = _photoArray[numPage+1];  
        //恢复比例  
        leftScrollView.zoomScale = 1.0;  
        rightScrollView.zoomScale = 1.0;  
    }  
    else if (numPage == 0)  
    {  
        UIScrollView *rightScrollView = _photoArray[numPage+1];  
        rightScrollView.zoomScale = 1.0;  
    }  
    else if (numPage == 2)  
    {  
        UIScrollView *leftScrollView = _photoArray[numPage-1];  
        //恢复比例  
        leftScrollView.zoomScale = 1.0;  
    }  
}  
  
//缩放时保持图片在中央  
-(void)scrollViewDidZoom:(UIScrollView *)scrollView  
{  
    UIImageView *myImageView = scrollView.subviews[0];  
    float contentX = scrollView.contentSize.width;  
    float contentY = scrollView.contentSize.height;  
      
    //如果放大没有超出边界  
    if (contentX < WIDTH && contentY <HEIGHT) {  
            myImageView.center = self.view.center;  
        NSLog(@"w = %f,h = %f",contentX,contentY);  
    }  
    else //如果放大超出了屏幕frame  
    {  
         
        myImageView.center = CGPointMake(contentX/2, contentY/2);  
    }  
    for (id item in scrollView.subviews) {  
        NSLog(@"zssm = %@",item);  
    }  
  
}  
  
@end  

实现效果:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容