天天看點

iOS個人整理11-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配合切換視圖

這裡總共有三張圖檔,加了第四張與第一張相同,用來模拟循環狀态

//
//  SecondViewController.m
//  ui_homework_UIScrollViewAlbum
//
//  Created by wanghao on 16/1/18.
//  Copyright © 2016年 wanghao. All rights reserved.
//
#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
           

實作效果:

iOS個人整理11-UIControl與子類:UIScrollView滾動視圖
iOS個人整理11-UIControl與子類:UIScrollView滾動視圖
iOS個人整理11-UIControl與子類:UIScrollView滾動視圖