IOS开发教程第一季之01UI基础day5合并IOS学习004----控件(ScrollView、pageController,NStimer)
1.设置一个ScrollView–ContentSize#import "ViewController.h"@interface ViewController ()@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;@property (weak, nonatomic) IBOutlet UIImageView *imgVie
1.设置一个ScrollView–ContentSize
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UIImageView *imgView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//告诉scrollView,存在与UIScrollView里面的内容的实际大小
//设置UIScrollView的内容大小等于图片框的实际大小
//self.scrollView.contentSize=self.imgView.frame.size;
//也可以设置为图片框图片的大小
self.scrollView.contentSize=self.imgView.image.size;
}
@end
2.设置一个ScrollView–contentOffset
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UIImageView *imgView;
- (IBAction)scroll;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//告诉scrollView,存在与UIScrollView里面的内容的实际大小
//设置UIScrollView的内容大小等于图片框的实际大小
//self.scrollView.contentSize=self.imgView.frame.size;
//也可以设置为图片框图片的大小
self.scrollView.contentSize=self.imgView.image.size;
//隐藏滚动指示器
self.scrollView.showsVerticalScrollIndicator=NO;
self.scrollView.showsHorizontalScrollIndicator=NO;
}
//通过代码来让图片滚动
- (IBAction)scroll {
//不能直接修改结构体的值,一定要中转一下
CGPoint point=self.scrollView.contentOffset;
point.x+=150;
point.y+=150;
//直接修改offset没有动画效果
//self.scrollView.contentOffset=point;
//通过block块来实现动画效果
[UIView animateWithDuration:1 animations:^{
self.scrollView.contentOffset=point;
}];
//直接使用动画方式来设置
[self.scrollView setContentOffset:point animated:YES];
}
@end
3.设置一个ScrollView–contentInset(内容边距)
```objectivec
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UIImageView *imgView;
- (IBAction)scroll;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//告诉scrollView,存在与UIScrollView里面的内容的实际大小
//设置UIScrollView的内容大小等于图片框的实际大小
self.scrollView.contentSize=self.imgView.frame.size;
//也可以设置为图片框图片的大小
//self.scrollView.contentSize=self.imgView.image.size;
//隐藏滚动指示器
self.scrollView.showsVerticalScrollIndicator=NO;
self.scrollView.showsHorizontalScrollIndicator=NO;
//设置内容的内边距
self.scrollView.contentInset=UIEdgeInsetsMake(50, 60, 49, 50);
}
//通过代码来让图片滚动
- (IBAction)scroll {
//不能直接修改结构体的值,一定要中转一下
CGPoint point=self.scrollView.contentOffset;
point.x+=0;
point.y+=0;
//直接修改offset没有动画效果
//self.scrollView.contentOffset=point;
//通过block块来实现动画效果
[UIView animateWithDuration:1 animations:^{
self.scrollView.contentOffset=point;
}];
//直接使用动画方式来设置
[self.scrollView setContentOffset:point animated:YES];
}
@end
4.喜马拉雅案例综合演示UIScrollView
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UIImageView *lastImageView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
CGFloat maxH=CGRectGetMaxY(self.lastImageView.frame);
//设置UIScrollView的contentSize
self.scrollView.contentSize=CGSizeMake(0, maxH);
//设置默认滚动位置
self.scrollView.contentOffset=CGPointMake(0, 120);
//设置距离上边始终有120的内边距
self.scrollView.contentInset=UIEdgeInsetsMake(-120, 0, 0, 0);
}
@end
5.通过代理注册事件
方法步骤
1、设置UIScrollView的delegate属性(也就是为UIScrollView找一个代理对象)
2、让代理对象遵守UIScrollViewDelegate这个协议,当代理对象遵守完毕这个协议以后,就可以保证代理对象中具有了对应的方法
3、当UIScrollView的某个事件被触发的时候,UIScrollView会自动调用代理对象(delegate)的某个方法,并调用这个方法。(这样就实现了事件的机制)
4、我们要做的就是在代理对象的相应方法中编写我们的代码,然后当UIScrollView的某个事件被触发的时候,就会自动的执行这里的代码。
UIScrollView的代理对象是如何工作的
具体的实现步骤
需求:监听UIScrollView的滚动事件
分析:要监听UIScrollView的滚动事件,需要通过代理来实现,无法通过addTarget方法
通过代理监听滚动事件的步骤
1、为UIScrollView找一个代理对象,也就是设置UIScrollView的delegate属性
2、为了保证代理对象中拥有对应方法,所以必须让代理对象(控制器自己)遵守对应控件的代理协议(当前控制器要作为那个控件的代理对象,就那么控制器就要遵守这个控件的代理协议),一般控件的代理协议命名规则都是:控件名Delegate(如:UIScrollViewDelegate,UIAlertViewDelegate)
3、在控制器中实现所需要的方法
#import "ViewController.h"
//让控制器遵守UIScrollView的代理协议
@interface ViewController ()<UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *scrollview;
@property (weak, nonatomic) IBOutlet UIImageView *imgView;
@end
/**
需求:监听UIScrollView的滚动事件
分析:要监听UIScrollView的滚动事件,需要通过代理来实现,无法通过addTarget方法
通过代理监听滚动事件的步骤
1、为UIScrollView找一个代理对象,也就是设置UIScrollView的delegate属性
2、为了保证代理对象中拥有对应方法,所以必须让代理对象(控制器自己)遵守对应控件的代理协议(当前控制器要作为那个控件的代理对象,就那么控制器就要遵守这个控件的代理协议),一般控件的代理协议命名规则都是:控件名Delegate(如:UIScrollViewDelegate,UIAlertViewDelegate)
3、在控制器中实现所需要的方法
*/
@implementation ViewController
//即将开始拖拽
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
NSLog(@"即将开始拖拽");
}
//正在滚动
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
NSLog(@"正在拖拽");
NSString* pointStr=NSStringFromCGPoint(self.scrollview.contentOffset) ;
NSLog(@"%@",pointStr);
}
//结束拖拽
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
NSLog(@"结束拖拽");
}
- (void)viewDidLoad {
[super viewDidLoad];
//设置scrollView的宽高
self.scrollview.contentSize=self.imgView.image.size;
//通常使用控制器作为代理对象,实际就是self
//1、为UIScrollView找一个代理对象,也就是设置UIScrollView的delegate属性
self.scrollview.delegate=self;
}
@end
输出:
2020-06-28 16:21:21.069764+0800 IOS040[5909:220727] {221.5, 312.5}
2020-06-28 16:21:21.085941+0800 IOS040[5909:220727] 正在拖拽
2020-06-28 16:21:21.086179+0800 IOS040[5909:220727] {224.5, 316.5}
2020-06-28 16:21:21.102507+0800 IOS040[5909:220727] 正在拖拽
2020-06-28 16:21:21.102678+0800 IOS040[5909:220727] {227, 320}
2020-06-28 16:21:21.105778+0800 IOS040[5909:220727] 即将开始拖拽
2020-06-28 16:21:21.369434+0800 IOS040[5909:220727] 结束拖拽
6.通过代理注册事件实现内容缩放
思路
1、拖拽一个UIScrollView
2、向UIScrollView中添加内容(这里的内容就是指要缩放的内容(控件))
3、通过代理监听缩放时间,在缩放实践中返回UIScrollView的某个子控件(这个子控件就是告诉UIScrollView对这个控件进行缩放)
4、设置缩放比:最大能放大多少倍,最小能缩小百分之多少
5、一次只能缩放一个子控件
#import "ViewController.h"
//设置代理协议
@interface ViewController ()<UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UIImageView *imgView;
@end
@implementation ViewController
//实现缩放方法,在这个方法中返回要进行缩放的子控件
-(UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView{
NSLog(@"实现缩放scrollViewWillBeginZooming");
//返回图片框进行缩放
return self.imgView;
}
//即将开始缩放
-(void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view{
NSLog(@"即将开始缩放scrollViewWillBeginZooming");
}
//正在缩放
- -(void)scrollViewDidZoom:(UIScrollView *)scrollView{
NSLog(@"正在缩放scrollViewDidZoom");
}
//结束缩放
-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale{
NSLog(@"结束缩放scrollViewDidEndZooming");
}
- (void)viewDidLoad {
[super viewDidLoad];
//设置scrollView的缩放比例
self.scrollView.maximumZoomScale=3.5;
self.scrollView.minimumZoomScale=0.5;
}
@end
7.图片浏览器–分页
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//动态创建imageview并放入到scrollView
CGFloat img_W=300;
CGFloat img_H=130;
CGFloat img_Y=0;
for (int i=0; i<5; i++) {
//创建一个UIView
UIImageView* imageview=[[UIImageView alloc]init];
//设置这个uiview的大小图片
imageview.image=[UIImage imageNamed:[NSString stringWithFormat:@"img_%02d",i+1]];
CGFloat img_X=i*img_W;
imageview.frame=CGRectMake(img_X, img_Y, img_W, img_H);
//将图片添加到scrollView
[self.scrollView addSubview:imageview];
}
//设置scrollview的滚动
CGFloat maxW=self.scrollView.frame.size.width*5;
self.scrollView.contentSize=CGSizeMake(maxW, img_H);
//实现UIScrollView的分页效果
self.scrollView.pagingEnabled=YES;
//隐藏滚动指示器
self.scrollView.showsHorizontalScrollIndicator=NO;
}
@end
8.图片浏览器–分页指示器
设置分页的思路:
1、更具UIScrollView滚动到第几张图片,设置pageController当前第几个点显示为current page
2、当前页的数值=(当前滚动的偏移contentOffset.x+半个图片的宽度)/每个图片的宽度
为什么要偏移加半个宽度?
如果contentOffset.x小于半个宽度,那么加上半个宽度以后除以图片宽度,结果还是0;
如果contentOffset.x大于半个宽度,那么加上半个宽度以后除以一个宽度,结果还是1
#import "ViewController.h"
@interface ViewController ()<UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//动态创建imageview并放入到scrollView
CGFloat img_W=300;
CGFloat img_H=130;
CGFloat img_Y=0;
for (int i=0; i<5; i++) {
//创建一个UIView
UIImageView* imageview=[[UIImageView alloc]init];
//设置这个uiview的大小图片
imageview.image=[UIImage imageNamed:[NSString stringWithFormat:@"img_%02d",i+1]];
CGFloat img_X=i*img_W;
imageview.frame=CGRectMake(img_X, img_Y, img_W, img_H);
//将图片添加到scrollView
[self.scrollView addSubview:imageview];
}
//设置scrollview的滚动
CGFloat maxW=self.scrollView.frame.size.width*5;
self.scrollView.contentSize=CGSizeMake(maxW, img_H);
//实现UIScrollView的分页效果
self.scrollView.pagingEnabled=YES;
//隐藏滚动指示器
self.scrollView.showsHorizontalScrollIndicator=NO;
//将分页控制器子控件防到最前
//[self.scrollView bringSubviewToFront:self.pageControl];
//x:112 y:93 w:39 H:39
self.pageControl.numberOfPages=5;
self.pageControl.currentPage=0;
}
//实现滚动方法
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
//实现滚动方法
//1、获取动动的x方向的偏移值
CGFloat offsetX=scrollView.contentOffset.x;
offsetX+=scrollView.frame.size.width*0.5;
//2、用x方向的偏移值/一张图片的宽度,取商就得到了当前滚动到了第一页(索引)
int currentpage=offsetX/self.scrollView.frame.size.width;
//3、将页码设置给pageController
self.pageControl.currentPage=currentpage;
}
@end
9.图片浏览器–自动滚动(NStimer)
两种不同的定时器
- NSTimer(间隔时间比较大,1秒,几秒等)
- CAdisplayLink(间隔时间比较小,0.0几秒)
通过NSTimer启动定时器的两种方法 - 调用timerWithXxx创建的timer,需要把这个tiemr对象手动加到消息循环中,再调用一次fire才能启动
- 调用schedulTimerWithXxx创建的timer,不需要再调用一次fire自动启动
#import "ViewController.h"
@interface ViewController ()<UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//动态创建imageview并放入到scrollView
CGFloat img_W=300;
CGFloat img_H=130;
CGFloat img_Y=0;
for (int i=0; i<5; i++) {
//创建一个UIView
UIImageView* imageview=[[UIImageView alloc]init];
//设置这个uiview的大小图片
imageview.image=[UIImage imageNamed:[NSString stringWithFormat:@"img_%02d",i+1]];
CGFloat img_X=i*img_W;
imageview.frame=CGRectMake(img_X, img_Y, img_W, img_H);
//将图片添加到scrollView
[self.scrollView addSubview:imageview];
}
//设置scrollview的滚动
CGFloat maxW=self.scrollView.frame.size.width*5;
self.scrollView.contentSize=CGSizeMake(maxW, img_H);
//实现UIScrollView的分页效果
self.scrollView.pagingEnabled=YES;
//隐藏滚动指示器
self.scrollView.showsHorizontalScrollIndicator=NO;
//将分页控制器子控件防到最前
//[self.scrollView bringSubviewToFront:self.pageControl];
self.pageControl.numberOfPages=5;
self.pageControl.currentPage=0;
//创建一个定时器控件,这个定时器会自动启动因为是scheduled
NSTimer* timer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(scrollImage) userInfo:nil repeats:YES];
}
-(void)scrollImage{
//滚动一次图片,实际设置contentOffset的值
//1、拿到当前的页数
NSInteger pageNumber=self.pageControl.currentPage;
//2、判断是否到了最后一页,如果到了,则设页数为0,如果没到页数++,并让scrollView的contentOffset做出对应的偏转
if (pageNumber==self.pageControl.numberOfPages-1) {
//表示已经到达最后一页,设page=0
pageNumber=0;
}else{
pageNumber++;
}
CGFloat offsetX=pageNumber*self.scrollView.frame.size.width;
[self.scrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES];
//3、如果已经滚动到最后一页,则滚动到下一页
}
//实现滚动方法
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
//实现滚动方法
//1、获取动动的x方向的偏移值
CGFloat offsetX=scrollView.contentOffset.x;
offsetX+=scrollView.frame.size.width*0.5;
//2、用x方向的偏移值/一张图片的宽度,取商就得到了当前滚动到了第一页(索引)
int currentpage=offsetX/self.scrollView.frame.size.width;
//3、将页码设置给pageController
self.pageControl.currentPage=currentpage;
}
@end
10.图片浏览器–bug修复–调整线程优先级
#import "ViewController.h"
@interface ViewController ()<UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
//创建一个用来引用的计时器对象的属性
@property (strong,nonatomic) NSTimer* timer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//动态创建imageview并放入到scrollView
CGFloat img_W=300;
CGFloat img_H=130;
CGFloat img_Y=0;
for (int i=0; i<5; i++) {
//创建一个UIView
UIImageView* imageview=[[UIImageView alloc]init];
//设置这个uiview的大小图片
imageview.image=[UIImage imageNamed:[NSString stringWithFormat:@"img_%02d",i+1]];
CGFloat img_X=i*img_W;
imageview.frame=CGRectMake(img_X, img_Y, img_W, img_H);
//将图片添加到scrollView
[self.scrollView addSubview:imageview];
}
//设置scrollview的滚动
CGFloat maxW=self.scrollView.frame.size.width*5;
self.scrollView.contentSize=CGSizeMake(maxW, img_H);
//实现UIScrollView的分页效果
self.scrollView.pagingEnabled=YES;
//隐藏滚动指示器
self.scrollView.showsHorizontalScrollIndicator=NO;
//将分页控制器子控件防到最前
//[self.scrollView bringSubviewToFront:self.pageControl];
self.pageControl.numberOfPages=5;
self.pageControl.currentPage=0;
//创建一个定时器控件,这个定时器会自动启动因为是scheduled
self.timer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(scrollImage) userInfo:nil repeats:YES];
//修改self.timer的优先级与控件一样
//创建一个消息循环对象
NSRunLoop* runloop=[NSRunLoop currentRunLoop];
//改变self.timer对象的优先级
[runloop addTimer:self.timer forMode:NSRunLoopCommonModes];
}
-(void)scrollImage{
//滚动一次图片,实际设置contentOffset的值
//1、拿到当前的页数
NSInteger pageNumber=self.pageControl.currentPage;
//2、判断是否到了最后一页,如果到了,则设页数为0,如果没到页数++,并让scrollView的contentOffset做出对应的偏转
if (pageNumber==self.pageControl.numberOfPages-1) {
//表示已经到达最后一页,设page=0
pageNumber=0;
}else{
pageNumber++;
}
CGFloat offsetX=pageNumber*self.scrollView.frame.size.width;
[self.scrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES];
}
//实现滚动方法
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
//实现滚动方法
//1、获取动动的x方向的偏移值
CGFloat offsetX=scrollView.contentOffset.x;
offsetX+=scrollView.frame.size.width*0.5;
//2、用x方向的偏移值/一张图片的宽度,取商就得到了当前滚动到了第一页(索引)
int currentpage=offsetX/self.scrollView.frame.size.width;
//3、将页码设置给pageController
self.pageControl.currentPage=currentpage;
}
//实现即将开始拖拽的方法
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
//停止定制器
//使用invalidate一旦停止计时器,那么这个计时器就不能在重用了,下次必须重新创建一个计时器
[self.timer invalidate];
//调用完invalidate方法后,这个计时器不能再使用了
self.timer=nil;
}
//实现拖拽完毕的方法
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
//重启定制器
self.timer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(scrollImage) userInfo:nil repeats:YES];
//创建一个消息循环对象
NSRunLoop* runloop=[NSRunLoop currentRunLoop];
//改变self.timer对象的优先级
[runloop addTimer:self.timer forMode:NSRunLoopCommonModes];
}
@end
更多推荐
所有评论(0)