iOS xib自动布局自定义简易轮播控件

先看效果  ZFBannerView

话不多说,直接上代码。


首先.h文件代码

//

//  ZFBannerView.h

//

//  Created by BiBiMan on 2021/4/23.

//  Copyright © 2021 BiBiMan. All rights reserved.

//

#import   

#import "ZFProtocolDock.h"/**< 协议坞*/

NS_ASSUME_NONNULL_BEGIN

typedef void(^SelectBlock)(NSInteger index);

@interface ZFBannerView :UIView

+ (instancetype)nib;

@property (nonatomic, assign) CGFloat itemCornerRadius;/**< item视图圆角半径*/

@property (nonatomic, assign) UIEdgeInsets itemEdgeInsets;/**< item视图内边距-控制item的位置*/

@property (nonatomic, assign) NSTimeInterval duration;/**< 轮播间隔时间:默认2s*/

@property (nonatomic, strong) UIColor *indicatorNormalColor;/**< 分页指示器默认颜色*/

@property (nonatomic, strong) UIColor *indicatorSelectedColor;/**< 分页指示器当前(选中)颜色*/

@property (nonatomic, assign) UIViewContentMode itemContentModel;/**< 图片填充模式*/

@property (nonatomic, strong) NSArray * _Nullable images;/**< 图片数组*/

@property (nonatomic, weak) id delegate;/**< 点击item代理回调,在协议坞自定义*/

@property (nonatomic, copy) SelectBlock handleBlock;/**< 点击block回调*/

@end

NS_ASSUME_NONNULL_END

然后.m文件代码

//

//  ZFBannerView.m

//

//  Created by BiBiMan on 2021/4/23.

//  Copyright © 2021 BiBiMan. All rights reserved.

//

#import "ZFBannerView.h"

#define PlaceHolderImage @"jiazaitupian"   /**< 占位图切图*/

@interface ZFBannerView ()

@property (nonatomic, weak) IBOutlet UIScrollView *mainScrollView;/**< 滚动视图*/

@property (nonatomic, weak) IBOutlet UIPageControl *mainPageControl;/**< 分页指示器*/

//MARK: - 自动布局约束部分

@property (nonatomic, weak) IBOutlet NSLayoutConstraint *itemTopLayout;/**< 上边距*/

@property (nonatomic, weak) IBOutlet NSLayoutConstraint *itemLeftLayout;/**< 左边距*/

@property (nonatomic, weak) IBOutlet NSLayoutConstraint *itemBottomLayout;/**< 下边距*/

@property (nonatomic, weak) IBOutlet NSLayoutConstraint *itemRightLayout;/**< 右边距*/

@property (nonatomic, weak) IBOutlet NSLayoutConstraint *leftItemLeadingLayout;/**< 左item视图左边距*/

@property (nonatomic, weak) IBOutlet NSLayoutConstraint *rightItemLeadingLayout;/**< 右item视图左边距*/

//MARK: - 视图类属性

@property (nonatomic, weak) IBOutlet UIImageView *leftItem;/**< 左item视图*/

@property (nonatomic, weak) IBOutlet UIImageView *middleItem;/**< 中间item视图*/

@property (nonatomic, weak) IBOutlet UIImageView *rightItem;/**< 右item视图*/

//MARK: - 行为属性

@property (nonatomic, assign) NSInteger currentIndex;

//MARK: - 计时属性

@property (nonatomic, strong) NSTimer *playTimer;

@end

@implementation ZFBannerView

+ (instancetype )nib {

    Class objCls = [ZFBannerView class];

    NSString*nibName =NSStringFromClass(objCls);

    return [[[NSBundle bundleForClass:objCls] loadNibNamed:nibName owner:nil options:nil] firstObject];

}

- (void)awakeFromNib {

    [super awakeFromNib];

    self.backgroundColor = UIColor.whiteColor;

    //初始化设置

    self.duration=2;

    self.itemEdgeInsets = UIEdgeInsetsZero;

    self.itemCornerRadius = 0;

    self.currentIndex = 0;

    self.itemContentModel = UIViewContentModeScaleAspectFill;

    self.mainPageControl.numberOfPages = 0;

}

