做過好幾個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];
}
}
呵呵,很簡單吧,滑動超過半頁的時候就去加載圖片和管理內存。