【Objective-C】UIScrollView的循环播放及缩
2016-04-11 本文已影响765人
酷酷的小虎子
今天小主给大家分享一个循环播放及缩放功能。
首先,UIScrollView作为滚动视图的基类,学好UIScrollView也成为学好UITableView和UICollectionView等滚动视图的前提。
UIScrollView主要使用在滚动头条(轮播图),相册等常见的功能里。
首先看一下轮播效果图如下:
循环播放效果图
再看一下放大缩小效果图如下:
放大缩小效果图
//宏定义屏幕的宽和高
#define ScreenWight [UIScreen mainScreen].bounds.size.width
#define ScreenHeight [UIScreen mainScreen].bounds.size.height
@interface ViewController ()<UIScrollViewDelegate>//签滚动视图协议,为了实现协议方法
/** 滚动视图属性 */
@property(nonatomic, retain)UIScrollView *scrollView;
/** 分页控件属性 */
@property(nonatomic, retain)UIPageControl *pageControl;
/** 标记属性 */
@property(nonatomic, assign)BOOL flag;
@end
- (void)loadView
{
[super loadView];
self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];
//设置容量
self.scrollView.contentSize = CGSizeMake(8 * ScreenWight, ScreenHeight);
//添加滚动视图
[self.view addSubview:_scrollView];
//设置整页翻动
self.scrollView.pagingEnabled = YES;
//设置偏移量
self.scrollView.contentOffset = CGPointMake(ScreenWight, 0);
//设置代理人
self.scrollView.delegate = self;
for (NSInteger i = 1; i < 7; i++) {
//创建小的滚动视图
/**
为什么要创建小的滚动视图?
因为在进行缩放之后发现,之前的滚动效果发生了变化,
原因在于当我们进行缩放的时候,协议方法不但会改变视图的尺存,同样也可以改变scrollView的contenSize属性。
解决方法:大的scrollView上先铺设小的scrollView ,然后把imageView放到小的scrollView上
大的scrollView主要承担水平或垂直滚动,小的scrollView承担缩放的功能,
并且每个都设置好缩放比例,这样再进行缩放,只会改变小scrollView的contenSize, 不会改变scrollView的contentSize。
*/
UIScrollView *tempScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(ScreenWight * i, 0, ScreenWight, ScreenHeight)];
tempScrollView.contentSize = CGSizeMake(ScreenWight, ScreenHeight);
//隐藏底部和右侧滚动条
tempScrollView.showsVerticalScrollIndicator = NO;
tempScrollView.showsHorizontalScrollIndicator = NO;
//设置缩放的比例
tempScrollView.minimumZoomScale = 0.5f;
tempScrollView.maximumZoomScale = 3.0f;
//小滚动视图设置代理,为的是实现缩放的代理方法
tempScrollView.delegate = self;
[self.scrollView addSubview:tempScrollView];
//循环往小滚动视图添加图片
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, ScreenWight, ScreenHeight)];
NSString *imageName = [NSString stringWithFormat:@"%ld.JPG", i];
imageView.image = [UIImage imageNamed:imageName];
[tempScrollView addSubview:imageView];
[imageView release];
//设置轻拍手势
//首先打开imageView的用户交互,默认是关闭
imageView.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapImageView:)];
tapGesture.numberOfTapsRequired = 2;
[imageView addGestureRecognizer:tapGesture];
}
//在最前面加上最后一张图,障眼法,给人一种感觉从第一页循环回最后一页
//在此刻改变滚动视图的偏移量
UIScrollView *frontScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, ScreenWight, ScreenHeight)];
frontScroll.contentSize = CGSizeMake(ScreenWight, ScreenHeight);
[self.scrollView addSubview:frontScroll];
UIImageView *frontImageView = [[UIImageView alloc] initWithFrame:self.view.frame];
frontImageView.image = [UIImage imageNamed:@"6.JPG"];
[frontScroll addSubview:frontImageView];
//在最后面加上第一张图
UIScrollView *lastScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(7 * ScreenWight, 0, ScreenWight, ScreenHeight)];
lastScroll.contentSize = CGSizeMake(ScreenWight, ScreenHeight);
[self.scrollView addSubview:lastScroll];
UIImageView *lastImageView = [[UIImageView alloc] initWithFrame:self.view.frame];
lastImageView.image = [UIImage imageNamed:@"1.JPG"];
[lastScroll addSubview:lastImageView];
//分页控件
self.pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(100, 600, 175, 30)];
self.pageControl.numberOfPages = 6;
[self.view addSubview:_pageControl];
[_pageControl release];
[self.pageControl addTarget:self action:@selector(didClickedPageControl:) forControlEvents:UIControlEventValueChanged];
}
#pragma mark 自定义方法,获取放大后显示的矩形区域
- (CGRect)zoomRectByScale:(CGFloat)scale Center:(CGPoint)center
{
CGRect zoomRect;
//求出新的长和宽
zoomRect.size.width = ScreenWight / scale;
zoomRect.size.height = ScreenHeight / scale;
//找到新的原点
zoomRect.origin.x = center.x * (1 - 1/scale);
zoomRect.origin.y = center.y * (1 - 1/scale);
return zoomRect;
}
如果大家获取放大后矩形区域的自定义方法不理解可以看一下这篇简书,看完大家一定可以理解
iOS中使图片放缩前后轻拍点的位置不变
#pragma mark 轻拍方法
- (void)didTapImageView:(UITapGestureRecognizer *)tap
{
//这个是要获取当前点击的小滚动视图,而小滚动视图我们没有设置属性,无法在这儿获取
//当前点击视图的父视图,其实就是当前点击的小滚动视图,就通过这种方法获取滚动视图对象�
UIScrollView *scroll = (UIScrollView *)tap.view.superview;
if (_flag == NO) {
CGRect newRect = [self zoomRectByScale:3.0 Center:[tap locationInView:tap.view]];
//zoomToRect方法是UIScrollVie对象的方法,将图片相对放大
[scroll zoomToRect:newRect animated:YES];
_flag = YES;
}else {
[scroll setZoomScale:1 animated:YES];
_flag = NO;
}
}
#pragma mark 缩放的代理方法
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
//这个代理方法就是要返回一个view跟着scrollView缩放,
//这个时候就会把scrollView的contentSize设置为imageView的大小
//同时只能有一个view跟着scrollView缩放
return scrollView.subviews.firstObject;
}
#pragma mark 滚动结束的代理方法
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
//滚动停止后,将每个小滚动视图比例还原
for (UIScrollView *tempScroll in scrollView.subviews) {
if ([tempScroll isKindOfClass:[UIScrollView class]]) {
tempScroll.zoomScale = 1.0;
}
}
//判断偏移量,并改变当前偏移量,实现循环播放功能
if (scrollView.contentOffset.x == 0) {
self.scrollView.contentOffset = CGPointMake(6 * ScreenWight, 0);
}
if (scrollView.contentOffset.x == ScreenWight * 7) {
self.scrollView.contentOffset = CGPointMake(ScreenWight, 0);
}
//获取当前的页数,即滚动视图控制分页控件
NSInteger pageNum = (long)(scrollView.contentOffset.x - ScreenWight) / ScreenWight;
//改变当前分页控件的显示页数
self.pageControl.currentPage = pageNum;
}
#pragma mark 分页控件的触发方法
- (void)didClickedPageControl:(UIPageControl *)pageControl
{
//根据当前点的下标,修改滚动视图应该显示的图片,即分页控件控制滚动视图
CGPoint newPoint = CGPointMake((pageControl.currentPage + 1) * ScreenWight , 0);
//修改滚动视图偏移量
[self.scrollView setContentOffset:newPoint animated:YES];
}
以上就是实现UIScrollView的循环播放及缩放功能的整个过程,整个功能实现的过程也将UIScrollView常用属性都用了一遍,很多解释都直接注释在了代码中,如果想要学会这个功能,小主建议大家好好捋一遍逻辑实现,再重头捋一遍代码。大家有什么不理解的可以再问我。