美文网首页
UIScrollView实现轮播图

UIScrollView实现轮播图

作者: Sh1mmer | 来源:发表于2019-06-19 15:21 被阅读0次

思路是将三个UIImageView放到scollview上,
在我们向左或向右滑动 在边缘时通过setContentOffset方法来实现
1.首先创建scrollview

    self.tempScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 200)];
    self.tempScrollView.contentSize = CGSizeMake(self.view.frame.size.width*3, 200);
    self.tempScrollView.contentOffset = CGPointMake(self.view.frame.size.width, 0);
    self.tempScrollView.delegate = self;
    self.tempScrollView.pagingEnabled = YES;
    [self.view addSubview:self.tempScrollView];

2.创建三个imageview并将它们放到scrollview上

_tempArr = @[@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10"];
self.index = _tempArr.count;
    for (NSInteger i = 0 ; i < 3; i++) {
        UIImageView *tempImage = [[UIImageView alloc] initWithFrame:CGRectMake(i*self.view.frame.size.width, 0, self.view.frame.size.width, 200)];
        tempImage.tag = 1000+i;
        [self.tempScrollView addSubview:tempImage];
        switch (i) {
                case 0:
                    //最后一张图
                    tempImage.image = [UIImage imageNamed:[nameArr lastObject]];
                    break;
                case 1:
                    //第一张图
                    tempImage.image = [UIImage imageNamed:[nameArr firstObject]];
                    break;
                case 2:
                    //第二张图
                    tempImage.image = [UIImage imageNamed:nameArr.count>1?nameArr[1]:nameArr[0]];
                    break;
                    
                default:
                    break;
            }
    }


3.实现协议

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    //self.temparr为图片数组
    if (scrollView.contentOffset.x/self.view.frame.size.width >=2) {
        self.tempScrollView.contentOffset = CGPointMake(self.view.frame.size.width, 0);
        self.index%_tempArr.count==_tempArr.count-1?(self.index = _tempArr.count):(self.index = self.index + 1);
        [self setImageName];
    }else if(scrollView.contentOffset.x <= 0){
        self.tempScrollView.contentOffset = CGPointMake(self.view.frame.size.width, 0);
        CGPointMake(self.view.frame.size.width, 0);
        self.index%_tempArr.count==1?(self.index = _tempArr.count):(self.index = self.index-1);
        [self setImageName];
    }
}
//滑动时改变图片的位置
- (void)setImageName{
    UIImageView *tempImage = [self.tempScrollView viewWithTag:1000];
    tempImage.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@",_tempArr[(self.index-1)%_tempArr.count]]];
    tempImage = [self.tempScrollView viewWithTag:1001];
    tempImage.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@",_tempArr[self.index%_tempArr.count]]];
    tempImage = [self.tempScrollView viewWithTag:1002];
    tempImage.image = [UIImage imageNamed:[NSString stringWithFormat:@"%@",_tempArr[(self.index+1)%_tempArr.count]]];
}
//解决滑动时卡顿问题
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    [self.tempScrollView setContentOffset:CGPointMake(self.view.frame.size.width, 0) animated:YES];
}

也可以添加nstimer来自动滑动

// 在手指触碰时停止计时器
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    [self timeOff];
}
//在手指离开时打开计时器
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    [self timeOn];
}
//通过滑动来更改图片位置
- (void)changeImage{
    
    [self.tempScrollView setContentOffset:CGPointMake(self.view.frame.size.width, 0) animated:YES];
    //如果感觉自动滚动速度过快,我们可以使用下面的代码来控制速度(这里的时间要小于timer时间 )
    self.tempScrollView.delegate = nil;
    [UIView animateWithDuration:1 animations:^{
        self.tempScrollView.contentOffset = CGPointMake(self.view.frame.size.width*2, 0);
    } completion:^(BOOL finished) {
        self.tempScrollView.delegate = self;
        self.tempScrollView.contentOffset = CGPointMake(self.view.frame.size.width, 0);
        self.index%self.tempArr.count==self.tempArr.count-1?(self.index = self.tempArr.count):(self.index = self.index + 1);
        [self setImageName];
    }];
}
//关闭计时器
- (void)timeOff{
    [self.timer invalidate];
    self.timer = nil;
}
//打开计时器
- (void)timeOn{
    self.timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(changeImage) userInfo:nil repeats:YES];
    
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}

我们在viewdidload方法中直接调用timeOn就可以打开计时器了

[self timeOn];

而且当我们快速滑动轮播图也不会出现卡顿

封装
.h

#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
typedef void(^SelectedBlock)(NSInteger index);
@interface CarouselView : UIScrollView
/// 图片名字数组
@property (nonatomic) NSArray *nameArr;
/// 点击图片回调
@property SelectedBlock selectedBlock;

@end

NS_ASSUME_NONNULL_END

#import "CarouselView.h"
#import <YYImage.h>
#import <YYWebImage.h>
@interface CarouselView ()<UIScrollViewDelegate>

