【翻译】制作无限循环的滚动视图
在给iPhone应用做翻页功能的时候,很多时候需要页面无限循环。例如,你有一个小的画册要显示,你想要滑过所有内容,然后从最后一个可以滑到开始那个。用户可以继续滑动只要他们想滑,在一个视图的内容同一个方向可以一直滑动。 这里有两个思路可以做到这个效果:
重复最后的视图
第一个观点对小型的循环是最好的方法。假设你有十张图片要显示。当用户在第一张图片的时候要向左滑动,会让用户看到第十张图片。当用户在第十张图片的时候向右滑动,让用户看到第一张。这里的逻辑需要我们把图片按顺序的添加进来,同时在第一张图片的左边加一张第十张的图片,在第十张的图片右边加一张第一张的图片。
现在,当用户滚动到尽头,我们把UIScrollView的偏移量重新定位一下。通过放置一个同样的图片在最后并且不使用动画把偏移量重新定位,让用户有无缝连接的体验。
- (void)scrollViewDidEndDecelerating:(UIScrollView *)sender {
// The key is repositioning without animation
if (scrollView.contentOffset.x == 0) {
// user is scrolling to the left from image 1 to image 10.
// reposition offset to show image 10 that is on the right in the scroll view
[scrollView scrollRectToVisible:CGRectMake(3520,0,320,480) animated:NO];
} else if (scrollView.contentOffset.x == 3840) {
// user is scrolling to the right from image 10 to image 1.
// reposition offset to show image 1 that is on the left in the scroll view
[scrollView scrollRectToVisible:CGRectMake(320,0,320,480) animated:NO];
}
}
只有三张图片
有时候你想要一个无限循环的页面,但你不想加载很多的内容。例如,在UIScrollView里面你有很多内容要显示。这种情况下,加载大量的数据就不是很理想的方式了。 这时候的逻辑就是保持UIScrollView里就是三个页面。每一个页面都会加载数据,而用户一直看的时候中间的页面加载的内容。当用户滚到到一个新的页面,每一个页面的内容都会被重置,并且偏移量会回到中间的页面,用户正在看的页面。这种做法即使你有大量的数据要滚动,都不会同时加载。同一时间只会加载三张图片。
- (void)viewDidLoad {
[super viewDidLoad];
documentTitles = [[NSMutableArray alloc] init];
// create our array of documents
for (int i = 0; i < 10; i++) {
[documentTitles addObject:[NSString stringWithFormat:@"Document %i",i+1]];
}
// create placeholders for each of our documents
pageOneDoc = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
pageTwoDoc = [[UILabel alloc] initWithFrame:CGRectMake(320, 0, 320, 44)];
pageThreeDoc = [[UILabel alloc] initWithFrame:CGRectMake(640, 0, 320, 44)];
pageOneDoc.textAlignment = UITextAlignmentCenter;
pageTwoDoc.textAlignment = UITextAlignmentCenter;
pageThreeDoc.textAlignment = UITextAlignmentCenter;
// load all three pages into our scroll view
[self loadPageWithId:9 onPage:0];
[self loadPageWithId:0 onPage:1];
[self loadPageWithId:1 onPage:2];
[scrollView addSubview:pageOneDoc];
[scrollView addSubview:pageTwoDoc];
[scrollView addSubview:pageThreeDoc];
// adjust content size for three pages of data and reposition to center page
scrollView.contentSize = CGSizeMake(960, 416);
[scrollView scrollRectToVisible:CGRectMake(320,0,320,416) animated:NO];
}
- (void)loadPageWithId:(int)index onPage:(int)page {
// load data for page
switch (page) {
case 0:
pageOneDoc.text = [documentTitles objectAtIndex:index];
break;
case 1:
pageTwoDoc.text = [documentTitles objectAtIndex:index];
break;
case 2:
pageThreeDoc.text = [documentTitles objectAtIndex:index];
break;
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)sender {
// All data for the documents are stored in an array (documentTitles).
// We keep track of the index that we are scrolling to so that we
// know what data to load for each page.
if(scrollView.contentOffset.x > scrollView.frame.size.width) {
// We are moving forward. Load the current doc data on the first page.
[self loadPageWithId:currIndex onPage:0];
// Add one to the currentIndex or reset to 0 if we have reached the end.
currIndex = (currIndex $gt;= [documentTitles count]-1) ? 0 : currIndex + 1;
[self loadPageWithId:currIndex onPage:1];
// Load content on the last page. This is either from the next item in the array
// or the first if we have reached the end.
nextIndex = (currIndex $gt;= [documentTitles count]-1) ? 0 : currIndex + 1;
[self loadPageWithId:nextIndex onPage:2];
}
if(scrollView.contentOffset.x $lt; scrollView.frame.size.width) {
// We are moving backward. Load the current doc data on the last page.
[self loadPageWithId:currIndex onPage:2];
// Subtract one from the currentIndex or go to the end if we have reached the beginning.
currIndex = (currIndex == 0) ? [documentTitles count]-1 : currIndex - 1;
[self loadPageWithId:currIndex onPage:1];
// Load content on the first page. This is either from the prev item in the array
// or the last if we have reached the beginning.
prevIndex = (currIndex == 0) ? [documentTitles count]-1 : currIndex - 1;
[self loadPageWithId:prevIndex onPage:0];
}
// Reset offset back to middle page
[scrollView scrollRectToVisible:CGRectMake(320,0,320,416) animated:NO];
}
原文:http://iosdevelopertips.com/user-interface/creating-circular-and-infinite-uiscrollviews.html