- (void)layoutSubviews {

    [super layoutSubviews];

    if(@available(iOS11.0, *)) {

        self.mainScrollView.contentSize = self.mainScrollView.contentLayoutGuide.layoutFrame.size;

    }else{

        CGFloat itemWidth = CGRectGetWidth(self.frame);

        CGFloatitemHeight =CGRectGetWidth(self.frame);

        self.mainScrollView.contentSize=CGSizeMake(itemWidth*3, itemHeight);

    }

}

- (void)setItemEdgeInsets:(UIEdgeInsets)itemEdgeInsets {

    _itemEdgeInsets= itemEdgeInsets;

    self.itemTopLayout.constant= itemEdgeInsets.top;

    self.itemLeftLayout.constant= itemEdgeInsets.left;

    self.itemBottomLayout.constant= itemEdgeInsets.bottom;

    self.itemRightLayout.constant= itemEdgeInsets.right;

    self.leftItemLeadingLayout.constant= itemEdgeInsets.left;

    self.rightItemLeadingLayout.constant= itemEdgeInsets.left;

}

- (void)setItemCornerRadius:(CGFloat)itemCornerRadius {

    _itemCornerRadius= itemCornerRadius;

    self.leftItem.layer.cornerRadius= itemCornerRadius;

    self.middleItem.layer.cornerRadius= itemCornerRadius;

    self.rightItem.layer.cornerRadius= itemCornerRadius;

}

- (void)setIndicatorNormalColor:(UIColor*)indicatorNormalColor {

    _indicatorNormalColor= indicatorNormalColor;

    self.mainPageControl.pageIndicatorTintColor= indicatorNormalColor;

}

- (void)setIndicatorSelectedColor:(UIColor*)indicatorSelectedColor {

    _indicatorSelectedColor= indicatorSelectedColor;

    self.mainPageControl.currentPageIndicatorTintColor= indicatorSelectedColor;

}

- (void)setItemContentModel:(UIViewContentMode)itemContentModel {

    _itemContentModel= itemContentModel;

    self.leftItem.contentMode= itemContentModel;

    self.middleItem.contentMode= itemContentModel;

    self.rightItem.contentMode= itemContentModel;

}

- (void)setImages:(NSArray *)images {

    if(!images.count) {

        self.userInteractionEnabled = NO;

        self.mainPageControl.numberOfPages = 0;

        [self rollBackToOriginPositon];

        return;

    }

    _images= images;

    self.mainPageControl.numberOfPages = images.count;

    [self rollBackToOriginPositon];

    [self refreshItemImage];

}

//MARK: - ScrollViewDelegate

#pragma mark - UIScrollViewDelegate <-滚动代理*****

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {

    //即将拖拽

    [selfstopPlay];

}

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {

    //结束拖拽,即将滚动减速

    if(!decelerate) {

        //拖拽位置未变化-无减速

        [self startPlay];

    }

}

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {

    //已经结束滚动减速-进行无缝切换

    CGFloat x = scrollView.contentOffset.x;

    CGFloat index = x /CGRectGetWidth(scrollView.frame);

    if(index >1) {

        self.currentIndex = [self nextIndex];

    }else if(index <1) {

        self.currentIndex = [self lastIndex];

    }

    self.mainPageControl.currentPage = self.currentIndex;

    [self switchToMiddleItem];

    if(!self.playTimer.valid) {

        //防止重复创建计时器

        [self startPlay];

    }

}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {

    [self scrollViewDidEndDecelerating:scrollView];

}

#pragma mark- *****滚动代理->

//MARK: - 回滚到初始位置

- (void)rollBackToOriginPositon {

    [self layoutIfNeeded];

    self.currentIndex = 0;

    self.mainPageControl.currentPage = 0;

    CGFloat itemWidth = self.mainScrollView.contentSize.width/3.0f;

    CGPoint offset =CGPointMake(itemWidth,0);

    [self.mainScrollView setContentOffset:offset animated:NO];

    [self startPlay];

}

