Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

day05之“ScrollView”

$
0
0

前言

.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

总结:

作者:u011018979 发表于2017/6/27 11:06:34 原文链接
阅读:31 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles