iOS笔记:使用UIPageControl+UIScrollView实现图片自动播放及手动切换

首先新建一个类UIPageViewDatasource继承自UIView,并定义UIPageViewDelegateUIPageViewDatasource两个协议,scrollViewpageControlanimationDurationdelegatedatasource等属性,以及reloadData方法。

UIPageViewDelegate协议中定义可选方法,实现点击某个page时触发的操作

- (void)pageView:(DLPageView *)pageView didSelectPage:(UIView *)view atIndexPath:(NSIndexPath *)indexPath;

UIPageViewDatasource协议中定义两个方法,分别用于设置pageControl的总页数以及每一页的view

- (NSInteger)numberOfPagesInPageView:(DLPageView *)pageView;
- (UIView *)pageView:(DLPageView *)pageView viewForPageAtIndexPath:(NSIndexPath *)indexPath;

在.m文件中,实现init方法,为animationDuration赋一个默认的初始值,同时调用initPageView方法构造UI。

手动实现animationDurationsetter方法,首先将当前定时器(timer)置空,防止重复定义引起多个定时器同时工作,然后判断animationDuration是否大于0。

- (void)setAnimationDuration:(NSTimeInterval)animationDuration {
    if (self.animationTimer) {
        [self.animationTimer invalidate];
        self.animationTimer = nil;
    }
    if (animationDuration > 0.0) {
        _animationDuration = animationDuration;
        [self animationTimerStart:self.animationTimer];
    }
}

定义animationTimerStart:animationTimerStop:方法实现定时器的添加和移除

- (void)animationTimerStart:(NSTimer *)timer {
    self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:_animationDuration target:self selector:@selector(animationTimerRun:) userInfo:nil repeats:YES];
}

- (void)animationTimerStop:(NSTimer *)timer {
    [self.animationTimer invalidate];
    self.animationTimer = nil;
}

启动定时器

- (void)animationTimerRun:(NSTimer *)timer {
    if (self.totalPages > 1) {
        CGPoint offset = CGPointMake(self.scrollView.contentOffset.x + CGRectGetWidth(self.scrollView.frame), self.scrollView.contentOffset.y);
        [self.scrollView setContentOffset:offset animated:YES];
    }
}

实现loadDatareloadData方法为pageView加载数据,同时为上一页、当前页、下一页添加点击手势操作UITapGestureRecognizer,在响应tap手势的方法中判断是否实现UIPageViewDelegate中的pageView:didSelectPage:atIndexPath:方法。

- (void)singleTapHandle:(UITapGestureRecognizer *)tap {
    if ([self.delegate respondsToSelector:@selector(pageView:didSelectPage:atIndexPath:)]) {
        [self.delegate pageView:self didSelectPage:tap.view atIndexPath:self.indexPathOfCurrentPage];
    }
}

定义getValidPageValue:方法,获取有效页码,处理第一页的上一页和最后一页的下一页。

- (NSInteger)getValidPageValue:(NSInteger)value {
    if (value == -1) {
        value = self.totalPages - 1;
    } else if (value == self.totalPages) {
        value = 0;
    }
    return value;
}

实现UIScrollViewDelegate中的scrollViewDidScroll:方法,获取用户的滑动操作,并判断左滑和右滑以翻到上一页或下一页。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    int x = scrollView.contentOffset.x;
    //左滑翻到下一页
    if(x >= (2 * self.frame.size.width)) {
        self.indexPathOfCurrentPage = [NSIndexPath indexPathForRow:[self getValidPageValue:self.indexPathOfCurrentPage.row + 1] inSection:self.indexPathOfCurrentPage.section];
        [self loadData];
    }
    //右滑翻到上一页
    if(x <= 0) {
        self.indexPathOfCurrentPage = [NSIndexPath indexPathForRow:[self getValidPageValue:self.indexPathOfCurrentPage.row - 1] inSection:self.indexPathOfCurrentPage.section];
        [self loadData];
    }
}

实现UIScrollViewDelegate中的scrollViewWillBeginDragging:方法和scrollViewDidEndDragging:willDecelerate:,当用户开始滑动时停止当前定时器,当用户停止滑动时重新开始定时器,如果跳过此步骤的话,可能存在的一个问题,当用户左右滑动手动翻页后,在定时器的作用下,当前页立刻切换到下一页,影响用户体验。

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    [self animationTimerStop:self.animationTimer];
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    [self animationTimerStart:self.animationTimer];
}

源码地址https://github.com/xiaoyu-lyt/DLPageView,同时感谢CocoaChina@sunpeng大大的分享

你可能感兴趣的:(iOS笔记:使用UIPageControl+UIScrollView实现图片自动播放及手动切换)