一、想法思路
首先scrollview的contentSize为3个屏幕的宽度,3个UIImageView一次排列在scrollview上,默认scrollview.contentOffset.x为一个屏幕宽度,每滚动一次,更新3个imageView的图片,更新完图片再调用scrollRectToVisible: animated:方法使scrollview的contentOffset.x滚回到一个屏幕的宽度,第二个imageView永远保持在中间的位置,只是图片换了,每次滑动后持续上述的操作,这样就能不停轮播切换图片的效果,当然这只是一种思路,你用其他办法能实现这个效果也可以。
说明:此处并无针对实际项目作出相关处理,只提供思路,实际情况请根据项目情况自行处理。
二、代码
我们先来看.h
#import <UIKit/UIKit.h>
@class TestBannerView;
@interface TestBannerView : UIView
@property (nonatomic, strong) NSArray *sources;
@property (nonatomic, assign) float scrollTime;
@end
然后是.m文件
#define BannerWidth self.bounds.size.width
#define BannerHight self.bounds.size.height
#import "TestBannerView.h"
@interface TestBannerView ()< UIScrollViewDelegate >
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UIPageControl *pageControl;
@property (nonatomic, strong) NSTimer *scrollTimer;
@property (nonatomic, assign) int currentPage;
@property (nonatomic, strong) UIImageView *previousImageView;
@property (nonatomic, strong) UIImageView *currentImageView;
@property (nonatomic, strong) UIImageView *nextImageView;
@end
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
[self initSubView];
}
- (void)initSubView
{
[self addSubview:self.scrollView];
[self addSubview:self.pageControl];
[_scrollView addSubview:self.previousImageView];
[_scrollView addSubview:self.currentImageView];
[_scrollView addSubview:self.nextImageView];
}
- (void)setSources:(NSArray *)sources
{
_sources = [sources copy];
if (_sources.count <= 1)
{
_pageControl.hidden = YES;
_scrollView.contentSize = CGSizeMake(BannerWidth, BannerHight);
}else{
_pageControl.hidden = NO;
_pageControl.numberOfPages = _sources.count;
_scrollView.contentSize = CGSizeMake(BannerWidth * 3, BannerHight);
}
[self updateImage];
}
- (void)updateImage
{
if (_currentPage >= (int)_sources.count) _currentPage = 0;
if (_currentPage < 0) {
_currentPage = (int)_sources.count-1;
}
int previous = (_currentPage - 1) < 0 ? (int)_sources.count - 1 : _currentPage - 1;
int next = (_currentPage + 1) >= (int)_sources.count ? 0 : _currentPage + 1;
if (_sources.count > 0) {
_pageControl.currentPage = _currentPage;
NSString *preStr = [_sources objectAtIndex:previous] ;
NSString *currentStr = [_sources objectAtIndex:_currentPage];
NSString *nextStr = [_sources objectAtIndex:next];
_previousImageView.image = [UIImage imageNamed:preStr];
_currentImageView.image = [UIImage imageNamed:currentStr];
_nextImageView.image = [UIImage imageNamed:nextStr];
}
[_scrollView scrollRectToVisible:CGRectMake(BannerWidth, 0, BannerWidth, BannerHight) animated:NO];
_scrollTime = _scrollTime > 0 ? _scrollTime : 1.5;
[self startTimer];
}
- (void)startTimer
{
if (_scrollTimer) {
[_scrollTimer invalidate];
_scrollTimer = nil;
}
_scrollTimer = [NSTimer timerWithTimeInterval:_scrollTime target:self selector:@selector(imageScroll:) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:_scrollTimer forMode:NSDefaultRunLoopMode];
}
- (void)imageScroll:(NSTimer *)timer
{
if (!_scrollView.isDragging) {
[_scrollView scrollRectToVisible:CGRectMake(2*BannerWidth, 0, BannerWidth, BannerHight) animated:YES];
_currentPage++;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self updateImage];
});
}
}
// UIScrollViewDelegate
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
if (_scrollTimer) {
[_scrollTimer invalidate];
_scrollTimer = nil;
}
if (scrollView.contentOffset.x>=BannerWidth*2)
_currentPage++;
else if (scrollView.contentOffset.x<BannerWidth)
_currentPage--;
[self updateImage];
}
// Set/Get
- (UIScrollView *)scrollView
{
if (!_scrollView) {
_scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
_scrollView.pagingEnabled = YES;
_scrollView.showsHorizontalScrollIndicator = NO;
_scrollView.bounces = NO;
_scrollView.delegate = self;
}
return _scrollView;
}
- (UIPageControl *)pageControl
{
if (!_pageControl) {
_pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, BannerHight-50, BannerWidth, 50)];
_pageControl.currentPageIndicatorTintColor = [UIColor redColor];
_pageControl.enabled = NO;
_pageControl.pageIndicatorTintColor = [UIColor blueColor];
}
return _pageControl;
}
- (UIImageView *)previousImageView
{
if (!_previousImageView) {
_previousImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, BannerWidth, BannerHight)];
}
return _previousImageView;
}
- (UIImageView *)currentImageView
{
if (!_currentImageView) {
_currentImageView = [[UIImageView alloc]initWithFrame:CGRectMake(BannerWidth, 0, BannerWidth, BannerHight)];
}
return _currentImageView;
}
- (UIImageView *)nextImageView
{
if (!_nextImageView) {
_nextImageView = [[UIImageView alloc]initWithFrame:CGRectMake(BannerWidth * 2, 0, BannerWidth, BannerHight)];
}
return _nextImageView;
}
// 调用
TestBannerView *banner = [[TestBannerView alloc]initWithFrame:CGRectMake(0, 64, WIDTH, 100)];
banner.backgroundColor = [UIColor yellowColor];
banner.sources = @[@"face1",@"face2",@"face3",@"face4"];
[self.view addSubview:banner];