@property NSInteger index;
@property NSTimer *timer;


@end

@implementation CarouselView

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.contentSize = CGSizeMake(self.frame.size.width*3, self.frame.size.height);
        self.contentOffset = CGPointMake(self.frame.size.width, 0);
        self.delegate = self;
        self.pagingEnabled = YES;
    }
    return self;
}

-(void)setNameArr:(NSArray *)nameArr{
    if (nameArr) {
        _nameArr = nameArr;
        for (NSInteger i = 0 ; i < 3; i++) {
            UIButton *tempBtn = [UIButton buttonWithType:UIButtonTypeCustom];
            tempBtn.frame = CGRectMake(i*self.frame.size.width, 0, self.frame.size.width, self.frame.size.height);
            tempBtn.tag = 1000+i;
            [tempBtn addTarget:self action:@selector(tapImage:) forControlEvents:UIControlEventTouchUpInside];
            [self addSubview:tempBtn];
            switch (i) {
                case 0:
                    //最后一张图
                    [tempBtn setBackgroundImage:[UIImage imageNamed:[nameArr lastObject]] forState:UIControlStateNormal];
                    break;
                case 1:
                    //第一张图
                    [tempBtn setBackgroundImage:[UIImage imageNamed:[nameArr firstObject]] forState:UIControlStateNormal];
                    break;
                case 2:
                    //第二张图
                    [tempBtn setBackgroundImage:[UIImage imageNamed:nameArr.count>1?nameArr[1]:nameArr[0]] forState:UIControlStateNormal];
                    break;
                    
                default:
                    break;
            }
        }
        self.index = _nameArr.count;
        [self timeOn];
    }
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    //self.nameArr为图片数组
    if (scrollView.contentOffset.x/self.frame.size.width >=2) {
        self.contentOffset = CGPointMake(self.frame.size.width, 0);
        self.index%_nameArr.count==_nameArr.count-1?(self.index = _nameArr.count):(self.index = self.index + 1);
        [self setImageName];
    }else if(scrollView.contentOffset.x <= 0){
        self.contentOffset = CGPointMake(self.frame.size.width, 0);
        self.index%_nameArr.count==1?(self.index = _nameArr.count):(self.index = self.index-1);
        [self setImageName];
    }
}
//滑动时改变图片的位置
- (void)setImageName{
    UIButton *tempBtn = [self viewWithTag:1000];
    [tempBtn setBackgroundImage:[UIImage imageNamed:[NSString stringWithFormat:@"%@",_nameArr[(self.index-1)%_nameArr.count]]] forState:UIControlStateNormal];
    
    
    tempBtn = [self viewWithTag:1001];
    [tempBtn setBackgroundImage:[UIImage imageNamed:[NSString stringWithFormat:@"%@",_nameArr[self.index%_nameArr.count]]] forState:UIControlStateNormal];
    
    
    tempBtn = [self viewWithTag:1002];
    [tempBtn setBackgroundImage:[UIImage imageNamed:[NSString stringWithFormat:@"%@",_nameArr[(self.index+1)%_nameArr.count]]] forState:UIControlStateNormal];
    
}
//解决滑动时卡顿问题
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    [self setContentOffset:CGPointMake(self.frame.size.width, 0) animated:YES];
}

// 在手指触碰时停止计时器
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    [self timeOff];
}
//在手指离开时打开计时器
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    [self timeOn];
}
//通过滑动来更改图片位置
- (void)changeImage{
    
    [self setContentOffset:CGPointMake(self.frame.size.width, 0) animated:YES];
    //如果感觉自动滚动速度过快,我们可以使用下面的代码来控制速度(这里的时间要小于timer时间 )
    self.delegate = nil;
    [UIView animateWithDuration:1 animations:^{
        self.contentOffset = CGPointMake(self.frame.size.width*2, 0);
    } completion:^(BOOL finished) {
        self.delegate = self;
        self.contentOffset = CGPointMake(self.frame.size.width, 0);
        self.index%self.nameArr.count==self.nameArr.count-1?(self.index = self.nameArr.count):(self.index = self.index + 1);
        [self setImageName];
    }];
}
//关闭计时器
- (void)timeOff{
    [self.timer invalidate];
    self.timer = nil;
}
//打开计时器
- (void)timeOn{
    self.timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(changeImage) userInfo:nil repeats:YES];
    
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}

- (void)tapImage:(UIButton *)tap{
    if (self.selectedBlock) {
        self.selectedBlock(self.index%self.nameArr.count+1);
    }
}
@end

调用

    CarouselView *tempView = [[CarouselView alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 200)];
    tempView.nameArr = _tempArr;
    tempView.selectedBlock = ^(NSInteger index) {
        NSLog(@"选择图片:%ld",index);
    };
    [self.view addSubview:tempView];

相关文章

网友评论

      本文标题:UIScrollView实现轮播图

      本文链接:https://www.haomeiwen.com/subject/qgpofctx.html