随着市场上越来越多的APP上线,好多软件对手机的内存要求也是很大,所以我们在开发的时候一定要掌握如何去优化内存,将自己的APP尽可能优化。今天我们就一起看一下九宫格的优化。下面是软件的截图
1、为了达到更好的效果我们不用UITableView,首先我们要通过XIB自定义一个图片和文字如图:
2、自定义主视图JRMainScrollView,通过协议代理来实现功能,做法和UITableView类似,大家可以参考一下UITableView
//数据源协议 @protocol JRMainScrollDataSource <NSObject> //获取总的数量 - (NSInteger) numberOfItems; //获取列的数量 - (NSInteger) numberOfColumsOfRow; //获取item - (UIView *) mainScrollView:(JRMainScrollView *)mainScrollView itemAtIndex:(NSInteger) index; @end
//属性协议 @protocol JRMainScrollDelegate <NSObject> @optional //获取高度 - (CGFloat) heightForItemAtView:(JRMainScrollView *) mainScrollView; //获取宽度 - (CGFloat) widthForItemAtView:(JRMainScrollView *) mainScrollView; //获取间距 - (CGFloat) mainScrollView:(JRMainScrollView *)mainScrollView spaceForItemWithType:(kJRMainScrollItemSpace)type; @end
typedef enum{ kJRMainScrollItemLeftSpace, kJRMainScrollItemTopSpace } kJRMainScrollItemSpace;
3、内部布局实现,计算出当前所有的frame,并且放入数组在此期间,用的的属性参数都需要从代理来获取,代码如下
//加载子视图 - (void)_loadSubViews{ //获取总个数和列数 NSInteger totalItems=[self.jrDataSource numberOfItems]; NSInteger colum=[self.jrDataSource numberOfColumsOfRow]; //获取宽度和高度 CGFloat itemWidth=[self.jrDelegate widthForItemAtView:self]; CGFloat itemHeigt=[self.jrDelegate heightForItemAtView:self]; //获取上下间距 CGFloat leftSpace=[self.jrDelegate mainScrollView:self spaceForItemWithType:kJRMainScrollItemLeftSpace]; CGFloat topSpace=[self.jrDelegate mainScrollView:self spaceForItemWithType:kJRMainScrollItemTopSpace]; CGFloat space=(kWidth-2*leftSpace-colum*itemWidth)/(colum-1)+itemWidth; for (int i=0;i<totalItems;i++) { int clo=i%colum; int row=i/colum; CGRect frame=CGRectMake(leftSpace+clo*space, 20+row*(itemHeigt+topSpace), itemWidth, itemHeigt); [self.array addObject:[NSValue valueWithCGRect:frame]]; } self.contentSize=CGSizeMake(0, CGRectGetMaxY([[self.array lastObject] CGRectValue])); self.showsVerticalScrollIndicator=NO; }
4、判断当前的frame是不是在当前的屏幕可视范围之内,如果要是在的进行视图的渲染,如果不在不予理睬。
-(void)layoutSubviews{ [super layoutSubviews]; //循环便利获取在屏幕中的frame for (int i=0;i<self.array.count;i++) { UIView * tempView=(UIView *)self.current[@(i)]; CGRect rect=[self.array[i] CGRectValue]; if ([self isInScreenWith:rect]) { if(!tempView){//字典里没有的才需要重重新加载 UIView *view=[self.jrDataSource mainScrollView:self itemAtIndex:i]; view.frame=rect; [self.current setObject:view forKey:@(i)]; [self addSubview:view]; } }else if(tempView){//如果存在字典而且不在视线内部的则移除 [self.current removeObjectForKey:@(i)]; [tempView removeFromSuperview]; [self.pool addObject:tempView]; } } //判断是不是在视野内部,其中有两种情况,Y值在屏幕内部,或者MAXY值在屏幕内部 - (BOOL) isInScreenWith:(CGRect) frame{ CGFloat setMiny=self.contentOffset.y; CGFloat setMaxy=self.contentOffset.y+kHeight; BOOL condition1=frame.origin.y>=setMiny&&frame.origin.y<=setMaxy; BOOL condition2=CGRectGetMaxY(frame)>=setMiny&&CGRectGetMaxY(frame)<=setMaxy; if(condition1||condition2){ return YES; } return NO; }
/** 存放frame*/ @property(nonatomic,strong) NSMutableArray * array; /** 存放当前显示的对象*/ @property(nonatomic,strong) NSMutableDictionary * current; /** 存放缓冲池对象*/ @property(nonatomic,strong) NSMutableSet * pool; /** * 获取重复利用的对象 * * @param identy <#identy description#> * * @return <#return value description#> */ - (JRRectView *) dequeueReusedItemWithIdenty:(NSString *) identy{ JRRectView * view=[self.pool anyObject]; if (view!=nil) { [self.pool removeObject:view]; } return view; }
//加载所有数据 - (void) _loadSubviews{ //1 增加滚动视图 JRMainScrollView * mainScroll=[[JRMainScrollView alloc] initWithFrame:self.view.bounds]; mainScroll.jrDataSource=self; mainScroll.jrDelegate=self; [mainScroll reloadViews]; [self.view addSubview:mainScroll]; } #pragma mark - 数据源方法 -(NSInteger)numberOfItems{ return 132; } -(NSInteger) numberOfColumsOfRow{ return 3; } -(UIView *) mainScrollView:(JRMainScrollView *)mainScrollView itemAtIndex:(NSInteger)index{ JRRectView *cell=[mainScrollView dequeueReusedItemWithIdenty:@"test"]; if (cell==nil) { cell=[[[NSBundle mainBundle] loadNibNamed:@"rect" owner:nil options:nil] lastObject]; } cell.titleLabel.text=[NSString stringWithFormat:@"下载"]; NSString * imageName=[NSString stringWithFormat:@"%d",arc4random_uniform(20)+256]; UIImage *image=[UIImage imageNamed:imageName]; cell.image.image=image; return cell; } #pragma mark - 代理方法 //获取高度 - (CGFloat) heightForItemAtView:(JRMainScrollView *) mainScrollView{ return 100; } //获取宽度 - (CGFloat) widthForItemAtView:(JRMainScrollView *) mainScrollView{ return 90; } //获取间距 - (CGFloat) mainScrollView:(JRMainScrollView *)mainScrollView spaceForItemWithType:(kJRMainScrollItemSpace)type{ if (type==kJRMainScrollItemLeftSpace) { return 20; }else if (type==kJRMainScrollItemTopSpace){ return 20; } return 20; }
想要了解更多内容的小伙伴,可以点击 查看源码 ,亲自运行测试。
疑问咨询或技术交流,请加入官方QQ群: (452379712)
作者: 杰瑞教育
出处: http://www.cnblogs.com/jerehedu/
本文版权归 烟台杰瑞教育科技有限公司 和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。