首页 > 其他 > 详细

UIScrollView实现重用机制(类似多列tableview)

时间:2014-02-23 08:13:27      阅读:564      评论:0      收藏:0      [点我收藏+]

要显示多列数据,在ios6之前可以通过自定义cell来实现,在ios6之后则可以使用UICollectionView。当然也有一种办法就是直接使用UIScrollView。不过UIScrollView并不像UITableview一样有重用机制,如果不经处理就加载多条数据,就会大量占用内存,程序越来越卡。本文的主题就是为UIScrollView实现重用机制,避免内存浪费。


总体的思路比较简单,就是在移动UIScrollView时判断其子视图在不在屏幕上,不在的话就将其移动。


下面直接上代码

@接口WLViewController:的UIViewController <UIScrollViewDelegate> {
    NSInteger的cellViewHeight;
    NSInteger的cellViewWide;
    NSInteger的countOfRow; / /一行的视图数
    NSInteger的queueCount; / /队列里元素的个数   
    
    NSInteger的dataIndex;
    NSInteger的的MaxRow;
    NSInteger的queueIndex;
    NSInteger的preIndex;
    NSInteger的maxindex;
}

- (无效)loadDataOfCell:(UIView的*)细胞;
- (无效)cellHasBeensSlected:(NSInteger的)inedx;
- (无效)writeCell:(UIView的*)细胞;
- (无效)readCell:(UIView的*)细胞withIndex:(NSInteger的)指数;

@结束

@接口WLViewController()

@属性(非原子,强)的NSMutableArray * dataSure; / /用来存放数据,应该是存做文件,为了简单,就先放在数组里
@属性(非原子,强)的NSMutableArray * viewQueue ;/ /队列,通过更改队列里视图的矩形位置来实现滚动
@属性(非原子,强)的UIScrollView * MAINVIEW;

@结束

@实施WLViewController

- (id)的初始化
{
    返回[自initWithCountOfRow:3];
}

- (id)的initWithCountOfRow:(NSInteger的)的计
{
    自= [超级初始化];
    如果(个体经营)
    {
        countOfRow = COUNT;
        cellViewHeight = cellViewWide = 320 / countOfRow;
        queueCount = countOfRow * 800 / cellViewHeight;
        queueCount  -  = countOfRow%2 == 0?0:countOfRow / 2;
        self.dataSure = [[NSMutableArray里的alloc]初始化];
    }
    
    回归自我;
}

