前言
.getter、setter的重写细节
/**
图像的setter方法;setter方法,除了赋值,还执行了contentSize的设置动作
*/
- (void)setImage:(UIImage *)image{
//setter方法的第一个步骤:给属性进行赋值
_image = image;
//设置图像视图的内容
[self.imageView setImage:_image];
//让图像视图,根据图像大小,自动调整自己的视图大小
[self.imageView sizeToFit];//Resizes and moves the receiver view so it just encloses its subviews.
//告诉图像视图,内部内容实际的大小
[self.scrollView setContentSize:_image.size];
}
/**
0.getter 方法的重写
* 使用自身对象的时候,使用_属性名称进行获取
*使用其他成员属性的时候,使用self.gtter 方法,这样可以及时的实例化对用的成员属性
1.懒加载imageView属性,重写getter方法--使用对象dot属性名称的时候,会调用getter方法,_属性名称不会调用getter方法
*/
- (UIImageView *)imageView{
if (nil == _imageView) {
//创建imageView
UIImageView *tmpImageView = [[UIImageView alloc]init];
_imageView=tmpImageView;
[self.scrollView addSubview:_imageView];
}
return _imageView;
}
零、 运行循环runloop
//往运行循环添加特定事件的目标和动作(add target/action for particular event)--- 使用UIControl 的addTarget:action:forControlEvents:方法
//将监听方法click注册到“运行循环”,当触发ControlEvent事件时,由“运行循环”通知Target(ViewController) 执行action(@selector)
//Adds a target and action for a particular event (or events) to an internal dispatch table.将特定事件的执行目标和行动添加到内部调度表
[btn addTarget:self action:@selector(click) forControlEvents:UIControlEventTouchUpInside];
#pragma mark - 计时器的播放实现
- (IBAction)start{
NSLog(@"%s",__FUNCTION__);
//间隔一秒更新counterLabel的显示
//计时器
//往运行循环添加timer的方式一:-------------------------------------------
/**
Creates and returns a new NSTimer object and schedules it on the current run loop in the default mode.
参数说明
1》seconds: double 时间间隔
2》target: The object to which to send the message specified by aSelector when the timer fires. 监听时钟触发的对象
3》Selector: The message to send to target when the timer fires.调用的方法
The selector should have the following signature: timerFireMethod:
- (void)timerFireMethod:(NSTimer *)timer
4》userInfo: The user info for the timer.通常为nil,可用于区分计时器
repeats:if YES, the timer will repeatedly reschedule itself until invalidated. If NO, the timer will be invalidated after it fires.是否重复
*/
// self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTimer:) userInfo:nil repeats:YES];
//将timer添加到运行循环的方式二-------------------------------------------
self.timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(updateTimer:) userInfo:nil repeats:YES];
//Registers a given timer with a given input mode.NSRunLoopCommonModes (监听滚动模式)
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode: NSRunLoopCommonModes];
}
一、掌握
1》UIScrollView的常见属性
// ViewController.m
// 20160316-喜马拉雅
// Created by devzkn on 3/16/16.
// Copyright © 2016 hisun. All rights reserved
//
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UIButton *lastButton;
@end
@implementation ViewController
/**
1.--setter方法的实现差别
contentSize 会根据ContentInset调整offset--除了赋值,还实现了其他动作
contentInset不会根据contentSize调整offset--单纯给属性赋值
*/
- (void)viewDidLoad {
[super viewDidLoad];
//1.设置间距:只是指定内容外侧的边距,并不会根据contentSize自动调整contentOffset
[self.scrollView setContentInset:UIEdgeInsetsMake(64, 0, 0, 0)];
//2. 设置滚动视图内容大小
//1> 若有间距contentInset,根据间距自动调整contentOffset
//2> 若无contentInset,contentOffset是(0,0)
[self.scrollView setContentSize:CGSizeMake(0, CGRectGetMaxY(self.lastButton.frame)+10)];//CGRectGetMaxY(self.lastButton.frame)+10) 是为了能更清楚的显示最后一个按钮
//3.设置偏移位置
[self.scrollView setContentOffset:CGPointMake(0, -64)];
}
@end
*因此在使用contentSize、contentInset、contentOffset的setter方法的时候,要注意先后顺序;想要准确的调整offset的话,可以先设置inset-》size;或者是:size-》offset
*storyBoard快速布局方法:使用option键,进行拖拽实现控件的copy
2》UI ScrollView的常用代理方法
3》UI Scrollview 的缩放
*在simulator上面操作缩放:按住option键即可
4》UI ScrollView和UIPageControl的分页实现方式
5》NSTimer 的使用
6》自动布局:Apple为了让程序员能够将注意力集中在程序上,而不用在代码中过多的使用frame。
*“参照” 任何一个控件,都可以参照另外一个控件定义出准确的位置
二、 什么是UIScrollView
是一个能滚动的视图控件,可以用来展示大量的内容,且通过滚动可以查看所有内容
1、UIScrollView 的基本使用 -- 解决UIScrollView 无法滚动的方法
1》 检查是否设置contentSize 属性
2》 检查scrollEnabled 属性值是否=NO
3》检查userInteractionEnabled 是否为NO
4》 取消outLayout 的功能:若是通过storyBoard中添加的scrollView控件,要想scrollView滚动的话,必须取消autoLayout。
2、UIScrollView的常见属性
@property(nonatomic) CGPoint contentOffset; //这个属性用来表示UIScrollView滚动的位置
@property(nonatomic) CGSize contentSize; //这个属性用来表示UIScrollView内容的尺寸,滚动范围(能滚多远)
@property(nonatomic) UIEdgeInsets contentInset; //这个属性能够在UIScrollView的4周增加额外的滚动区域
三、UIScrollView的delegate
0、代理的作用是什么?
1》》代理设计模式,在o c中使用最为广泛的一种设计模式;主要用来负责在两个对象之间,发生某些事件时,来传递消息或者数据
2》》监听哪些“不能通过addTarget方式监听“的事件
1.背景
1》目标:想再UIScrollView的正在滚动状态、滚动到某位置、停止滚动状态时做一些特定的动作
2》前提:监听UIScrollView 的滚动过程(事件)
3》实现方法:通过给UIScrollView 设置delegate对象,当UIScrollView发生一系列滚动的时候,会自动通知(发生特定消息亦即方法调用)它的代理对象
4》 成为delegate 对象的条件:遵守UIScrollViewDelegate的协议,并实现对应方法
--通常将UIScrollView 所在的ViewController设置为它的delegate对象
5》设置UIScrollView 的delegate属性的两者方法:
1》》通过代码实现:
使用修改scrollView对象的属性方式添加delegate 折叠原码
1
self.scrollView.delegate = self;
2》》:通过storyBoard的拖线
delegate 的例子:控制器希望知道用户输入的每一个字符!
代理小结:
1、代理实现的步骤:
1》》成为(子)控件的代理;--父亲(视图控制器)成为儿子(textField)的代理
2》》 遵守协议--》目的是利用Xcode的智能提示功能,快速编写代码--这个步骤可选
3》》实现协议方法
p s: 协议是由控件定义的,因为只有控件自己本身最了解自己内部发生的事件。
四、UIScrollView 的缩放原理
1. 当用户在UIScrollView身上使用捏合手势时,UIScrollView会给delegate对象发送一条消息,询问delegate究竟要缩放自己内部的哪个子控件(那一块内容)
- (void) scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view;//准备开始缩放的时候调用
- (void)scrollViewDidZoom:(UIScrollView *)scrollView;//正在缩放的时候调用
当用户使用捏合手势的时候,UIScrollView 会调用delegate对象的viewForZoomingInScrollView:方法,这个方法返回的控件就是需要进行缩放的控件。
2、缩放实现步骤:
1>设置UIScrollView的iddelegate对象
2》设置minimumZoomScale、MaximumZoomScale 缩小、放大的最大比例
3》delegate对象实现viewForZoomingInScrollView:方法,返回需要缩放的视图控件
ps:其他根缩放相关的delegate方法:
五、分页
只要将UIScrollView 的属性PageEnabled设为YES,UIScrollView会被分割成多个独立的页面,里面的内容就能进行分页展示
1》通常配合UIPageControl使用,来增强分页效果
1》》UIPageControl 的常见属性:
//一共有多少页
@property(nonatomic) NSInteger numberOfPages;
//当前显示的页码
@property(nonatomic) NSInteger currentPage;
//只有一页时,是否需要隐藏页码指示器
@property(nonatomic) BOOL hidesForSinglePage;
//其他页码指示器的颜色
@property(nonatomic,retain) UIColor *pageIndicatorTintColor;
//当前页码指示器的颜色
@property(nonatomic,retain) UIColor *currentPageIndicatorTintColor;
六、NSTimer 定时器
1、作用:
1》》:在指定的时间,执指定的任务(方法、动作)
2》》:每隔一段时间,执行制定任务(action)
2.实现方法:
1》》开启一个定时任务,调用scheduleTimerWithTimeInterval:方法
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;
每隔ti秒,调用一次aTarget的aSelector方法,yesOrNo决定了是否重复执行这个任务
1》》停止定时器工作 --调用invalidate:方法
- (void)invalidate;//n一旦定时器被停止了,就不能再次执行任务。只能再创建一个新的定时器才能执行新的任务
2.NSTimer准确吗?如果不准确,怎么办?
1>>.NSTimer通常用来有一定时间跨度的周期性事件的处理!--》不准确
2>>.CADisplayLink 与 NSTimer 有什么不同?
IOS设备的屏幕刷新频率是固定的,CADisplayLink在正常情况下会在每次刷新结束都被调用,精确度相当高。--》解决方法,CADisplayLink适用于“时间间隔比较短“的事件处理
*NSTimer的精确度就显得低了点,比如NSTimer的触发时间到的时候,runloop如果在阻塞状态,触发时间就会推迟到下一个runloop周期--》导致任务的叠加。并且 NSTimer新增了tolerance属性,让用户可以设置可以容忍的触发的时间的延迟范围。
*CADisplayLink使用场合相对专一,适合做UI的不停重绘,比如自定义动画引擎或者视频播放的渲染。NSTimer的使用范围要广泛的多,各种需要单次或者循环定时处理的任务都可以使用。在UI相关的动画或者显示内容使用 CADisplayLink比起用NSTimer的好处就是我们不需要在格外关心屏幕的刷新频率了,因为它本身就是跟屏幕刷新同步的。
ps注意:
1>通常来讲,iOS设备的刷新频率事60HZ也就是每秒60次。那么每一次刷新的时间就是1/60秒 大概16.7毫秒。当我们的frameInterval值为1的时候我们需要保证的是 CADisplayLink调用的`target`的函数计算时间不应该大于 16.7否则就会出现严重的丢帧现象。https://developer.apple.com/library/ios/documentation/QuartzCore/Reference/CADisplayLink_ClassRef/index.html
2>在mac应用中我们使用的不是CADisplayLink而是 CVDisplayLink它是基于C接口的用起来配置有些麻烦但是用起来还是很简单的。
https://developer.apple.com/library/ios/samplecode/AVBasicVideoOutput/Introduction/Intro.html#//apple_ref/doc/uid/DTS40013109
2>一个类似Secret文字渐变效果的开源库
https://github.com/zipme/RQShineLabel/tree/master/Example/RQShineLabelDemo
正文
一、UIKit 的复习,以及delegate 的介绍
//
// ViewController.m
// 20160313-UIKitReview
//
// Created by devzkn on 3/13/16.
// Copyright © 2016 hisun. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()<UITextFieldDelegate>
@end
@implementation ViewController
/**
1、UIButton -》UIControl-》UIView
1.1》 设置控件的状态
NS_CLASS_AVAILABLE_IOS(2_0) @interface UIControl : UIView
@property(nonatomic,getter=isEnabled) BOOL enabled;//启用、禁用控件
@property(nonatomic,getter=isSelected) BOOL selected;//选中、不选中
@property(nonatomic,getter=isHighlighted) BOOL highlighted; //高亮、不高亮
1.2》 设置控件内容的布局
@property(nonatomic) UIControlContentVerticalAlignment contentVerticalAlignment;//垂直居中方法
@property(nonatomic) UIControlContentHorizontalAlignment contentHorizontalAlignment;//水平居中方向
1.3>添加监听方法
- (void)addTarget:(nullable id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;
- (void)removeTarget:(nullable id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;
2.UILabel -》UIView
3、UIImageView-》UIView
4.UITextField-》UIControl-》UIView
****代理设计模式,是oc中最为广泛的一种设计模式
1》 代理的作用是什么?
*监听哪些“不能通过addTarget方式监听的“事件
*主要负责在,两对象之间,发生某些事件时,数据或消息的传递工作
2》代理实现的步骤
*成为(子)控件的代理;父亲(视图控制器)成为儿子(textField)的代理
*可选步骤:遵守协议,-》利用ide的提示功能,快速编写代码
*实现协议方法
*/
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeContactAdd];
[btn setCenter:self.view.center];
[self.view addSubview:btn];
//将监听方法click注册到“运行循环”,当触发ControlEvent事件时,由“运行循环”通知Target(ViewController) 执行action(@selector)
//Adds a target and action for a particular event (or events) to an internal dispatch table.将特定事件的执行目标和行动添加到内部调度表
[btn addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
UITextField *textField = [[UITextField alloc]initWithFrame:CGRectMake(100, 100, 80, 20)];
[textField setText:@"lydia"];
[textField setTextColor:[UIColor blackColor]];
[textField setContentHorizontalAlignment:UIControlContentHorizontalAlignmentCenter];
[textField setDelegate:self];
[self.view addSubview:textField];
}
#pragma mark - 文本框代理
/**
成为代理之后要做的事情是什么?以及如何工作
1》协议:一些预先定义的没有具体的实现方法名,每个方法对应不同的事件。@protocol UITextFieldDelegate <NSObject>
*/
//Asks the delegate if the specified text should be changed.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
NSLog(@"replacementString =%@, textField = %@,NsRange = %@",string,textField.text,NSStringFromRange(range));
//限制输入的长度
long location = range.location;
return location<7;//YEStrue if the specified text range should be replaced; otherwise, NOfalse to keep the old text.
}
/**
*/
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
// NSLog(@"%s",__FUNCTION__);
return YES;// if an editing session should be initiated
}
- (void)textFieldDidBeginEditing:(UITextField *)textField{
// NSLog(@"%s",__FUNCTION__);
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField{
// NSLog(@"%s",__FUNCTION__);
return YES;//if editing should stop
}
- (void)textFieldDidEndEditing:(UITextField *)textField{
NSLog(@"%s",__FUNCTION__);
}
- (BOOL)textFieldShouldClear:(UITextField *)textField{
NSLog(@"%s",__FUNCTION__);
return YES;//if the text field’s contents should be cleared;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
NSLog(@"%s",__FUNCTION__);
return YES;//if the text field should implement its default behavior for the return button;
}
- (void)click:(UIButton *)button{
NSLog(@"%s",__FUNCTION__);
[button removeTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
}
// ViewController.m
// 20160316-喜马拉雅
// Created by devzkn on 3/16/16.
// Copyright © 2016 hisun. All rights reserved.
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UIButton *lastButton;
@end
@implementation ViewController
/**
1.--setter方法的实现差别(可采用设置断点进行查看)
contentSize 会根据ContentInset调整offset--除了赋值,还实现了其他动作
contentInset不会根据contentSize调整offset--单纯给属性赋值
*/
//系统加载了storyBoard之后,调用setScrollView:方法对scrollView对象进行赋值
- (void)setScrollView:(UIScrollView *)scrollView{//本方法先于viewDidLoad:执行;本方法由系统底层自动调用
_scrollView = scrollView;//1》setter 方法的第一句,就是赋值
//2》其他的动作
[_scrollView setContentInset:UIEdgeInsetsMake(64, 0, 10, 0)];
[_scrollView setContentSize:CGSizeMake(0, CGRectGetMaxY(self.lastButton.frame))];
}
/**
视图加载完成之后执行
*/
- (void)viewDidLoad {
[super viewDidLoad];
//1.设置间距:只是指定内容外侧的边距,并不会根据contentSize自动调整contentOffset
// [self.scrollView setContentInset:UIEdgeInsetsMake(64, 0, 0, 0)];
//2. 设置滚动视图内容大小
//1> 若有间距contentInset,根据间距自动调整contentOffset
//2> 若无contentInset,contentOffset是(0,0)
// [self.scrollView setContentSize:CGSizeMake(0, CGRectGetMaxY(self.lastButton.frame)+10)];//CGRectGetMaxY(self.lastButton.frame)+10) 是为了能更清楚的显示最后一个按钮
//3.设置偏移位置
// [self.scrollView setContentOffset:CGPointMake(0, -64)];
}
@end
//
// ViewController.m
// 20160317-倒计时
//
// Created by devzkn on 3/17/16.
// Copyright © 2016 hisun. All rights reserved.
//
#import "ViewController.h"
@interface ViewController () <UIAlertViewDelegate>
@property (weak, nonatomic) IBOutlet UILabel *counterLabel;
@property (nonatomic,strong) NSTimer *timer;
@end
@implementation ViewController
#pragma mark - 计时器的播放实现
- (IBAction)start{
NSLog(@"%s",__FUNCTION__);
//间隔一秒更新counterLabel的显示
//计时器
//往运行循环添加timer的方式一:-------------------------------------------
/**
Creates and returns a new NSTimer object and schedules it on the current run loop in the default mode.
参数说明
1》seconds: double 时间间隔
2》target: The object to which to send the message specified by aSelector when the timer fires. 监听时钟触发的对象
3》Selector: The message to send to target when the timer fires.调用的方法
The selector should have the following signature: timerFireMethod:
- (void)timerFireMethod:(NSTimer *)timer
4》userInfo: The user info for the timer.通常为nil,可用于区分计时器
repeats:if YES, the timer will repeatedly reschedule itself until invalidated. If NO, the timer will be invalidated after it fires.是否重复
*/
// self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTimer:) userInfo:nil repeats:YES];
//将timer添加到运行循环的方式二-------------------------------------------
self.timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(updateTimer:) userInfo:nil repeats:YES];
//Registers a given timer with a given input mode.NSRunLoopCommonModes (监听滚动模式)
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode: NSRunLoopCommonModes];
}
/**
时钟更新方法
*/
- (void) updateTimer:(NSTimer *) timer{
//1>取出标签的数字
int count = self.counterLabel.text.intValue;
//若counterLabel.text.intValue =0 ,弹出一些提示信息,否则进行倒计时
if (0 > --count) {//count-- 先赋值,再自减
[self pause];
[[[UIAlertView alloc]initWithTitle:@"start" message:@"In the beginning, laydia" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"done",@"kevin",nil] show];
return;
}
//2》修改counterLabel的text信息
self.counterLabel.text = [NSString stringWithFormat: @"%d",count];//--count 先自减,再赋值
}
- (IBAction)pause{
NSLog(@"%s",__FUNCTION__);
//停止时钟,一旦调用invalidate:方法,timer就失效,如果要重新启动时钟,需要重新实例化
[self.timer invalidate];//唯一停止时钟的方法
}
- (IBAction)clean{
NSLog(@"%s",__FUNCTION__);
}
#pragma mark - UIAlertViewDelegate 的协议方法
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
NSLog(@"%lu",buttonIndex);
}
- (void)alertViewCancel:(UIAlertView *)alertView{
NSLog(@"%s",__FUNCTION__);
}
-(BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView{
NSLog(@"%s",__FUNCTION__);
return NO;
}
@end
图片轮播器
开发步骤:
1. scrollView getter方法懒加载
只指定了大小,添加到视图
2. viewDidLoad中添加图像,并且计算位置
3. 运行观察效果,修改scrollView的属性…….
4. 实例化UIPageControl
5. 因为分页控件和滚动视图是分离的,因此监听滚动停止代理方法,修改分页控件的页数
6. 将UIPageControl定义成属性,并且添加监听方法
7. 实现监听方法,页数变化后,修改scrollView的位置
8. 添加时钟,调用分页控件的监听方法,实现图片自动轮播
/ ViewController.m
// 20160318-图片轮播器
/**
今天的开发步骤:
1. scrollView getter方法懒加载
只指定了大小,添加到视图
2. viewDidLoad中添加图像,并且计算位置
3. 运行观察效果,修改scrollView的属性.......
4. 实例化UIPageControl
5. 因为分页控件和滚动视图是分离的,因此监听滚动停止代理方法,修改分页控件的页数
6. 将UIPageControl定义成属性,并且添加监听方法
7. 实现监听方法,页数变化后,修改scrollView的位置
8. 添加时钟,调用分页控件的监听方法,实现图片自动轮播
*/
//
// Created by devzkn on 3/18/16.
// Copyright © 2016 hisun. All rights reserved.
//
#import "ViewController.h"
#define kImageCount 5
@interface ViewController () <UIScrollViewDelegate>
@property (nonatomic,weak) UIScrollView *scrollView;
@property (nonatomic,weak) UIPageControl *pageControl;
@property (nonatomic,strong) NSTimer *timer;
@end
@implementation ViewController
/**
重写getter方法,进行懒加载实例化属性对象
*/
- (UIPageControl *)pageControl{
if (nil == _pageControl) {
//实例化属性
UIPageControl *tmpPageControl = [[UIPageControl alloc]init];
//设置控件大小
CGSize size = [tmpPageControl sizeForNumberOfPages:kImageCount];
[tmpPageControl setBounds:CGRectMake(0, 0, size.width, size.height)];
//设置总页数
[tmpPageControl setNumberOfPages:kImageCount];
//设置颜色
[tmpPageControl setPageIndicatorTintColor:[UIColor redColor]];
[tmpPageControl setCurrentPageIndicatorTintColor:[UIColor blackColor]];
//设置位置
[tmpPageControl setCenter:CGPointMake(self.view.center.x, CGRectGetHeight(self.scrollView.bounds))];
_pageControl = tmpPageControl;
//添加监听方法:再oc中,继承于UIControl的控件,绝大多数都可以监听UIControlEventValueChanged事件,UIButton除外
[_pageControl addTarget:self action:@selector(changePage) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:_pageControl];
}
return _pageControl;
}
/**
重写getter方法,进行懒加载方式实例化属性
*/
- (UIScrollView *)scrollView{
if (nil == _scrollView) {
UIScrollView *tmpScrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(10, 20, 300, 130)];
_scrollView = tmpScrollView;
//代理设置、contentSize、contentOffset、contentInset
[_scrollView setDelegate:self];
[_scrollView setContentSize:CGSizeMake(CGRectGetWidth(_scrollView.bounds)*kImageCount, 0)];
//设置分页
[_scrollView setPagingEnabled:YES];
//取消水平滚动条
[_scrollView setShowsHorizontalScrollIndicator:NO];
[_scrollView setShowsVerticalScrollIndicator:NO];
//取消弹簧效果
[_scrollView setBounces:NO];
[_scrollView setBackgroundColor:[UIColor lightGrayColor]];
[self.view addSubview:_scrollView];
}
return _scrollView;
}
/**
通常用来设置数据
*/
- (void)viewDidLoad {
[super viewDidLoad];
//设置图片(内容)
for (int i=0; i<kImageCount; i++) {
NSString *imageName = [NSString stringWithFormat:@"img_%02d",i+1];
UIImage *image = [UIImage imageNamed:imageName] ;
UIImageView *imageView = [[UIImageView alloc]initWithFrame:self.scrollView.bounds];
[imageView setImage:image];
[self.scrollView addSubview:imageView];
}
//计算imageView的位置
[[self.scrollView subviews] enumerateObjectsUsingBlock:^(UIImageView *imageView, NSUInteger idx, BOOL *stop) {
CGRect frame =imageView.frame;
frame.origin.x = idx*CGRectGetWidth(frame);
[imageView setFrame:frame];
}];
[self.pageControl setCurrentPage:0];
//启动时钟
[self startTimer];
}
- (void) startTimer{
//启动时钟(修改UIPageControl 的currentPage 同时也修改UIScrollView 的contentOffset)
self.timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(photoCarousel:) userInfo:nil repeats:YES];
//注册时钟到runloop
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}
/**
修改scrollView的contentoffset的同时,对UIPageControl进行页码设置,来实现定时图片轮播
*/
- (void) photoCarousel:(NSTimer *)timer{
//设置页码
[self.pageControl setCurrentPage:((self.pageControl.currentPage+1)%kImageCount)];
//设置偏移位置
// [self.scrollView setContentOffset:CGPointMake(self.pageControl.currentPage*CGRectGetWidth(self.scrollView.bounds), 0) animated:YES];
[self changePage];
}
#pragma mark scrollView 的代理方法
/**
Tells the delegate that the scroll view has ended decelerating the scrolling movement.
*/
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
//更新pageControl的页码
// UIPageControl *pageControl =[[self.view subviews]lastObject];
self.pageControl.currentPage= scrollView.contentOffset.x/ CGRectGetWidth(scrollView.bounds);
}
//抓住图片时,停止时钟
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
[self.timer invalidate];
NSLog(@"%s",__FUNCTION__);
}
// 停止抓住图片时,开启时钟
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{
[self startTimer];
NSLog(@"%s",__FUNCTION__);
}
/**
切换图片(修改UIScrollView 显示的UIImageView对象,即修改contentOffSize即可 )
*/
- (void) changePage{//根据pageControl的页码,来调整UIScrollView的内容(图像)位置
CGFloat x= self.pageControl.currentPage*CGRectGetWidth(self.scrollView.frame);
[self.scrollView setContentOffset:CGPointMake(x, 0) animated:YES];
}
@end