IOS开发学习笔记036-UIScrollView-循环自动滚动

时间:2023-11-10 13:40:56

实现scrollView的自动循环滚动,需要实现几个方法。

其中scrollView中始终保存三张图片,其他的图片在滚动到时再进行加载。

循环的实现主要是在setUpdate 中,如果索引为0是第一个,索引为2是最后一个,这是对索引值进行改变。第一个后接着显示最后一个,最后一个后接着显示第一个。依次循环。

分析过程为:

IOS开发学习笔记036-UIScrollView-循环自动滚动

1、首先是set方法 setImageNames

 #pragma mark - setter方法重写
- (void)setImageNames:(NSArray *)imageNames
{
_imageNames = imageNames; // 删除之前的所有图片,如果没有这句话图片会重复添加
[self.scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; //NSLog(@"setImageNames----%@",imageNames);
// 添加图片
for (int i = ; i < kCount; i ++ )
{
UIImageView *imageView = [[UIImageView alloc] init];
[self.scrollView addSubview:imageView];
} // 设置pageControl的页数
self.pageControl.numberOfPages = _imageNames.count; // 更新内容
[self setUpdate];
}

2、然后实现更新内容的方法 setUpdate

 // 更新内容
- (void)setUpdate
{
NSLog(@"setUpdate---%ld",self.scrollView.subviews.count);
//NSInteger index = 0;
// 更新数据,图片内容
for (int i = ; i < self.scrollView.subviews.count; i ++)
{
UIImageView *ima = self.scrollView.subviews[i]; // 获取图片
NSInteger index = self.pageControl.currentPage; // 当前索引 if (i == ) { // 最左边图片,第一个,共三个
index --;
}
else if(i == ) // 最右边图片,第二个,共三个
{
index ++;
} if (index < ) { // 如果是最左边,显示最后一张图片,总得图片个数,_imageNames.Count;
index = self.pageControl.numberOfPages - ; //
}
else if(index >= self.pageControl.numberOfPages) // 如果是最右边,就显示第一张图片
{
index = ;
} ima.tag = index; // 设置tag为计算索引值
ima.image = [UIImage imageNamed:self.imageNames[index]]; // 重新设置图片 }
// NSLog(@"setUpdate--index--%ld",index);
// 设置scrollView偏移量
self.scrollView.contentOffset = CGPointMake(self.scrollView.frame.size.width, );
}

3、然后设置控件frame

 #pragma mark - 计算控件的frame
// layout ,计算控件的frame
- (void)layoutSubviews
{
[super layoutSubviews]; // 设置scrollView的frame
self.scrollView.frame = self.bounds;
//view的高度和宽度
CGFloat viewW = self.scrollView.frame.size.width;
CGFloat viewH = self.scrollView.frame.size.height; // view 的位置
self.scrollView.contentSize = CGSizeMake(viewW * kCount, ); // 计算图片的 frame
for(int i = ; i < kCount ; i ++)
{
UIImageView *imageView = self.scrollView.subviews[i];
imageView.frame = CGRectMake(i * viewW, , viewW, viewH);
} // pageControl 的frame
self.pageControl.frame = CGRectMake(viewW - , viewH - , , );
}

4、实现代理方法 scrollViewDidScroll

 #pragma mark - 代理方法
// 代理方法
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// NSLog(@"scrollViewDidScroll----%ld",self.scrollView.subviews.count); // 计算最中间的那个imageView位置
NSLog(@"scrollViewDidScroll----%ld",self.scrollView.subviews.count);
NSInteger page = ;
CGFloat minDistance = MAXFLOAT; for (int i = ; i < self.scrollView.subviews.count; i++)
{
UIImageView *ima = self.scrollView.subviews[i]; // 获取图片
CGFloat distance = ;
// 计算当前image视图中图片相对与整个scrollView的绝对距离
distance = ABS(ima.frame.origin.x - self.scrollView.contentOffset.x);
//
if (distance < minDistance)
{
minDistance = distance; // 最小值
page = ima.tag;
}
}
NSLog(@"scrollViewDidScroll--pageIndex-%ld",page);
self.pageControl.currentPage = page; // 显示最新的页码
}

5、设置滚动下一页的方法

 - (void)nextPage
{
// 设置新的偏移量,直接对宽度乘以2,不用担心越界
[self.scrollView setContentOffset:CGPointMake( * self.scrollView.frame.size.width, ) animated:YES];
}

主要代码如下:

 //
