iOS开发之UI篇(9)—— UIScrollView、UIPageControl

来源:互联网 发布:陈丹青局部观后感知乎 编辑:程序博客网 时间:2024/05/29 16:58

版本
Xcode 9.1

一、纯代码创建

1. 简单使用

首先,定义一个UIScrollView类型的属性:

@property (nonatomic, strong) UIScrollView *scrollView;

然后在懒加载(getter方法)里设置scrollView相关属性:

#define     SCROLL_WIDTH      [UIScreen mainScreen].bounds.size.width#define     SCROLL_HEIGHT     [UIScreen mainScreen].bounds.size.height/3#pragma mark - 懒加载- (UIScrollView *)scrollView {    if (_scrollView == nil) {        // 实例化        _scrollView = [[UIScrollView alloc] init];        // 设置尺寸大小        _scrollView.frame = CGRectMake(0, 20, SCROLL_WIDTH, SCROLL_HEIGHT);        // 设置滚动区域        _scrollView.contentSize = CGSizeMake(SCROLL_WIDTH*3, SCROLL_HEIGHT);        // 隐藏水平滑条        _scrollView.showsHorizontalScrollIndicator = NO;        // 设置分页(每次滑动一页)        _scrollView.pagingEnabled = YES;        // 弹簧效果(边界拉出来一小段会弹回去)        _scrollView.bounces = NO;    //关闭    }    return _scrollView;}

然后就可以在viewDidLoad或者其他地方调用scrollView了:

