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大大的分享

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容