// SLQPageScroll.m
// UIScrollView-分页练习
//
// Created by Christian on 15/5/31.
// Copyright (c) 2015年 slq. All rights reserved.
//
// 滚动图片个数
#define kCount 3 #import "SLQPageScroll.h" @interface SLQPageScroll () <UIScrollViewDelegate> // 遵守协议 @property (strong, nonatomic) IBOutlet UIScrollView *scrollView; // scrollView
@property (weak, nonatomic) IBOutlet UIPageControl *pageControl; // pageControl
@property (strong, nonatomic ) NSTimer *timer; @end @implementation SLQPageScroll + (instancetype)pageScroll
{
// NSStringFromClass 将类名转换成字符串,xib文件名和类名一样
return [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil] lastObject];
} #pragma mark - 计算控件的frame
// layout ,计算控件的frame
- (void)layoutSubviews
{
[super layoutSubviews]; // 设置scrollView的frame
self.scrollView.frame = self.bounds;
//view的高度和宽度
CGFloat viewW = self.scrollView.frame.size.width;
CGFloat viewH = self.scrollView.frame.size.height; // view 的位置
self.scrollView.contentSize = CGSizeMake(viewW * kCount, ); // 计算图片的 frame
for(int i = ; i < kCount ; i ++)
{
UIImageView *imageView = self.scrollView.subviews[i];
imageView.frame = CGRectMake(i * viewW, , viewW, viewH);
} // pageControl 的frame
self.pageControl.frame = CGRectMake(viewW - , viewH - , , );
} #pragma mark - setter方法重写
- (void)setImageNames:(NSArray *)imageNames
{
_imageNames = imageNames; // 删除之前的所有图片,如果没有这句话图片会重复添加
[self.scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; //NSLog(@"setImageNames----%@",imageNames);
// 添加图片
for (int i = ; i < kCount; i ++ )
{
UIImageView *imageView = [[UIImageView alloc] init];
[self.scrollView addSubview:imageView];
} // 设置pageControl的页数
self.pageControl.numberOfPages = _imageNames.count; // 更新内容
[self setUpdate];
} #pragma mark - 代理方法
// 代理方法
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// NSLog(@"scrollViewDidScroll----%ld",self.scrollView.subviews.count); // 计算最中间的那个imageView位置
NSLog(@"scrollViewDidScroll----%ld",self.scrollView.subviews.count);
NSInteger page = ;
CGFloat minDistance = MAXFLOAT; for (int i = ; i < self.scrollView.subviews.count; i++)
{
UIImageView *ima = self.scrollView.subviews[i]; // 获取图片
CGFloat distance = ;
// 计算当前image视图中图片相对与整个scrollView的绝对距离
distance = ABS(ima.frame.origin.x - self.scrollView.contentOffset.x);
//
if (distance < minDistance)
{
minDistance = distance; // 最小值
page = ima.tag;
}
}
// NSLog(@"scrollViewDidScroll--pageIndex-%ld",page);
self.pageControl.currentPage = page; // 显示最新的页码
} // 更新内容
- (void)setUpdate
{
//NSLog(@"setUpdate---%ld",self.scrollView.subviews.count);
// 更新数据,图片内容
for (int i = ; i < self.scrollView.subviews.count; i ++)
{
UIImageView *ima = self.scrollView.subviews[i]; // 获取图片
NSInteger index = self.pageControl.currentPage; // 当前索引 if (i == ) { // 最左边图片,第一个,共三个
index --;
}
else if(i == ) // 最右边图片,第二个,共三个
{
index ++;
} if (index < ) { // 如果是最左边,显示最后一张图片,总得图片个数,_imageNames.Count;
index = self.pageControl.numberOfPages - ; //
}
else if(index >= self.pageControl.numberOfPages) // 如果是最右边,就显示第一张图片
{
index = ;
} ima.tag = index; // 设置tag为计算索引值
ima.image = [UIImage imageNamed:self.imageNames[index]]; // 重新设置图片 }
// NSLog(@"setUpdate--index--%ld",index)
// 设置scrollView偏移量
self.scrollView.contentOffset = CGPointMake(self.scrollView.frame.size.width, );
} // 停止拖动
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
[self setUpdate];
} // 拖动暂停状态
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self setUpdate];
} - (void)setCurrentColor:(UIColor *)currentColor
{
_currentColor = currentColor;
self.pageControl.currentPageIndicatorTintColor = _currentColor;
}
- (void)setOtherColor:(UIColor *)otherColor
{
_otherColor = otherColor;
self.pageControl.pageIndicatorTintColor = _otherColor;
} // xib 初始化完毕会调用这个方法
- (void)awakeFromNib
{
self.pageControl.currentPage = ;
self.scrollView.bounces = NO; // 开启定时器
[self startTimer]; } - (void)nextPage
{
// 设置新的偏移量
[self.scrollView setContentOffset:CGPointMake( * self.scrollView.frame.size.width, ) animated:YES];
} #pragma mark - 定时器
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
[self startTimer];
} - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
[self stopTimer];
} - (void)startTimer
{
// 创建定时器
self.timer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(nextPage) userInfo:nil repeats:YES];
// 设置计时器线程的优先级和其他线程一样
[[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
} - (void)stopTimer
{
[self.timer invalidate]; // 停止计时器
self.timer = nil; //清空指针
}
@end