zoukankan      html  css  js  c++  java
  • UIScorllView和UIPageController的区别和实现图片轮播

    首先我们要先建一个project,选择iOS下的第一个Application 中的Single View Application

    开始工作已经准备完毕现在我们进入到Main.storyboard拖控件

    需要用到的控件有

    • UIScrollView也就是滚动的那个
    • UIPageControl也就是图片下面那几个小点
    • NSTimer就是定时器让其自动换页的

    第一步:拖控件连线

    • 在Main.storyboard拖一个UIScrollView放在屏幕上,在UIScrollView下面放一个UIPageControl(注意是下面而不是在UIscrollView上放,如果放到UIScrollView上将看不到UIPageControl)
    • 进行连线,将其连到ViewController.m中的@interface ViewController () 和@end中间
    #import "ViewController.h"
    @interface ViewController ()
    @property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
    @property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
    @end

    第二步:下面我们要在ViewDidLod中把一个UIImageView加到scrollView中。同时我们要将5张图片放到Images.xcassets中,代码如下

    复制代码
    // 广告图片总数
        int count = 5;
        CGSize size = self.scrollView.frame.size;
        for (int i = 0; i < count; i++) {
            NSString *imageName = [NSString stringWithFormat:@"img_%02d", i + 1];
            UIImage *image = [UIImage imageNamed:imageName];
            UIImageView *iconView = [[UIImageView alloc] initWithImage:image];
            [self.scrollView addSubview:iconView];
            // 设置frame
            CGFloat x = i * size.width;
            iconView.frame = CGRectMake(x, 0, size.width, size.height);
        }
    复制代码

    这里要注意的就是5个UIimageView的尺寸,宽和高都一样,唯独不一样的就是他的X,需要1张1张图片往后排

    第三步:设置scrollView的滚动范围以及设置分页,代码如下

    复制代码
        // 设置滚动范围
        self.scrollView.contentSize = CGSizeMake(count * size.width, 0);
        // 滚动条不显示
        self.scrollView.showsHorizontalScrollIndicator = NO;
        self.scrollView.showsVerticalScrollIndicator = NO;
        // 设置分页
        self.scrollView.pagingEnabled = YES;
        // 设置pagecontrol
        self.pageControl.numberOfPages = count;
    复制代码

    上面代码中滚动条不显示那两行代码是因为UIScrollView默认是有横竖滚动条的,那两行代码分别让水平的和竖直的的滚动条不显示,一定要让scrollView设置分页否则那个分页器不会跟着走,最后设置pageControl的页数

    第四步:设置scorllView的代理,代理大家都应该熟悉了把,首先要在@interface ViewController ()后面遵循代理 代码如下
    @interface ViewController () <UIScrollViewDelegate>
    然后在ViewDidLod中设置谁遵循这个代理 那当然是ViewController了 代码如下

        // 设置代理
        self.scrollView.delegate = self;

    好了下面开始实现UIScrollView的代理方法了
    我们需要用的代理的方法有3个分别是

    1. - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    2. - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    3. - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate

    第一个是scrollView滚动时调用的方法,第二个是开始拖拽时调用的方法, 第三个是结束拖拽时调用的方法

    首先我们先想scrollView滚动时是不是拖拽到一半以上松手就能到下一张图片,答案肯定是的。那么就来写这个方法,代码如下

    复制代码
    // 正在滚动时
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        int page = (scrollView.contentOffset.x + scrollView.frame.size.width / 2) / scrollView.frame.size.width;
        self.pageControl.currentPage = page;
    }
    复制代码

    这里计算page页数用到了我们非常熟悉的把一个数 / 多少得到的数  比如112 / 10 等于多少 很明显是 11 这样就能很好通过尺寸把该显示的页面算出来,对了忘了说contentOffset是什么意思了,这个就可以理解为是拖拽的距离

    第五步:现在要实现定时器功能了,让其自动翻页,首先要在@interface ViewController () @end中定义一个定时器timer 代码如下

    @property (nonatomic, strong) NSTimer *timer; 

    有人会问为什么要定义这个,因为后面不止一方法需要用到这个timer

    定义一个定时器方法,代码如下

    复制代码
    - (void)addTimer
    {
        NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(nextImage) userInfo:nil repeats:YES];
        self.timer = timer;
        // 消息循环
        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
        [runLoop addTimer:timer forMode:NSRunLoopCommonModes];
    }
    复制代码

    这是一个定时器的方法,里面创建了定时器,并加入了消息循环中,这里面要设置定时器2s之后应该执行哪个方法,很显然要让它2s之后进行翻页啊,那么我们就来写下这个方法nextImage,代码如下

    复制代码
    - (void)nextImage
    {
        // 当前页码
        NSInteger page = self.pageControl.currentPage;
        if (page == self.pageControl.numberOfPages - 1) {
            page = 0;
        } else {
            page++;
        }
        
        CGFloat offsetX = page * self.scrollView.frame.size.width;
        [UIView animateWithDuration:1.0 animations:^{
            self.scrollView.contentOffset = CGPointMake(offsetX, 0);
        }];
        
    }
    复制代码

    这个方法中首先先定义一个page来保存当前的page,然后进行判断如果是最后一张要将页面换成0(这个并不完美会直接从最后一张往回到第一张,但我学习视频的那个老师没有给出解决方法)其他的进行page加1 设置完page数那么我们需要让其自动滚动啊,那我们就来设置scrollView的offset,定义offsetX 等于page数乘以scrollView的宽度,这样正好能移动到下一个视图,同时给移动加一个动画

    之后在ViewDidLod中调用此方法,代码如下

    [self addTimer];

    第六步:下面来到UIScrollView的代理方法中,其中还有两个代理方法我们没有实现,就是开始拖拽和结束拖拽的方法,代码如下

    复制代码
    // 开始拖拽的时候调用
    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
        // 停止定时器
        [self.timer invalidate];
    }
    // 结束拖拽的时候调用
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
    {
        [self addTimer];
    }
    复制代码

    这里的开始拖拽是要把定时器停止,不然你拖拽不动也会翻页,所有要把定时器停止,把定时器停止了,那我们要向让其在动起来,那么就要让其在开启,要在结束拖拽时开始定时器。

    如果你到这一步了,那么恭喜你的图片轮播器就做好了!

    完整代码如下

    复制代码
    #import "ViewController.h"
    
    @interface ViewController () <UIScrollViewDelegate>
    @property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
    @property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
    
    @property (nonatomic, strong) NSTimer *timer;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // 广告图片总数
        int count = 5;
        CGSize size = self.scrollView.frame.size;
        for (int i = 0; i < count; i++) {
            NSString *imageName = [NSString stringWithFormat:@"img_%02d", i + 1];
            UIImage *image = [UIImage imageNamed:imageName];
            UIImageView *iconView = [[UIImageView alloc] initWithImage:image];
            [self.scrollView addSubview:iconView];
            // 设置frame
            CGFloat x = i * size.width;
            iconView.frame = CGRectMake(x, 0, size.width, size.height);
        }
        
        // 设置滚动范围
        self.scrollView.contentSize = CGSizeMake(count * size.width, 0);
        // 滚动条不显示
        self.scrollView.showsHorizontalScrollIndicator = NO;
        self.scrollView.showsVerticalScrollIndicator = NO;
        // 设置分页
        self.scrollView.pagingEnabled = YES;
        // 设置pagecontrol
        self.pageControl.numberOfPages = count;
    
        // 设置代理
        self.scrollView.delegate = self;
    
        [self addTimer];
    }
    
    - (void)addTimer
    {
        NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(nextImage) userInfo:nil repeats:YES];
        self.timer = timer;
        // 消息循环
        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
        [runLoop addTimer:timer forMode:NSRunLoopCommonModes];
    }
    
    - (void)nextImage
    {
        // 当前页码
        NSInteger page = self.pageControl.currentPage;
        if (page == self.pageControl.numberOfPages - 1) {
            page = 0;
        } else {
            page++;
        }
        
        CGFloat offsetX = page * self.scrollView.frame.size.width;
        [UIView animateWithDuration:1.0 animations:^{
            self.scrollView.contentOffset = CGPointMake(offsetX, 0);
        }];
        
    }
    
    #pragma mark - scrollView代理方法
    // 正在滚动时
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        int page = (scrollView.contentOffset.x + scrollView.frame.size.width / 2) / scrollView.frame.size.width;
        self.pageControl.currentPage = page;
    }
    // 开始拖拽的时候调用
    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
        // 停止定时器
        [self.timer invalidate];
    }
    // 结束拖拽的时候调用
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
    {
        [self addTimer];
    }
    
    @end
    复制代码

     

  • 相关阅读:
    第三方包源码maven 下载
    Redis实现主从复制(转)
    Linq的优缺点
    async & await (转载)
    [转]抽象类与接口的区别及应用
    转载:C#中的泛型
    MVC导出数据到EXCEL新方法:将视图或分部视图转换为HTML后再直接返回FileResult
    C#中委托
    创建新的虚拟机
    GitHub上整理的一些工具[转载]
  • 原文地址:https://www.cnblogs.com/yxt9322yxt/p/4755883.html
Copyright © 2011-2022 走看看