转载自 http://blog.csdn.net/cubepeng/article/details/7901229
做过好几个app中都要实现图片的相册浏览的功能,有开源的库可以用,但是我都觉得比较重,自己写另一个比较轻的。其实相册的功能思路是很清楚的,实现滑动中的内存重用和内存的cache。好现在我逐步讲解,如何来构建简单的相册。
1.首先我们来创建一个UIScrollView。
- _scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0,0, 320, 480)];
- _scrollView.delegate=self;
- _scrollView.scrollEnabled=YES;
- _scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
- _scrollView.pagingEnabled=YES;
- _scrollView.showsVerticalScrollIndicator=NO;
- _scrollView.showsHorizontalScrollIndicator=NO;
- _scrollView.backgroundColor = self.view.backgroundColor;
- [_scrollView setContentSize:CGSizeMake(320*[_itemSet count], 316)];
(大家注意到有一个_itemSet,这是一个包含了图片数据的集合,可以是网络上的图片的地址,也可以是包含了封装图片地址的对象的实例,总值不能是UIImage的实例,不然就是失去了封装的意义了。)
- [self.view addSubview:_scrollView];
- [self configScrowViewWithIndex:self.itemIndex withForward:NO withOrigin:YES];
- pageIndex = itemIndex;
将scrollview添加为当前试图的子试图之后,我们马上 调用
[selfconfigScrowViewWithIndex:self.itemIndexwithForward:NOwithOrigin:YES];
这是实现整个业务逻辑的关键方法,就是说去配置当前的索引应该执行的操作,第一个参数是当前的索引,比如说0就代表我是从_itemSet的第一个元素 映射的图片开始显示;第二个参数是判断当前是向前还是向后翻动相册;第三个参数是表示当前是不是第一次显示相册。
将itemSet的索引赋给页数,这两个成员一直是相等的,这样只是为了区别的看待这两个序数。
2.实现我们的关键方法:
- (void)configScrowViewWithIndex:(int)index withForward:(BOOL)isForward withOrigin:(BOOL)isOrigin
- - (void)configScrowViewWithIndex:(int)index withForward:(BOOL)isForward withOrigin:(BOOL)isOrigin
- {
- if ([_itemSet count]<1) {
- return;
- }
- //当偏移量是0的话加载当前的索引的视图和前后的视图(如果存在的话)
- if (isOrigin) {
- WPCellImageView *currentView = [self configItemWithIndex:index];
- if (currentView) {
- currentView.tag = CURRENTVIEWTAG;
- [_scrollView addSubview:currentView];
- }
- WPCellImageView *nextView = [self configItemWithIndex:index+1];
- if (nextView) {
- nextView.tag = NEXTVIEWTAG;
- [_scrollView addSubview:nextView];
- }
- WPCellImageView *lastView = [self configItemWithIndex:index-1];
- if(lastView)
- {
- lastView.tag = LASTVIEWTAG;
- [_scrollView addSubview:lastView];
- }
- }
- else {
- //如果向前滑动的话,加载下一张试图的后一张试图,同时移除上一张试图的前一张试图
- if (isForward) {
- if ([_scrollView viewWithTag:LASTVIEWTAG])
- {
- WPCellImageView *view = (WPCellImageView*)[_scrollView viewWithTag:
- LASTVIEWTAG];
- [view cancelImageLoad];
- [[_scrollView viewWithTag:LASTVIEWTAG]removeFromSuperview];//移出前一个视图
- }
- if ([_scrollView viewWithTag:NEXTVIEWTAG])
- {
- //如果下个视图存在
- UIView *currentView = [_scrollView viewWithTag:CURRENTVIEWTAG];
- currentView.tag = LASTVIEWTAG;
- UIView *view = [_scrollView viewWithTag:NEXTVIEWTAG];
- view.tag = CURRENTVIEWTAG;
- WPCellImageView *nextView = [self configItemWithIndex:index+1];
- if (nextView) {
- nextView.tag = NEXTVIEWTAG;
- [_scrollView addSubview:nextView];
- }
- }
- }
- //如果向后滑动的话,加载上一张试图的前一张试图,同时移除下一张试图的后一张试图
- else {
- if ([_scrollView viewWithTag:NEXTVIEWTAG]) {
- [[_scrollView viewWithTag:NEXTVIEWTAG]removeFromSuperview];//移出后一个视图
- WPCellImageView *view = (WPCellImageView*)[_scrollView viewWithTag:
- NEXTVIEWTAG];
- [view cancelImageLoad];
- }
- if ([_scrollView viewWithTag:LASTVIEWTAG]) { //如果上个视图存在
- UIView *currentView = [_scrollView viewWithTag:CURRENTVIEWTAG];
- currentView.tag = NEXTVIEWTAG;
- UIView *view = [_scrollView viewWithTag:LASTVIEWTAG];
- view.tag = CURRENTVIEWTAG;
- WPCellImageView *lastView = [self configItemWithIndex:index-1];
- if (lastView) {
- lastView.tag = LASTVIEWTAG;
- [_scrollView addSubview:lastView];
- }
- }
- }
- }
- }
这里面还调用了一个方法:
- (WPCellImageView*)configItemWithIndex:(int)index
这个方法是index所代表的索引的试图,WPCellImageVIew是我定制的一个试图,能够根据图片URL下载图片,有一些开源库可以用,这里就不细说了。下面贴上这个方法的实现。
- if (index<0 || index>[_itemSet count]-1) {
- DLog(@"%d",[_itemSet count]);
- return nil;
- }
- WPWaterflowItem *dic = [_itemSet objectAtIndex:index];
- WPCellImageView *firstView = [[WPCellImageView alloc]initWithFrame:CGRectMake(_scrollView.frame.size.width*index, 0, _scrollView.frame.size.width, _scrollView.frame.size.height) ];
- [firstView setURL:dic.picURL];
- return [firstView autorelease];
3.通过UIScrollview的代理方法实现图片的显示和内存管理
- #pragma mark UIScrollView Delegate
- - (void)scrollViewDidScroll:(UIScrollView *)scrollView
- {
- CGFloat pageWidth = scrollView.frame.size.width;
- int beforeIndex = pageIndex;
- pageIndex = floor((scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
- if (pageIndex>beforeIndex) {
- itemIndex ++;
- [self configScrowViewWithIndex:itemIndex withForward:YES withOrigin:NO];
- }
- else if(pageIndex<beforeIndex) {
- itemIndex --;
- [self configScrowViewWithIndex:itemIndex withForward:NO withOrigin:NO];
- }
- }
呵呵,很简单吧,滑动超过半页的时候就去加载图片和管理内存。