- (void)viewDidLoad {    [super viewDidLoad];    // 实例化3个UIImageView,并添加到scrollView    for(int i=0; i<3; i++) {        UIImageView *imageView = [[UIImageView alloc] init];        imageView.frame = CGRectMake(SCROLL_WIDTH*i, 0, SCROLL_WIDTH, SCROLL_HEIGHT);        imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",i]];        // 将imageView添加到scrollView        [self.scrollView addSubview:imageView];    }    // 添加scrollView到self.view    [self.view addSubview:self.scrollView];}

效果图:


2. 实现图片循环切换

先来讲讲思路:
如下图,我们要实现三张图片的循环切换。
首先,我们设置五个视图,第一个视图显示最后一张图片,最后一个视图显示第一张图片。
然后,设置scrollView的初始偏移量为第二个视图。
最后,设置代理,在滑动结束的代理方法中,(悄悄地)将试图1切换到视图4,亦或将视图5切换到视图2。


scrollView内容

完整代码如下:

#define     SCROLL_WIDTH      [UIScreen mainScreen].bounds.size.width#define     SCROLL_HEIGHT     [UIScreen mainScreen].bounds.size.height/3#import "ViewController.h"@interface ViewController () <UIScrollViewDelegate>@property (nonatomic, strong) UIScrollView *scrollView;@end@implementation ViewController#pragma mark - 生命周期- (void)viewDidLoad {    [super viewDidLoad];    // 实例化5个UIImageView,并添加到scrollView    for(int i=0; i<5; i++) {        UIImageView *imageView = [[UIImageView alloc] init];        imageView.frame = CGRectMake(SCROLL_WIDTH*i, 0, SCROLL_WIDTH, SCROLL_HEIGHT);        imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",i]];        if (i == 0) {            // 第一个视图显示最后一张图片            imageView.image = [UIImage imageNamed:@"2.jpg"];        }else if(i == 4){            // 第五个视图显示第一张图片            imageView.image = [UIImage imageNamed:@"0.jpg"];        }else {            imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",i-1]];        }        // 添加imageView到scrollView        [self.scrollView addSubview:imageView];    }    // 添加scrollView到self.view    [self.view addSubview:self.scrollView];}#pragma mark - UIScrollViewDelegate// 已经停止减速- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {    // 改变偏移量    if (scrollView.contentOffset.x >= SCROLL_WIDTH*4) {        // 移动到第一个视图        scrollView.contentOffset = CGPointMake(SCROLL_WIDTH*1, 0);    }else if(scrollView.contentOffset.x <= 0){        // 移到第三个视图        scrollView.contentOffset = CGPointMake(SCROLL_WIDTH*3, 0);    }}#pragma mark - 懒加载- (UIScrollView *)scrollView {    if (_scrollView == nil) {        // 实例化        _scrollView = [[UIScrollView alloc] init];        // 设置尺寸大小        _scrollView.frame = CGRectMake(0, 20, SCROLL_WIDTH, SCROLL_HEIGHT);        // 设置滚动区域        _scrollView.contentSize = CGSizeMake(SCROLL_WIDTH*5, SCROLL_HEIGHT);        // 隐藏水平滑条        _scrollView.showsHorizontalScrollIndicator = NO;        // 设置分页(每次滑动一页)        _scrollView.pagingEnabled = YES;        // 弹簧效果(边界拉出来一小段会弹回去)        _scrollView.bounces = NO;    //关闭        _scrollView.contentOffset = CGPointMake(SCROLL_WIDTH*1, 0);        // 设置代理方法        _scrollView.delegate = self;    }    return _scrollView;}

效果:


3. UIScrollView搭配UIPageControl

实现的效果如下:定时每3秒钟自动向后翻一页。当开始有手指拖拽时,定时暂停;直到松开手指视图滑动结束后,才重新3秒定时。


效果图

只需在如上的代码添加一个UIPageControl用于小点点显示当前页数,和添加一个定时器NSTimer用于定时切换。
完整代码:

#define     SCROLL_WIDTH      [UIScreen mainScreen].bounds.size.width#define     SCROLL_HEIGHT     [UIScreen mainScreen].bounds.size.height/3#import "ViewController.h"@interface ViewController () <UIScrollViewDelegate> {    NSTimer     *_timer;}@property (nonatomic, strong) UIScrollView *scrollView;@property (nonatomic, strong) UIPageControl *pageControl;@end@implementation ViewController#pragma mark - 生命周期- (void)viewDidLoad {    [super viewDidLoad];    // 实例化5个UIImageView,并添加到scrollView    for(int i=0; i<5; i++) {        UIImageView *imageView = [[UIImageView alloc] init];        imageView.frame = CGRectMake(SCROLL_WIDTH*i, 0, SCROLL_WIDTH, SCROLL_HEIGHT);        imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",i]];        if (i == 0) {            // 第一个视图显示最后一张图片            imageView.image = [UIImage imageNamed:@"2.jpg"];        }else if(i == 4){            // 第五个视图显示第一张图片            imageView.image = [UIImage imageNamed:@"0.jpg"];        }else {            imageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",i-1]];        }        // 添加imageView到scrollView        [self.scrollView addSubview:imageView];    }    // 添加scrollView到self.view    [self.view addSubview:self.scrollView];    // 添加pageControl到self.view    [self.view addSubview:self.pageControl];    // 启动定时器    _timer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(changeImage:) userInfo:nil repeats:YES];}#pragma mark - UIScrollViewDelegate// 准备开始滑动 (仅手动拖拽时调用;代码设置setContentOffset:/scrollRectToVisible:不会调用)- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {    [_timer setFireDate:[NSDate distantFuture]];    // 很久之后才触发,相当于暂停}// 已经停止减速(仅手动拖拽时调用)- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {    _timer.fireDate = [NSDate dateWithTimeInterval:3.0 sinceDate:[NSDate date]];    [self updateContentOffsetAndCurrentPage];}#pragma mark - 私有方法// 定时3秒时间到,开始切换图片- (void)changeImage:(NSTimer *)timer {    CGPoint tempPoint = self.scrollView.contentOffset;    tempPoint.x += SCROLL_WIDTH;    if (tempPoint.x/SCROLL_WIDTH >= 5) {        tempPoint.x = 0;    }    self.scrollView.contentOffset = tempPoint;    [self updateContentOffsetAndCurrentPage];}// 更新当前图片和页数- (void)updateContentOffsetAndCurrentPage {    // 更新偏移量    if (self.scrollView.contentOffset.x >= SCROLL_WIDTH*4) {        // 移动到第一个视图        self.scrollView.contentOffset = CGPointMake(SCROLL_WIDTH*1, 0);    }else if(self.scrollView.contentOffset.x <= 0){        // 移到第三个视图        self.scrollView.contentOffset = CGPointMake(SCROLL_WIDTH*3, 0);    }    // 更新当前页数    NSInteger currentPage = (self.scrollView.contentOffset.x-SCROLL_WIDTH)/SCROLL_WIDTH;    if (currentPage < 0) {        currentPage = 0;    }else if (currentPage > 2) {        currentPage = 2;    }    self.pageControl.currentPage = currentPage;}#pragma mark - 懒加载- (UIScrollView *)scrollView {    if (_scrollView == nil) {        // 实例化        _scrollView = [[UIScrollView alloc] init];        // 设置尺寸大小        _scrollView.frame = CGRectMake(0, 20, SCROLL_WIDTH, SCROLL_HEIGHT);        // 设置滚动区域        _scrollView.contentSize = CGSizeMake(SCROLL_WIDTH*5, SCROLL_HEIGHT);        // 隐藏水平滑条        _scrollView.showsHorizontalScrollIndicator = NO;        // 设置分页(每次滑动一页)        _scrollView.pagingEnabled = YES;        // 弹簧效果(边界拉出来一小段会弹回去)        _scrollView.bounces = NO;    //关闭        _scrollView.contentOffset = CGPointMake(SCROLL_WIDTH*1, 0);        // 设置代理方法        _scrollView.delegate = self;    }    return _scrollView;}- (UIPageControl *)pageControl {    if (_pageControl == nil) {        // 实例化UIPageControl        _pageControl = [[UIPageControl alloc] init];        _pageControl.frame = CGRectMake(0, 20+SCROLL_HEIGHT-30, SCROLL_WIDTH, 30);        // 设置总页数        _pageControl.numberOfPages = 3;        // 设置背景色        _pageControl.backgroundColor = [UIColor clearColor];        // 设置当前页颜色        _pageControl.currentPageIndicatorTintColor = [UIColor purpleColor];        // 设置其他页颜色        _pageControl.pageIndicatorTintColor = [UIColor greenColor];        //添加事件//        [_pageControl addTarget:self action:@selector(pageDidChanged:) forControlEvents:UIControlEventValueChanged];    }    return _pageControl;}@end

4. 使用UIScrollView实现图片缩放功能

首先,设置滚动区域足够大,并设置缩放比例范围:

        // 设置滚动区域        _scrollView.contentSize = CGSizeMake(SCROLL_WIDTH*5, SCROLL_HEIGHT*5);        _scrollView.minimumZoomScale = 0.5;     // 最小缩小比例        _scrollView.maximumZoomScale = 2.0;     // 最大放大比例

然后在scrollView里添加图片:

    UIImage *image = [UIImage imageNamed:@"1.jpg"];    _imageView = [[UIImageView alloc] initWithImage:image];    [self.scrollView addSubview:_imageView];

最后在代理方法里返回需要放大的控件:

// 缩放代理方法:返回需要缩放的视图 (手动拖拽及代码设置缩放均会调用)- (nullable UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {    return _imageView;}

接下来,可用手指捏合图片或者调用setZoomScale:animated:/zoomToRect:animated:方法来触发以下代理方法执行进一步操作:

// 准备开始缩放 (手动拖拽及代码设置均会调用)- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(nullable UIView *)view NS_AVAILABLE_IOS(3_2) {    NSLog(@"%s",__func__);}// 正在缩放 (手动拖拽及代码设置均会调用,可能多次调用)- (void)scrollViewDidZoom:(UIScrollView *)scrollView NS_AVAILABLE_IOS(3_2) {    NSLog(@"%s",__func__);}// 已结束缩放 (手动拖拽及代码设置均会调用)- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(nullable UIView *)view atScale:(CGFloat)scale {    NSLog(@"%s",__func__);}

5. UIScrollView的代理方法总结

// 准备开始滑动 (仅手动拖拽时调用;代码设置setContentOffset:/scrollRectToVisible:不会调用)- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;// 已经开始滑动(手动拖拽及代码设置滚动均会调用,可能多次调用)- (void)scrollViewDidScroll:(UIScrollView *)scrollView;// 准备结束滑动(仅手动拖拽时调用)- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset NS_AVAILABLE_IOS(5_0);// 已经结束滑动(仅手动拖拽时调用)- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;// 准备开始减速(仅手动拖拽时调用)- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView;// 已经停止减速(仅手动拖拽时调用)- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;// 滚动完毕(代码设置setContentOffset/scrollRectVisible:animated:,且animated设为YES时才调用)- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView;// 缩放代理方法:返回需要缩放的视图 (手动拖拽及代码设置均会调用)- (nullable UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView;// 准备开始缩放 (手动拖拽及代码设置均会调用)- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(nullable UIView *)view NS_AVAILABLE_IOS(3_2);// 正在缩放 (手动拖拽及代码设置均会调用,可能多次调用)- (void)scrollViewDidZoom:(UIScrollView *)scrollView NS_AVAILABLE_IOS(3_2);// 已结束缩放 (手动拖拽及代码设置均会调用)- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(nullable UIView *)view atScale:(CGFloat)scale;// 是否能滚动到顶端 (当手指触摸状态栏的时候)- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView;// 已经完成滚动到顶端 (触摸状态栏顶端时调用)- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView;// adjustedContentInset(与边缘的距离)值被改变的delegate- (void)scrollViewDidChangeAdjustedContentInset:(UIScrollView *)scrollView API_AVAILABLE(ios(11.0), tvos(11.0));

二、使用XIB与storyboard创建

和UIView的创建差不多,就多了个delegate的关联,就不浪费时间贴上了。可参阅之前的博文:http://www.jianshu.com/p/9362d0274ed5。

原创粉丝点击