- (无效)viewDidLoad中
{
    [超级viewDidLoad中];
    
    self.viewQueue = [[NSMutableArray里的alloc]初始化];
    self.mainView = [[UIScrollView的页头]的initWithFrame:[[UIScreen mainScreen]界限];
    self.mainView.contentSize = CGSizeMake(320,800);
    self.mainView.delegate =自我;
    [self.view addSubview:self.mainView];
    
    
    为(int i = 0; I <queueCount,我+ +)
    {
        的CGRect RECT = CGRectMake(I%countOfRow * cellViewWide,I / countOfRow * cellViewHeight,cellViewWide,cellViewHeight);
        
        
        AlbumView *相册= [[AlbumView页头]的initWithFrame:RECT];
        [self.mainView addSubview:相册];
        [self.viewQueue ADDOBJECT:相册];
        [自我loadDataOfCell:相册];
        dataIndex + +;
    }
    
    的MaxRow = 0;
    queueIndex = 0;
    
}

- (无效)scrollViewDidScroll:(UIScrollView的*)滚动视图
{
    / /防止开始就向上滑
    如果(scrollView.contentOffset.y <= 0)
        返回;
    
    整数P =(int)的scrollView.contentOffset.y / cellViewHeight;
    如果(P> =的MaxRow)
    {
	/ /增加MAINVIEW的长度
        [自我addRows:P / 2 + 1];
        的MaxRow =(self.mainView.contentSize.height  -  cellViewHeight * queueCount / countOfRow)/ cellViewHeight;
    }
    
    如果(P> preIndex)
    {
        [自我下拉:对preIndex];
        
    }
    否则,如果(P <preIndex)
    {
        [自拉:preIndex  -  P];
    }
    
    preIndex = P / /记录前一位置
    如果(dataIndex> = maxindex)maxindex = dataIndex;
}


- (无效)addRows:(NSInteger的)计数
{
    CGSize大小= self.mainView.contentSize;
    size.height + = cellViewHeight *计数;
    self.mainView.contentSize =大小;
}

- (无效)下拉:(NSInteger的)的计
{
    
    为(int i = 0;我<countOfRow *算,我+ +)
    {
        AlbumView *相册= [self.viewQueue objectAtIndex:queueIndex];
        album.frame = CGRectMake(dataIndex%countOfRow * cellViewWide,dataIndex / countOfRow * cellViewHeight,cellViewWide,cellViewHeight);
        //如果没加载数据,就加载数据,如果已经加载过(向上滑动后又滑下),因为已经加载过一次,所以就直接读取
        如果(dataIndex> = maxindex)
            [自我loadDataOfCell:相册];
        其他
            [自我readCell:专辑withIndex:dataIndex];
        
        dataIndex + +;
	/ /变更换队列的索引,指向下一个将要使用的视图
        queueIndex = queueIndex + 1 == queueCount?0:queueIndex + 1;
    }

}

- (无效)的上拉:(NSInteger的)的计
{
    为(int i = 0;我<countOfRow *算,我+ +)
    {
        dataIndex  - ;
        queueIndex = queueIndex == 0?queueCount  -  1:queueIndex  -  1;
        
        AlbumView *相册= [self.viewQueue objectAtIndex:queueIndex];
        album.frame = CGRectMake(dataIndex%countOfRow * cellViewWide,(dataIndex / countOfRow  -  queueCount / countOfRow)* cellViewHeight,cellViewWide,cellViewWide);
        / /向上滑动只需要读取之前加载的视图
        [自我readCell:专辑withIndex:dataIndex  -  queueCount];
    }
}

- (无效)loadDataOfCell:(UIView的*)细胞
{
    
    / /获取数据源,如果从文件获取,则需要判断是否已经存在该文件。这里只是简化的写法。
    [(AlbumView *)细胞dosome];
    ((AlbumView *)细胞)I = dataIndex;
    
    [自我writeCell:电池];
    
}

- (无效)cellHasBeensSlected:(NSInteger的)inedx
{
    / /钩子方法,在MAINVIEW的子视图被点击时调用
    的NSLog(@“------为%d”,inedx);
}

- (无效)writeCell:(UIView的*)细胞
{
    / /写方法,这里只简单的把视图的数据写入数组
    AlbumView *相册= [[AlbumView的alloc]初始化];
    album.backgroundColor = cell.backgroundColor;
    album.i = dataIndex;
    
    [self.dataSure ADDOBJECT:相册];
}

- (无效)readCell:(UIView的*)细胞withIndex:(NSInteger的)指标
{
    / /读方法,同上
    AlbumView *子视图= [self.dataSure objectAtIndex:指数];
    cell.backgroundColor = subview.backgroundColor;
    ((AlbumView *)细胞)I = subview.i;
}

@结束


为了实现钩子方法,这里选择写UIScrollView的分类的方式实现

@执行的UIScrollView(AlbumViewController)
- (无效)touchesEnded:(的NSSet *)触动withEvent:方法(UIEvent *)事件
{
    的UITouch *触摸= [触摸anyObject];
    如果([self.nextResponder.nextResponder isMemberOfClass:[ccViewController类!]])返回;  
 
    AlbumView *相册=(AlbumView *)[个体经营的hitTest:[触摸locationInView:个体经营] withEvent:这个事件];
    [(WLViewController *)self.nextResponder.nextResponder cellHasBeensSlected:album.i]; 
}
@结束

最后是AlbumView类,这个类很随意。

@接口AlbumView:UIView的
@属性(非原子)NSInteger的我;

- (无效)dosome;

@结束
@实施AlbumView

- (无效)dosome
{
    CGFloat R =(CGFloat)(arc4random()%10)/ 10.0;
    CGFloat G =(CGFloat)(arc4random()%10)/ 10.0;
    CGFloat B =(CGFloat)(arc4random()%10)/ 10.0;
    self.backgroundColor = [的UIColor colorWithRed:R绿:G蓝:乙阿尔法:1.0];
}

@结束

一个简单的dome,只是简单的提供一个思路,如果投入使用的话还得进行一些细微的调整,例如,后台加载数据,以及等待数据加载时应该转菊花来增加用户体验等。

上传两张效果图

bubuko.com,布布扣bubuko.com,布布扣


UIScrollView实现重用机制(类似多列tableview)

原文:http://blog.csdn.net/citysupervisor/article/details/19556815

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!