为了实现仿照类似于图中星球直播抓娃娃的效果,最主要的方面是实现下部分滚动,分析一下需要get的点。
- 无限循环滚动
- 数据可以reload
- 滚动位置精准可计算,这样爪子才能抓到
- 考虑进入后台的情况
根据以上几点 最终选定用CADisplayLink来作为基础,封装一个类似与tableView 的控件,这样做的优点是 定时器保证每个item 的位移的精准性,加入runloop 中 进入后台会直接暂停,缺点是计算量较大。
我封装了一个VGAutoScrollView 的控件,本质上是view 与 scrollView 无关,原理是 通过CADisplayLink 来移动所有的item, 当一个item 消失在屏幕中的时候,要跳到屏幕最前方形成复用。下面简介一下使用方法
- 为了方便使用,而且原理类似,代码形式按照tableView的代理形式来实现,首先是初始化的代码
_autoScrollView = [[VGAutoScrollView alloc]initWithFrame:self.view.frame];
_autoScrollView.delegate = self;
_autoScrollView.dataSource = self;
[self.view addSubview:_autoScrollView];
- VGAutoScrollViewDelegate
VGAutoScrollViewDelegate 主要是对UI 按照 indexPath 来进行不同设置,如果每个section中需要设置的都是相同的,则可以直接设置属性,不需要实现代理,包含如下属性
@property(nonatomic,assign)CGFloat speed;//每次刷新需要前进的pt值 默认0.5
@property(nonatomic,assign)CGFloat itemWidth;
@property(nonatomic,assign)CGFloat itemSpace;
@property(nonatomic,assign)CGFloat direction;
@property(nonatomic,assign)UIEdgeInsets sectionInsets;
@property(nonatomic,assign)CGFloat sectionHeight;
@property(nonatomic,assign)CGFloat sectionHeaderHeight;
- VGAutoScrollViewDataSource
- (UIView *)autoScrollView:(VGAutoScrollView *)autoScrollView viewForItemAtIndexPath:(NSIndexPath *)indexPath{
UILabel * label = (UILabel *) [autoScrollView dequeueReusableItemViewWithIndex:indexPath];
if (label == nil) {
label = [[UILabel alloc]init];
}
return label;
}
在数据源回调中要使用 dequeueReusableItemViewWithIndex 来实现复用机制,直接是使用任何view 都可以,如果是自定义view 要设置内部元素frame 要写在 layoutsubviews 中,因为view在排版过程中会被修改frame
- VGAutoScrllViewItem
一个简单的类,类似于cell,由于只包含两个属性,为了方便使用,合并写在VGAutoScrollView类中。
@property(nonatomic,weak)UIView * itemView;
@property(nonatomic,strong)NSIndexPath * indexPath;
itemView 为引用 在viewForItemAtIndexPath 中 该indexPath 返回的view
下图是控件的效果
demo.gif
图中的item 非常多,因为实现了如下代理
- (NSInteger)numberOfSectionsInAutoScrollView:(VGAutoScrollView *)autoScrollView{
return 12;
}
- (NSInteger)autoScrollView:(VGAutoScrollView *)autoScrollView numbersOfItemsInSection:(NSInteger)section{
return 10000;
}
有12个section ,每个section上有10000个item ,并且每个section 中itemWidth,speed,和移动方向都和其它section 不同。
看一下在这种情况在iphone7上的性能消耗
比较适中的开销,因为section越多计算量越大,这种算是有点极端的情况,正常条件的需求下cpu 会维持在5%左右,因为数组循环遍历的方式不可避免,所以cpu 消耗也变的不可避免。
我之前的直播就是用这个控件来实现抓娃娃和另一个游戏,手感还不错,😄。这里附上控件的代码Demo
网友评论