首先新建一個(gè)類UIPageViewDatasource繼承自UIView蹬挺,并定義UIPageViewDelegate
和UIPageViewDatasource
兩個(gè)協(xié)議探遵,scrollView
躲株、pageControl
筋遭、animationDuration
和delegate
碉熄、datasource
等屬性详囤,以及reloadData
方法财骨。
在UIPageViewDelegate
協(xié)議中定義可選方法,實(shí)現(xiàn)點(diǎn)擊某個(gè)page時(shí)觸發(fā)的操作
- (void)pageView:(DLPageView *)pageView didSelectPage:(UIView *)view atIndexPath:(NSIndexPath *)indexPath;
在UIPageViewDatasource
協(xié)議中定義兩個(gè)方法藏姐,分別用于設(shè)置pageControl
的總頁數(shù)以及每一頁的view
- (NSInteger)numberOfPagesInPageView:(DLPageView *)pageView;
- (UIView *)pageView:(DLPageView *)pageView viewForPageAtIndexPath:(NSIndexPath *)indexPath;
在.m文件中隆箩,實(shí)現(xiàn)init
方法,為animationDuration
賦一個(gè)默認(rèn)的初始值羔杨,同時(shí)調(diào)用initPageView
方法構(gòu)造UI捌臊。
手動(dòng)實(shí)現(xiàn)animationDuration
的setter
方法,首先將當(dāng)前定時(shí)器(timer)置空兜材,防止重復(fù)定義引起多個(gè)定時(shí)器同時(shí)工作理澎,然后判斷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:
方法實(shí)現(xiàn)定時(shí)器的添加和移除
- (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;
}
啟動(dòng)定時(shí)器
- (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];
}
}
實(shí)現(xiàn)loadData
和reloadData
方法為pageView加載數(shù)據(jù)矾端,同時(shí)為上一頁、當(dāng)前頁卵皂、下一頁添加點(diǎn)擊手勢(shì)操作UITapGestureRecognizer
秩铆,在響應(yīng)tap手勢(shì)的方法中判斷是否實(shí)現(xiàn)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;
}
實(shí)現(xiàn)UIScrollViewDelegate
中的scrollViewDidScroll:
方法,獲取用戶的滑動(dòng)操作滚粟,并判斷左滑和右滑以翻到上一頁或下一頁寻仗。
- (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];
}
}
實(shí)現(xiàn)UIScrollViewDelegate
中的scrollViewWillBeginDragging:
方法和scrollViewDidEndDragging:willDecelerate:
,當(dāng)用戶開始滑動(dòng)時(shí)停止當(dāng)前定時(shí)器凡壤,當(dāng)用戶停止滑動(dòng)時(shí)重新開始定時(shí)器署尤,如果跳過此步驟的話,可能存在的一個(gè)問題亚侠,當(dāng)用戶左右滑動(dòng)手動(dòng)翻頁后曹体,在定時(shí)器的作用下,當(dāng)前頁立刻切換到下一頁硝烂,影響用戶體驗(yàn)箕别。
- (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,同時(shí)感謝CocoaChina@sunpeng大大的分享