思路:UIScrollView上添加三个图层(UIImage无限滚动则添加三个UIImageView,UIView无限滚动则添加三个UIView),手动定义三个视图下标(下标用于获取数据源),中间视图下标初始定为0,左侧视图下标定为数据源数组最大下标(arr.count -1),右侧视图下标定为1。监测scroll滑动方法:右滑全体下标+1,判断三个下标等于arr.count时将下标赋为0;左滑全体下标-1,判断三个下标等于-1时将该下标赋为数据源数组最大下标(arr.count -1)。手动将scroll.offset设为中间视图的位置(不带滑动特效)。
UIImageView:
UIImageView和UIScrollView定义略
关键方法:
//这个方法会在子视图添加到父视图或者离开父视图时调用
- (void)willMoveToSuperview:(UIView*)newSuperview
{
//解决当父View释放时,当前视图因为被Timer强引用而不能释放的问题
if(!newSuperview)
{
[self.moveTimerinvalidate];
moveTimer=nil;
}
else
{
[selfsetUpTime];
}
}
- (void)setUpTime
{
moveTimer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(animalMoveImage:) userInfo:nil repeats:YES];
isTimeUp = NO;
}
- (void)animalMoveImage:(NSTimer*)time
{
if(self.imageLinkURL.count<=1)
{
return;
}
[self setContentOffset:CGPointMake(SCREEN_WIDTH * 2, 0) animated:YES];
isTimeUp = YES;
[NSTimer scheduledTimerWithTimeInterval:0.3f target:self selector:@selector(scrollViewDidScroll:) userInfo:nil repeats:NO];
}
#pragma mark - 图片停止时,调用该函数使得滚动视图复用
- (void)scrollViewDidScroll:(UIScrollView*)scrollView
{
if (self.contentOffset.x <= 0)
{
centerImageIndex = centerImageIndex - 1;
leftImageIndex = leftImageIndex - 1;
rightImageIndex = rightImageIndex - 1;
if(leftImageIndex== -1) {
leftImageIndex = _imageLinkURL.count-1;
}
if (centerImageIndex == -1)
{
centerImageIndex = _imageLinkURL.count-1;
}
if(rightImageIndex== -1)
{
rightImageIndex = _imageLinkURL.count-1;
}
}
elseif(self.contentOffset.x>=SCREEN_WIDTH*2)
{
centerImageIndex = centerImageIndex + 1;
leftImageIndex = leftImageIndex + 1;
rightImageIndex = rightImageIndex + 1;
if (leftImageIndex == _imageLinkURL.count) {
leftImageIndex=0;
}
if (centerImageIndex == _imageLinkURL.count)
{
centerImageIndex = 0;
}
if (rightImageIndex == _imageLinkURL.count)
{
rightImageIndex=0;
}
}
else
{
return;
}
_leftImageView 根据下标leftImageIndex使用图片显示框架进行图片显示
_centerImageView 根据下标centerImageIndex使用图片显示框架进行图片显示
_rightImageView 根据下标rightImageIndex使用图片显示框架进行图片显示
self.contentOffset = CGPointMake(SCREEN_WIDTH, 0);
//手动控制图片滚动应该取消那个三秒的计时器
if(!isTimeUp) {
[moveTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:3.0]];
}
isTimeUp = NO;
}
- (void)scrollViewWillBeginDragging:(UIScrollView*)scrollView
{
[moveTimer invalidate];
moveTimer = nil;
}
- (void)scrollViewDidEndDragging:(UIScrollView*)scrollView willDecelerate:(BOOL)decelerate
{
[self setUpTime];
}
UIView:
此处以两个视图无限滚动为例,view无限滚动注意点:需要拷贝代码/xib生成的view,拷贝方法:对view的归档、解档。因使用归档/解档拷贝出来的view其子视图圆角等自定义属性会被格式化,此处笔者使用对子视图标记tag来进行二次设置。多次的归档/解档会占用一部分内存,所以只copy一次(数据源大于等于3时,三个view不存在相同的情况,只需要将view加入数组按下标取即可)
关键方法:
- (void)willMoveToSuperview:(UIView*)newSuperview
{
if(!newSuperview)
{
[self.moveTimerinvalidate];
moveTimer=nil;
}
else
{
[selfsetUpTime];
}
}
- (void)setUpTime
{
moveTimer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(animalMoveImage:) userInfo:nil repeats:YES];
isTimeUp = NO;
}
- (void)animalMoveImage:(NSTimer*)time
{
if(self.recommendViewArr.count <= 1)
{
return;
}
[self.scrollRecommend setContentOffset:CGPointMake(SCREEN_NEW_WIDTH * 2, 0) animated:YES];
isTimeUp = YES;
[NSTimer scheduledTimerWithTimeInterval:0.3f target:self selector:@selector(scrollViewDidScroll:) userInfo:nil repeats:NO];
}
- (void)scrollViewDidScroll:(UIScrollView*)scrollView
{
if (self.scrollRecommend.contentOffset.x <= 0)
{
centerViewIndex = centerViewIndex - 1;
leftViewIndex = leftViewIndex - 1;
rightViewIndex = rightViewIndex - 1;
if(leftViewIndex== -1) {
leftViewIndex = self.recommendViewArr.count-1;
}
if(centerViewIndex== -1)
{
centerViewIndex = self.recommendViewArr.count-1;
}
if(rightViewIndex== -1)
{
rightViewIndex = self.recommendViewArr.count-1;
}
}
elseif(self.scrollRecommend.contentOffset.x>= (SCREEN_NEW_WIDTH*2))
{
centerViewIndex = centerViewIndex + 1;
leftViewIndex = leftViewIndex + 1;
rightViewIndex = rightViewIndex + 1;
if (leftViewIndex == self.recommendViewArr.count) {
leftViewIndex=0;
}
if (centerViewIndex == self.recommendViewArr.count)
{
centerViewIndex=0;
}
if (rightViewIndex == self.recommendViewArr.count)
{
rightViewIndex=0;
}
}
else
{
return;
}
//view不能同时拥有两个父视图,所以_viewHotelRecommend和_viewIntegralRecommend在_leftView和_centerView中切换不需要先进行移除操作,重复addSubview中会进行切断旧父视图及绑定新父视图的操作,_viewHotelRecommendCopy和_viewIntegralRecommendCopy在_rightView中重复addSubview道理同上,相当于只是改变了他们在父视图中的图层索引
if (leftViewIndex == 0) {
[_leftView addSubview: _viewHotelRecommend];
}
else{
[_leftView addSubview: _viewIntegralRecommend];
}
if (centerViewIndex == 0) {
[_centerView addSubview: _viewHotelRecommend];
}
else{
[_centerView addSubview: _viewIntegralRecommend];
}
if (rightViewIndex == 0) {
if (!_viewHotelRecommendCopy) {
_viewHotelRecommendCopy = [self copyAView:_viewHotelRecommend];
[_rightView addSubview:_viewHotelRecommendCopy];
}
else{
[_rightView addSubview: _viewHotelRecommendCopy];
}
}
else{
[_rightView addSubview: _viewIntegralRecommendCopy];
}
self.scrollRecommend.contentOffset = CGPointMake(SCREEN_NEW_WIDTH, 0);
if(!isTimeUp) {
[moveTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:3.0]];
}
isTimeUp = NO;
}
//UIView归档/解档实现深拷贝
- (UIView*)copyAView:(UIView*)view
{
NSData *tempArchive = [NSKeyedArchiver archivedDataWithRootObject:view];
UIView *copyView = [NSKeyedUnarchiver unarchiveObjectWithData:tempArchive];
// 在原View中遍历子控件
for(UIView*subViewinview.subviews) {
// 在复制好的View的子控件中遍历,找到与之对应的子控件
for(UIView*copySubViewincopyView.subviews) {
// 这里通过frame确定是否是同一个控件
if ([NSStringFromCGRect(copySubView.frame) isEqualToString:NSStringFromCGRect(subView.frame)]) {
//在xib中已经对需要处理的控件进行tag标记
if(subView.tag==1) {
copySubView.layer.cornerRadius= subView.layer.cornerRadius;
copySubView.layer.masksToBounds=YES;
}
elseif(subView.tag==2){
UIButton*btn = (UIButton*)copySubView;
btn.titleLabel.font=font_Info;
}
elseif(subView.tag==3){
UILabel*lbl = (UILabel*)copySubView;
if(_sIntegralDesc.length>0) {
lbl.text= [NSStringstringWithFormat:@"您有%@积分可用",_sIntegralDesc];
}
}
elseif(subView.tag==4){
UILabel*lbl = (UILabel*)copySubView;
lbl.attributedText=_attHotelDesc;
}
elseif(subView.tag==5){
UILabel*lbl = (UILabel*)copySubView;
lbl.text=_sDestination;
}
break;
}
}
}
returncopyView;
}
- (void)scrollViewWillBeginDragging:(UIScrollView*)scrollView
{
[moveTimer invalidate];
moveTimer = nil;
}
- (void)scrollViewDidEndDragging:(UIScrollView*)scrollView willDecelerate:(BOOL)decelerate
{
[self setUpTime];
}
网友评论