IOS开发之UIScrollView实现图片轮播器的无限滚动

时间:2022-05-26 14:08:23

IOS开发之UIScrollView实现图片轮播器的无限滚动

简介

在现在的一些App中常常见到图片轮播器,一般用于展示广告、新闻等数据,在iOS内并没有现成的控件直接实现这种功能,但是通过UIScrollView的允许分页设置,可以实现滚动轮播的功能。

轮播原理

UIScrollView对象有pagingEnable成员,如果设置为YES,那么每一个scrollView尺寸这么大的区域就会被当作一页,在滚动时会根据滚动的比例自动计算应该切换到哪一页。

无限滚动原理

要实现无限滚动,需要额外的两张图片,假设我们的图片有五张,存在images数组中,那么我们在将图片插入到scrollView中时,在第一张图片前面插入一个最后一张图片作为辅助图片,在最后一张后面插入一个第一张图片作为辅助图片。这样,当滚动到第一张前面一张时,在页面切换结束后无动画的切换scrollView的偏移量为最后一张图片(不包含最后一张后面的第一张那个辅助图片),这样就实现了由辅助图片到真实图片的过渡,之所以设置辅助图片是为了在滚动中看到那个真实图片。同理,当滚动到最后一张的后面一张时,我们吧scrollView的偏移量设置为第一张图片即可。

具体的代码实现

这个代码是在开发一个项目中所写的,已经封装称一个View,只需要调用initWithFrame指定轮播器尺寸,然后通过设置images成员的值即可实现无限滚动的轮播。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// .h
//
// ESPicPageView.h
// 享技
//
// Created by 11 on 11/30/15.
// Copyright © 2015 soulghost. All rights reserved.
//
 
#import <UIKit/UIKit.h>
 
@interface ESPicPageView : UIView
 
@property (nonatomic, strong) NSArray *images;
 
@end
// --------------------------------------------
// .m
//
// ESPicPageView.m
// 享技
//
// Created by 11 on 11/30/15.
// Copyright © 2015 soulghost. All rights reserved.
//
 
#import "ESPicPageView.h"
#import "UIImageView+WebCache.h"
 
@interface ESPicPageView () <UIScrollViewDelegate>
 
@property (nonatomic, weak) UIScrollView *scrollView;
@property (nonatomic, weak) UIPageControl *pageControl;
@property (nonatomic, assign) CGFloat imgW;
@property (nonatomic, assign) CGFloat imgH;
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, strong) NSArray *imageViews;
@property (nonatomic, assign) NSInteger imageCount;
 
@end
 
@implementation ESPicPageView
 
- (instancetype)initWithFrame:(CGRect)frame{
 
  if (self = [super initWithFrame:frame]) {
 
    self.backgroundColor = [UIColor blueColor];
    UIScrollView *scrollView = [[UIScrollView alloc] init];
    self.scrollView = scrollView;
    self.scrollView.delegate = self;
    self.scrollView.pagingEnabled = YES;
    self.scrollView.showsHorizontalScrollIndicator = NO;
    self.scrollView.backgroundColor = [UIColor whiteColor];
    [self addSubview:scrollView];
    self.imgW = frame.size.width;
    self.imgH = frame.size.height;
    [self setNeedsLayout];
 
    UIPageControl *pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(frame.size.width - 50, frame.size.height - 10, 0, 0)];
    self.pageControl = pageControl;
    self.pageControl.numberOfPages = 1;
    [self addSubview:pageControl];
 
    self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(nextImage) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
 
  }
 
  return self;
 
}
 
- (void)nextImage{
  NSInteger page = self.pageControl.currentPage;
  page = self.pageControl.currentPage + 1;
  CGPoint offset = CGPointMake((1 + page) * self.imgW, 0);
  [self.scrollView setContentOffset:offset animated:YES];
}
 
- (void)setupImageViews{
 
  for (int i = 0; i < self.images.count + 2; i++) {
    UIImageView *imageView = [[UIImageView alloc] init];
    CGFloat imageX = i * self.imgW;
    CGFloat imageY = 0;
    CGFloat imageW = self.imgW;
    CGFloat imageH = self.imgH;
    imageView.frame = CGRectMake(imageX, imageY, imageW,imageH);
    [self.scrollView insertSubview:imageView atIndex:0];
  }
 
}
 
- (NSArray *)imageViews{
 
  if (_imageViews == nil) {
    NSMutableArray *arr = [NSMutableArray array];
    for (int i = 0; i < self.images.count + 2; i++) {
      UIImageView *imageView = [[UIImageView alloc] init];
      CGFloat imageX = i * self.imgW;
      CGFloat imageY = 0;
      CGFloat imageW = self.imgW;
      CGFloat imageH = self.imgH;
      imageView.frame = CGRectMake(imageX, imageY, imageW,imageH);
      [self.scrollView insertSubview:imageView atIndex:0];
      [arr addObject:imageView];
    }
    _imageViews = arr;
  }
 
  return _imageViews;
 
}
 
- (void)setImages:(NSArray *)images{
 
  _images = images;
  self.imageCount = images.count;
  self.pageControl.numberOfPages = self.imageCount;
  [self addPics];
 
}
 
- (void)addPics{
 
  for (int i = 0; i < self.images.count + 2; i++) {
    UIImageView *imageView = self.imageViews[i];
    if (i == 0) {
      imageView.image = [self.images lastObject];
    }else if(i == self.images.count + 1){
      imageView.image = [self.images firstObject];
    }else{
      imageView.image = self.images[i - 1];
    }
  }
 
}
 
- (void)layoutSubviews{
 
  [super layoutSubviews];
  self.scrollView.frame = self.bounds;
  self.scrollView.contentSize = CGSizeMake((self.imageCount + 2) * self.imgW, 0);
  [self.scrollView setContentOffset:CGPointMake(self.imgW, 0) animated:NO];
 
}
 
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
 
  [self.timer invalidate];
  self.timer = nil;
}
 
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
 
  self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(nextImage) userInfo:nil repeats:YES];
  [[NSRunLoop currentRunLoop ] addTimer:self.timer forMode:NSRunLoopCommonModes];
 
}
 
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
 
  if (scrollView.contentOffset.x == self.imgW * (self.imageCount + 1)) {
    [self.scrollView setContentOffset:CGPointMake(self.imgW, 0) animated:NO];
  }else if(scrollView.contentOffset.x == 0){
    [self.scrollView setContentOffset:CGPointMake(self.imgW * (self.imageCount), 0) animated:NO];
  }
 
  self.pageControl.currentPage = (self.scrollView.contentOffset.x + self.imgW * 0.5f) / self.imgW - 1;
 
}
 
@end

以上就是使用UIScrollView实现图片的轮播的功能,如有疑问大家可以留言,也可以到本站社区留言讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

原文链接:http://blog.csdn.net/xyt8023y/article/details/50116571