版本記錄
版本號(hào) | 修改時(shí)間 |
---|---|
V1.0 | 2017.04.18 |
前言
很多APP都有很多圖片輪播banner直秆,是用戶了解app的重要接口邑狸,也是app發(fā)布活動(dòng)或者消息的很好選擇诡必。比如每年雙11或者其他節(jié)日蒿赢,天貓等app都會(huì)在banner上加入很多活動(dòng)接口润樱,以便用戶盡快獲得活動(dòng)的信息。banner的實(shí)現(xiàn)有很多第三方框架羡棵,我自己封裝了一個(gè)圖片輪播器github壹若,有什么不對(duì)的地方希望大家能給我指出,謝謝皂冰。
詳細(xì)設(shè)計(jì)
我們先看一下代碼組織結(jié)構(gòu)店展。
接著看詳細(xì)的代碼
1. AppDelegate.m
#import "AppDelegate.h"
#import "JJBannerVC.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
JJBannerVC *bannerVC = [[JJBannerVC alloc] init];
self.window.rootViewController = bannerVC;
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
- (void)applicationWillTerminate:(UIApplication *)application {
}
@end
2.JJBannerVC.h
#import <UIKit/UIKit.h>
@interface JJBannerVC : UIViewController
@end
3.JJBannerVC.m
#import "JJBannerVC.h"
#import "JJBannerView.h"
#import "Masonry.h"
@interface JJBannerVC ()
@property (nonatomic, strong) JJBannerView *bannerView;
@end
@implementation JJBannerVC
#pragma mark - Override Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
self.bannerView = [[JJBannerView alloc] initWithFrame:CGRectZero];
[self.view addSubview:self.bannerView];
self.bannerView.imageArr = [self loadImageArr];
}
- (void)viewWillLayoutSubviews
{
[self.bannerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.offset(0);
}];
}
#pragma mark - Object Private Function
- (NSArray *)loadImageArr
{
NSMutableArray *imageArrM = [NSMutableArray array];
for (NSInteger i = 0; i < 5; i ++) {
NSString *imageStr = [NSString stringWithFormat:@"Home_Scroll_%02zd",i+1];
UIImage *image = [UIImage imageNamed:imageStr];
[imageArrM addObject:image];
}
return imageArrM.copy;
}
@end
4.JJBannerView.h
#import <UIKit/UIKit.h>
@interface JJBannerView : UIView
@property (nonatomic, strong) NSArray *imageArr;
@end
5. JJBannerView.m
#import "JJBannerView.h"
#import "JJBannerFlowLayout.h"
#import "Masonry.h"
#import "JJBannerCollectionViewCell.h"
#define kJJBannerViewSectionCount (100)
@interface JJBannerView () <UICollectionViewDelegate, UICollectionViewDataSource>
@property (nonatomic, strong) UICollectionView *collectionView;
@property (nonatomic, strong) UIPageControl *pageControl;
@property (nonatomic, strong) NSTimer *timer;
@end
@implementation JJBannerView
static NSString * const cellIdentify = @"cellIdentify";
#pragma mark - Overide Base Function
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self setupCollectionView];
[self setupPageControl];
[self setupTimer];
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
[self.pageControl mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.offset(-40);
make.centerX.equalTo(self);
}];
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.offset(0);
}];
}
- (void)removeFromSuperview
{
[super removeFromSuperview];
[self.timer invalidate];
}
#pragma mark - Object Private Function
- (void)setupCollectionView
{
JJBannerFlowLayout *flowLayout = [[JJBannerFlowLayout alloc] init];
self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:flowLayout];
[self addSubview:self.collectionView];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
[self.collectionView registerClass:[JJBannerCollectionViewCell class] forCellWithReuseIdentifier:cellIdentify];
self.collectionView.pagingEnabled = YES;
self.collectionView.bounces = NO;
self.collectionView.showsHorizontalScrollIndicator = NO;
self.collectionView.showsVerticalScrollIndicator = NO;
}
- (void)setupPageControl
{
UIPageControl *pageControl = [[UIPageControl alloc] init];
pageControl.currentPageIndicatorTintColor = [UIColor darkGrayColor];
pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
[self addSubview:pageControl];
self.pageControl = pageControl;
}
- (void)setupTimer
{
self.timer = [NSTimer timerWithTimeInterval:2 target:self selector:@selector(nextPage) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}
#pragma mark - Object Base Function
- (void)nextPage
{
NSInteger page = self.pageControl.currentPage;
NSIndexPath *scrollIndexPath = nil;
// 如果是最后一張圖片
if (page == self.imageArr.count - 1) {
scrollIndexPath = [NSIndexPath indexPathForItem:0 inSection:kJJBannerViewSectionCount/2 + 1];
}
else {
scrollIndexPath = [NSIndexPath indexPathForItem:page + 1 inSection:kJJBannerViewSectionCount/2];
}
[self.collectionView scrollToItemAtIndexPath:scrollIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
}
#pragma mark - UICollectionViewDelegate, UICollectionViewDataSource>
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
self.timer.fireDate = [NSDate distantFuture];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
self.timer.fireDate = [NSDate dateWithTimeIntervalSinceNow:2];
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
[self scrollViewDidEndDecelerating:scrollView];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSInteger page = scrollView.contentOffset.x / scrollView.bounds.size.width;
NSInteger sectionNum = page / self.imageArr.count;
NSInteger itemNUm = page % self.imageArr.count;
if (sectionNum == kJJBannerViewSectionCount/2) {
return;
}
NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForItem:itemNUm inSection:kJJBannerViewSectionCount/2];
[self.collectionView scrollToItemAtIndexPath:scrollIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
NSInteger page = (scrollView.contentOffset.x/scrollView.bounds.size.width) + 0.499;
NSInteger pageNO = page % self.imageArr.count;
self.pageControl.currentPage = pageNO;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return kJJBannerViewSectionCount;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.imageArr.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
JJBannerCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentify forIndexPath:indexPath];
cell.indexPath = indexPath;
return cell;
}
#pragma mark - Getter & Setter Function
- (void)setImageArr:(NSArray *)imageArr
{
_imageArr = imageArr;
[self.collectionView reloadData];
self.pageControl.numberOfPages = self.imageArr.count;
[self layoutIfNeeded];
NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForItem:0 inSection:kJJBannerViewSectionCount/2];
[self.collectionView scrollToItemAtIndexPath:scrollIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
}
@end
6.JJBannerFlowLayout.h
#import <UIKit/UIKit.h>
@interface JJBannerFlowLayout : UICollectionViewFlowLayout
@end
7.JJBannerFlowLayout.m
#import "JJBannerFlowLayout.h"
@implementation JJBannerFlowLayout
- (void)prepareLayout
{
[super prepareLayout];
self.itemSize = self.collectionView.bounds.size;
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.minimumLineSpacing = 0;
self.minimumInteritemSpacing = 0;
}
@end
8.JJBannerCollectionViewCell.h
#import <UIKit/UIKit.h>
@interface JJBannerCollectionViewCell : UICollectionViewCell
@property (nonatomic, strong) NSIndexPath *indexPath;
@end
9. JJBannerCollectionViewCell.m
#import "JJBannerCollectionViewCell.h"
#import "Masonry.h"
@interface JJBannerCollectionViewCell ()
@property (nonatomic, strong) UIImageView *imageView;
@end
@implementation JJBannerCollectionViewCell
#pragma mark - Override Base Function
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self setupUI];
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
[self.imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.offset(0);
}];
}
#pragma mark - Object Base Function
- (void)setupUI
{
UIImageView *imageView = [[UIImageView alloc] init];
[self.contentView addSubview:imageView];
self.imageView = imageView;
}
#pragma mark - Getter & Setter Function
- (void)setIndexPath:(NSIndexPath *)indexPath
{
_indexPath = indexPath;
self.imageView.image = [UIImage imageNamed:@(indexPath.item).description];
}
@end
設(shè)計(jì)結(jié)果
我們直接看下邊的gif圖。
可以看見實(shí)現(xiàn)了圖片輪播的效果秃流。
后記
這個(gè)東西很簡單赂蕴,但是我還是自己寫了一遍,有些東西很長時(shí)間不寫就忘記不少了舶胀,但是看看還是能很快的撿起來概说,相信大家和我都是一樣的。希望我寫的這個(gè)小東西能對(duì)大家有用嚣伐,再次謝謝大家對(duì)我的支持席怪。