//MARK: - 滚动到右侧图片

- (void)scrollToNextItemWithanimated:(BOOL)animated {

    CGFloat itemWidth = self.mainScrollView.contentSize.width/3.0;

    CGPoint offset =CGPointMake(itemWidth *2,0);

    [self.mainScrollView setContentOffset:offsetanimated:animated];

}

//MARK: - 无缝切换到中间图片

- (void)switchToMiddleItem {

    [self refreshItemImage];

    CGFloat itemWidth = self.mainScrollView.contentSize.width/3.0;

    CGPoint offset =CGPointMake(itemWidth *1,0);

    [self.mainScrollView setContentOffset:offset animated:NO];

}

//MARK: - 防止数据溢出nextIndex

- (NSInteger)nextIndex {

    NSInteger index =self.currentIndex+1;

    if(index >=self.images.count) {

        index =0;

    }

    return index;

}

//MARK: - 防止数据溢出lastIndex

- (NSInteger)lastIndex {


    NSInteger index =self.currentIndex-1;

    if(index <0) {

        index =self.images.count-1;

    }

    if(!self.images.count) {

        index =0;

    }

    return index;

}

//MARK: - 更新item的图片

- (void)refreshItemImage {

    if(!self.images.count) {

        [self setImage:PlaceHolderImage forItem:self.leftItem];

        [self setImage:PlaceHolderImage forItem:self.middleItem];

        [self setImage:PlaceHolderImage forItem:self.rightItem];

    }else{

        [self setImage:self.images[[self lastIndex]] forItem:self.leftItem];

        [self setImage:self.images[self.currentIndex] forItem:self.middleItem];

        [self setImage:self.images[[self nextIndex]] forItem:self.rightItem];

    }


}

//MARK: - 根据数组图片类型做兼容展示

- (void)setImage:(id)imageforItem:(UIImageView*)item {

    if ([image isKindOfClass:[UIImage class]]) {

        [item setImage:image];

    }else if ([image isKindOfClass:[NSString class]]) {

        NSString*imageStr = (NSString*)image;

        if([imageStr hasPrefix:@"http"]) {

            //网络图片

            [itemyy_setImageWithURL:[NSURLURLWithString:imageStr]placeholder:[UIImageimageNamed:PlaceHolderImage]];

        }else{

            UIImage*imgObj = [UIImage imageNamed:image];

            if(!imgObj) {

                imgObj = [UIImage imageNamed:PlaceHolderImage];

            }

            [item setImage:imgObj];

        }

    }else{

        [item setImage:[UIImage imageNamed:PlaceHolderImage]];

    }

}

- (void)startPlay {

    //销毁计时器

    [self stopPlay];

    if(self.images.count) {

        //初始化计时器

        self.playTimer = [NSTimer timerWithTimeInterval:self.duration target:self selector:@selector(playing) userInfo:nil repeats:YES];

        //启动计时器

        [[NSRunLoop currentRunLoop] addTimer:self.playTimer forMode:NSRunLoopCommonModes];

    }

}

//MARK: - 销毁计时器

- (void)stopPlay {

    [_playTimer invalidate];

    _playTimer = nil;

}

//MARK: - 轮播

- (void)playing {

    [self scrollToNextItemWithanimated:YES];

}

- (UIView *)superview {

    UIView*view = [supersuperview];

    if(!view) {

        [self stopPlay];

    }

    return view;

}

//点击了banner

- (IBAction)didSelectItem:(UITapGestureRecognizer *)tap {

    NSLog(@"%d-%@",(int)self.currentIndex,self.images[self.currentIndex]);

    //执行代理回调

    if([self.delegaterespondsToSelector:@selector(didSelectItemForIndex:)]) {

        [self.delegate didSelectItemForIndex:self.currentIndex];

    }

    //执行block回调

    if (self.handleBlock) {

        self.handleBlock(self.currentIndex);

    }

}

@end

最后.xib文件代码(转成Source Code)

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

ZFBannerView Git Demo

你可能感兴趣的:(iOS xib自动布局自定义简易轮播控件)