UISCrollView —— 图片轮播器实现(三)——(第二讲)

时间:2022-12-05 20:21:50

1. 所用知识点

  1> UIScrollView的基本属性,和UIPageControl设置,还有就是要用到NSTimer来定时实现UIScrollView的图片轮播

  2> NSTimer简单介绍:

    2.1  NSTimer叫做“定时器”,它的作用如下

         * 在指定的时间执行指定的任务

         * 每隔一段时间执行指定的任务
 
    2.2  NSTimer简单使用:
        1> 调用下面的方法就会开启一个定时任务

              + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti   target:(id)aTarget

                     selector:(SEL)aSelector

                     userInfo:(id)userInfo

                     repeats:(BOOL)yesOrNo;

       意思就是:每隔ti秒,调用一次aTarget的aSelector方法,yesOrNo决定了是否重复执行这个任务

       2> 通过invalidate方法可以停止定时器的工作,一旦定时器被停止了,就不能再次执行任务。只能再创建一个新的定时器才能执行新的任务

             - (void)invalidate;

2、图片轮播具体代码实现

 1 #import "ViewController.h"
2
3 //#define kImageCount 5
4 #define IMAGE_COUNT 5
5 @interface ViewController ()<UIScrollViewDelegate>
6 @property (weak, nonatomic) IBOutlet UIScrollView *sc;
7 @property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
8
9 // 注意:NSTimer应该是weak
10 // 为什么NSTimer应该是weak, 因为只要创建一个NSTimer对象, 该对象就会被主线程强引用
11 @property (weak, nonatomic) NSTimer *timer;
12 @end
13
14 @implementation ViewController
15
16 - (void)viewDidLoad
17 {
18 [super viewDidLoad];
19
20 self.sc.showsHorizontalScrollIndicator = NO;
21 self.sc.showsVerticalScrollIndicator = NO;
22
23 // Do any additional setup after loading the view, typically from a nib.
24 CGFloat width = self.sc.frame.size.width;
25 CGFloat height = self.sc.frame.size.height;
26
27 // 1.初始化子控件, 添加图片
28 for (int i = 0; i < IMAGE_COUNT; i++) {
29 // 1.创建UIImageView
30 UIImageView *iv = [[UIImageView alloc] init];
31 // 2.创建图片
32 UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"img_%02i", i + 1]];
33 // 3.设置每个UIImageView的frame
34 iv.frame = CGRectMake(i * width, 0, width, height); // 按照宽度分页
35 iv.image = image;
36 // 4.添加到父控件
37 [self.sc addSubview:iv];
38 }
39
40 // 2.设置滚动范围
41 self.sc.contentSize = CGSizeMake(IMAGE_COUNT * width, height);
42 self.sc.bounces = NO;
43 self.sc.pagingEnabled = YES;
44
45 // 3.监听PageControl的点击事件
46 [self.pageControl addTarget:self action:@selector(pageControlClick:) forControlEvents:UIControlEventValueChanged];
47 self.pageControl.numberOfPages = IMAGE_COUNT;
48
49 // 4.通过KVC给UIPageControl的私有属性赋值, 设置自定义图片
50 [self.pageControl setValue:[UIImage imageNamed:@"current"] forKeyPath:@"_currentPageImage"];
51 [self.pageControl setValue:[UIImage imageNamed:@"other"] forKeyPath:@"_pageImage"];
52
53 // 5.让UIScrollView每隔一段事件就切换一页
54 /*
55 scheduledTimerWithTimeInterval: 创建一个定时器, 并且立即可是计时
56 TimeInterval: 间隔时间
57 target: 调用谁的方法
58 selector: 调用什么方法
59 userInfo: 需要传递什么参数
60 repeats: 是否重复
61 每隔2.0秒调用一次self的nextPage方法, 并且不传递任何参数
62 */
63 // 如果给userInfo赋值, 那么定时器调用的方法就必须接受参数, 并且接受的参数就是NSTimer
64 // 只要调用scheduled方法创建一个NSTimer对象, 系统就会自动将NSTimer添加到主线程中
65
66 // self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(nextPage:) userInfo:@"lnj" repeats:YES];
67 [self startTimer];
68
69 }
70
71 // 切换到下一页
72 - (void)nextPage:(NSTimer *)timer
73 {
74 // NSLog(@"%@", timer.userInfo);
75
76 // 1.获取下一页的页码
77 NSUInteger page = self.pageControl.currentPage + 1;
78 // 2.判断页码是否越界
79 if (page >= IMAGE_COUNT) {
80 // 如果越界就回到第0页
81 self.pageControl.currentPage = 0;
82 }else
83 {
84 // 如果没有越界, 就进入到下一页
85 self.pageControl.currentPage = page;
86 }
87
88 [self pageControlClick:self.pageControl];
89 }
90
91 #pragma mark - UIScrollViewDelegate
92 // 只要滚动就会调用
93 - (void)scrollViewDidScroll:(nonnull UIScrollView *)scrollView
94 {
95 // 1.计算页码
96 // 当前页码 = 偏移位 / UIScrollView的宽度
97 CGFloat page = scrollView.contentOffset.x / scrollView.frame.size.width;
98 int currnetPage = page + 0.5;
99
100 // 2.修改页码
101 self.pageControl.currentPage = currnetPage;
102 }
103
104 // 开始拖拽
105 - (void)scrollViewWillBeginDragging:(nonnull UIScrollView *)scrollView
106 {
107 // NSLog(@"%s", __func__);
108 [self stopTimer];
109 }
110
111 // 结束拖拽
112 - (void)scrollViewDidEndDragging:(nonnull UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
113 {
114 // NSLog(@"%s", __func__);
115 [self startTimer];
116
117 }
118
119 #pragma mark - 定时器相关
120 - (void)startTimer
121 {
122 // 打开定时器
123 self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(nextPage:) userInfo:@"lnj" repeats:YES];
124
125 // 主线程在处理其它事件的时候, 分一点时间来处理NSTimer
126 // 1.0 0.1
127 [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
128 }
129
130 - (void)stopTimer
131 {
132 // 关掉定时器
133 #warning 注意:NSTimer是一次性的, 只要invalidate之后就不能使用了
134 // 只要调用invalidate方法, 系统就会将NSTimer从主线程移除, 并且销毁NSTimer对象
135 NSLog(@"销毁前: %@", self.timer);
136 [self.timer invalidate];
137 NSLog(@"销毁后: %@", self.timer);
138 }
139
140 #pragma mark - 内部监听
141 - (IBAction)pageControlClick:(UIPageControl *)sender {
142
143 self.sc.contentOffset = CGPointMake(sender.currentPage * self.sc.frame.size.width , 0);
144 }
145 @end

写了半天,来预览一下华丽的图片轮播器

UISCrollView —— 图片轮播器实现(三)——(第二讲) 

下一讲,将讲解,如何封装图片轮播器,下节再见,^_^