| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- #import "TYTabPagerController.h"
- #import "TYTabTitleViewCell.h"
- #import <QMUIKit/QMUIKit.h>
- @interface TYTabPagerController ()<UICollectionViewDelegateFlowLayout, UICollectionViewDataSource>
- {
- struct {
- unsigned int titleForIndex :1;
- }_tabDataSourceFlags;
- struct {
- unsigned int configreReusableCell :1;
- unsigned int didSelectAtIndexPath :1;
- unsigned int didScrollToTabPageIndex :1;
- unsigned int transitionFromeCellAnimated :1;
- unsigned int transitionFromeCellProgress :1;
- }_tabDelegateFlags;
- }
- // views
- //@property (nonatomic, weak) UIView *pagerBarView;
- @property (nonatomic, weak) UICollectionView *collectionViewBar;
- @property (nonatomic, weak) UIView *progressView;
- @property (nonatomic ,assign) Class cellClass;
- @property (nonatomic ,assign) BOOL cellContainXib;
- @property (nonatomic ,strong) NSString *cellId;
- @end
- //#define kCollectionViewBarHieght 50 + 44
- //tabbar高度
- #define kUnderLineViewHeight 1
- #define _pageBarWidth (kScreenW - 10 * 2)
- @implementation TYTabPagerController
- - (instancetype)initWithCoder:(NSCoder *)aDecoder
- {
- if (self = [super initWithCoder:aDecoder]) {
- [self configireTabPropertys];
-
- }
- return self;
- }
- - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
- {
- if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
-
- [self configireTabPropertys];
- }
- return self;
- }
- - (void)configireTabPropertys
- {
- _kCollectionViewBarHieght = 50 + 44;
-
- _animateDuration = 0.1;
- _barStyle = TYPagerBarStyleNoneView;
- _normalTextFont = [UIFont systemFontOfSize:16];
- _selectedTextFont = [UIFont boldSystemFontOfSize:20];
- _cellSpacing = 0;
- _cellEdging = 0;
- _progressHeight = kUnderLineViewHeight;
- _progressEdging = 0;
- _progressWidth = 0;
- self.changeIndexWhenScrollProgress = 1.0;
- self.contentTopEdging = _kCollectionViewBarHieght;
- }
- #pragma mark - life cycle
- - (void)viewDidLoad {
- [super viewDidLoad];
- // Do any additional setup after loading the view.
- // add pager bar
- [self addPagerBarView];
- // add title views
- [self addCollectionViewBar];
- // add progress view
- [self addUnderLineView];
- }
- - (void)addPagerBarView
- {
- //首页顶部背景颜色
- _bgTopImgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"mg_hm_topBgImgView"]];
- _bgTopImgView.frame = CGRectMake(0, 0, kScreenW, _kCollectionViewBarHieght);
- [self.view addSubview:_bgTopImgView];
-
- _pagerBarView = [[UIView alloc]initWithFrame:CGRectMake(0,0,CGRectGetWidth(self.view.frame), self.kCollectionViewBarHieght)];
- [self.view addSubview:_pagerBarView];
-
- }
- //在这里添加控件
- - (void)addCollectionViewBar
- {
-
-
-
- UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];
- layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
- UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(20,0, CGRectGetWidth(self.view.frame), _pagerBarView.height) collectionViewLayout:layout];
- collectionView.showsHorizontalScrollIndicator = NO;
- collectionView.showsVerticalScrollIndicator = NO;
- collectionView.delegate = self;
- collectionView.backgroundColor = kYellowColor;
- collectionView.dataSource = self;
- [_pagerBarView addSubview:collectionView];
- //tabbar title
-
- _collectionViewBar = collectionView;
- if (_cellContainXib) {
- UINib *nib = [UINib nibWithNibName:_cellId bundle:nil];
- [collectionView registerNib:nib forCellWithReuseIdentifier:_cellId];
- }else {
- [collectionView registerClass:_cellClass forCellWithReuseIdentifier:_cellId];
- }
- }
- // layout tab view
- - (void)layoutTabPagerView
- {
- ((UICollectionViewFlowLayout *)_collectionViewBar.collectionViewLayout).minimumLineSpacing = 0;
- // CGFloat collectionViewEaging = _barStyle != TYPagerBarStyleCoverView ? _collectionLayoutEdging : (_collectionLayoutEdging > 0 ? _collectionLayoutEdging : -_progressEdging+_cellSpacing);
- ((UICollectionViewFlowLayout *)self.collectionViewBar.collectionViewLayout).sectionInset = UIEdgeInsetsMake(5,0,0,0);
- //tabbar 位置
-
- // if(isIPhoneX())
- // {
- // _pagerBarView.frame = CGRectMake(0,self.collectionLayoutEdging ,CGRectGetWidth(self.view.frame),_kCollectionViewBarHieght);
- // }
- // else
- // {
- _pagerBarView.frame = CGRectMake(0,MG_TOP_MARGIN,CGRectGetWidth(self.view.frame),_kCollectionViewBarHieght);
- // }
-
- CGFloat collectionbar_w =0;
- for (int i =0; i<[self.dataSource numberOfControllersInPagerController]; i++)
- {
- NSString *title = [self.dataSource pagerController:self titleForIndex:i];
- CGFloat width = [self boundingSizeWithString:title font:_selectedTextFont constrainedToSize:CGSizeMake(300, 100)].width+_cellEdging*1.5;
- if (width > _pageBarWidth/7)
- {
- collectionbar_w +=width;
- }else
- collectionbar_w +=_pageBarWidth/7;
- }
- if (collectionbar_w > _pageBarWidth)
- {
- collectionbar_w =_pageBarWidth;
- }
- // _collectionViewBar.frame = CGRectMake(10,0,collectionbar_w,_kCollectionViewBarHieght);
-
- // _collectionViewBar.y += 10;
- // int x = CGRectGetMinXHorizontallyCenterInParentRect(self.view.frame,_collectionViewBar.frame);
- // _collectionViewBar.x = x;
-
- self.pagerBarView.frame = CGRectMake(0, isIPhoneX() ? 30 : 10, kScreenW - self.collectionLayoutEdging , kRealValue(44));
- self.collectionViewBar.frame = self.pagerBarView.bounds;
- }
- //添加下划线
- - (void)addUnderLineView
- {
- UIView *underLineView = [[UIView alloc]init];
- underLineView.hidden = (_barStyle == TYPagerBarStyleNoneView);
- underLineView.layer.cornerRadius = 2;
- if (_barStyle != TYPagerBarStyleCoverView) {
- [_collectionViewBar addSubview:underLineView];
- }else{
- underLineView.layer.zPosition = -1;
- [_collectionViewBar insertSubview:underLineView atIndex:0];
- }
- _progressView = underLineView;
- }
- #pragma mark - setter
- - (void)setBarStyle:(TYPagerBarStyle)barStyle
- {
- _barStyle = barStyle;
- _progressView.hidden = (_barStyle == TYPagerBarStyleNoneView);
- }
- - (void)setDelegate:(id<TYTabPagerControllerDelegate>)delegate
- {
- [super setDelegate:delegate];
- _tabDelegateFlags.configreReusableCell = [self.delegate respondsToSelector:@selector(pagerController:configreCell:forItemTitle:atIndexPath:)];
- _tabDelegateFlags.didSelectAtIndexPath = [self.delegate respondsToSelector:@selector(pagerController:didSelectAtIndexPath:)];
- _tabDelegateFlags.didScrollToTabPageIndex = [self.delegate respondsToSelector:@selector(pagerController:didScrollToTabPageIndex:)];
- _tabDelegateFlags.transitionFromeCellAnimated = [self.delegate respondsToSelector:@selector(pagerController:transitionFromeCell:toCell:animated:)];
- _tabDelegateFlags.transitionFromeCellProgress = [self.delegate respondsToSelector:@selector(pagerController:transitionFromeCell:toCell:progress:)];
- }
- - (void)setDataSource:(id<TYPagerControllerDataSource>)dataSource
- {
- [super setDataSource:dataSource];
-
- _tabDataSourceFlags.titleForIndex = [self.dataSource respondsToSelector:@selector(pagerController:titleForIndex:)];
- NSAssert(_tabDataSourceFlags.titleForIndex, @"TYPagerControllerDataSource pagerController:titleForIndex: not impletement!");
- }
- #pragma mark - public
- - (void)reloadData
- {
- [_collectionViewBar reloadData];
-
- [super reloadData];
- }
- // update tab subviews frame
- - (void)updateContentView
- {
- [super updateContentView];
- [self layoutTabPagerView];
- [self setUnderLineFrameWithIndex:1 animated:NO];
- [self tabScrollToIndex:1 animated:NO];
- }
- - (void)registerCellClass:(Class)cellClass isContainXib:(BOOL)isContainXib
- {
- _cellClass = cellClass;
- _cellId = NSStringFromClass(cellClass);
- _cellContainXib = isContainXib;
- }
- - (CGRect)cellFrameWithIndex:(NSInteger)index
- {
- if (index >= self.countOfControllers) {
- return CGRectZero;
- }
- UICollectionViewLayoutAttributes * cellAttrs = [_collectionViewBar layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0]];
- return cellAttrs.frame;
- }
- - (UICollectionViewCell *)cellForIndex:(NSInteger)index
- {
- if (index >= self.countOfControllers) {
- return nil;
- }
- return [_collectionViewBar cellForItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0]];
- }
- - (void)tabScrollToIndex:(NSInteger)index animated:(BOOL)animated
- {
- if (_tabDelegateFlags.didScrollToTabPageIndex) {
- [self.delegate pagerController:self didScrollToTabPageIndex:index];
- }
-
- if (index < self.countOfControllers) {
- [_collectionViewBar scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:index inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:animated];
- }
- }
- #pragma mark - private
- // set up progress view frame
- //设置下划线
- - (void)setUnderLineFrameWithIndex:(NSInteger)index animated:(BOOL)animated
- {
- if (_progressView.isHidden || self.countOfControllers == 0) {
- return;
- }
- CGRect cellFrame = [self cellFrameWithIndex:index];
- CGFloat progressEdging = _progressWidth > 0 ? (cellFrame.size.width - _progressWidth)/2 : _progressEdging;
- CGFloat progressX = cellFrame.origin.x+progressEdging;
- CGFloat progressY = _barStyle == TYPagerBarStyleCoverView ? (cellFrame.size.height - _progressHeight)/2:(cellFrame.size.height - _progressHeight);
- progressY += 3;
- CGFloat width = cellFrame.size.width-2*progressEdging;
- if (animated) {
- [UIView animateWithDuration:_animateDuration animations:^{
- _progressView.frame = CGRectMake(progressX + 13, progressY+3, width - 26, _progressHeight);
- }];
- }else {
- _progressView.frame = CGRectMake(progressX + 13, progressY+3, width - 26, _progressHeight);
- }
- }
- - (void)setUnderLineFrameWithfromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress
- {
- if (_progressView.isHidden || self.countOfControllers == 0) {
- return;
- }
-
- CGRect fromCellFrame = [self cellFrameWithIndex:fromIndex];
- CGRect toCellFrame = [self cellFrameWithIndex:toIndex];
-
- CGFloat progressFromEdging = _progressWidth > 0 ? (fromCellFrame.size.width - _progressWidth)/2 : _progressEdging;
- CGFloat progressToEdging = _progressWidth > 0 ? (toCellFrame.size.width - _progressWidth)/2 : _progressEdging;
- CGFloat progressY = _barStyle == TYPagerBarStyleCoverView ? (toCellFrame.size.height - _progressHeight)/2 + 3:(toCellFrame.size.height - _progressHeight) + 3;
- progressY += 3;
- CGFloat progressX, width;
-
- if (_barStyle == TYPagerBarStyleProgressBounceView) {
- if (fromCellFrame.origin.x < toCellFrame.origin.x) {
- if (progress <= 0.5) {
- progressX = fromCellFrame.origin.x + progressFromEdging ;
- width = (toCellFrame.size.width-progressToEdging+progressFromEdging+_cellSpacing)*2*progress + fromCellFrame.size.width-2*progressFromEdging ;
- }else {
- progressX = fromCellFrame.origin.x + progressFromEdging + (fromCellFrame.size.width-progressFromEdging+progressToEdging+_cellSpacing)*(progress-0.5)*2 ;
- width = CGRectGetMaxX(toCellFrame)-progressToEdging - progressX ;
- }
- }else {
- if (progress <= 0.5) {
- progressX = fromCellFrame.origin.x + progressFromEdging - (toCellFrame.size.width-progressToEdging+progressFromEdging+_cellSpacing)*2*progress;
- width = CGRectGetMaxX(fromCellFrame) - progressFromEdging - progressX ;
- }else {
- progressX = toCellFrame.origin.x + progressToEdging ;
- width = (fromCellFrame.size.width-progressFromEdging+progressToEdging + _cellSpacing)*(1-progress)*2 + toCellFrame.size.width - 2*progressToEdging ;
- }
- }
- }else {
- progressX = (toCellFrame.origin.x+progressToEdging-(fromCellFrame.origin.x+progressFromEdging))*progress+fromCellFrame.origin.x+progressFromEdging ;
- width = (toCellFrame.size.width-2*progressToEdging)*progress + (fromCellFrame.size.width-2*progressFromEdging)*(1-progress) ;
- }
- _progressView.frame = CGRectMake(progressX + 13,progressY+3, width - 26, _progressHeight);//下划线宽度
-
- }
- #pragma mark - override transition
- - (void)transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex animated:(BOOL)animated
- {
- UICollectionViewCell *fromCell = [self cellForIndex:fromIndex];
- UICollectionViewCell *toCell = [self cellForIndex:toIndex];
-
- if (![self isProgressScrollEnabel]) {
- // if isn't progressing
- if (_tabDelegateFlags.transitionFromeCellAnimated) {
- [self.delegate pagerController:self transitionFromeCell:fromCell toCell:toCell animated:animated];
- }
- [self setUnderLineFrameWithIndex:toIndex animated:fromCell && animated ? animated: NO];
- }
- [self tabScrollToIndex:toIndex animated:toCell ? YES : fromCell && animated ? animated: NO];
- }
- - (void)transitionFromIndex:(NSInteger)fromIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress
- {
- UICollectionViewCell *fromCell = (TYTabTitleViewCell *)[self cellForIndex:fromIndex];
- UICollectionViewCell *toCell = (TYTabTitleViewCell *)[self cellForIndex:toIndex];
-
- if (_tabDelegateFlags.transitionFromeCellProgress) {
- [self.delegate pagerController:self transitionFromeCell:fromCell toCell:toCell progress:progress];
- }
-
- [self setUnderLineFrameWithfromIndex:fromIndex toIndex:toIndex progress:progress];
- }
- #pragma mark - UICollectionViewDataSource
- - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
- {
- return [self.dataSource numberOfControllersInPagerController];
- }
- - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
- {
-
- UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:_cellId forIndexPath:indexPath];
-
- if (_tabDataSourceFlags.titleForIndex) {
- NSString *title = [self.dataSource pagerController:self titleForIndex:indexPath.item];
- if (_tabDelegateFlags.configreReusableCell) {
- [self.delegate pagerController:self configreCell:cell forItemTitle:title atIndexPath:indexPath];
- }
-
- if (_tabDelegateFlags.transitionFromeCellAnimated) {
- [self.delegate pagerController:self transitionFromeCell:(indexPath.item == self.curIndex ? nil : cell) toCell:(indexPath.item == self.curIndex ? cell : nil) animated:NO];
- }
-
- }
-
- return cell;
-
- }
- #pragma mark - UICollectionViewDelegateFlowLayout
- - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
- {
- [self moveToControllerAtIndex:indexPath.item animated:YES];
- if (_tabDelegateFlags.didSelectAtIndexPath) {
- [self.delegate pagerController:self didSelectAtIndexPath:indexPath];
- }
- }
- - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
- {
- // if(false)
- // {
- // return CGSizeMake(_pageBarWidth/3,CGRectGetHeight(_collectionViewBar.frame) - 10);
- // }
- NSString *title = [self.dataSource pagerController:self titleForIndex:indexPath.item];
- CGFloat width = [self boundingSizeWithString:title font:_selectedTextFont constrainedToSize:CGSizeMake(300, 100)].width+_cellEdging*1.5;
- if (width > _pageBarWidth/7)
- {
- return CGSizeMake(width,CGRectGetHeight(_collectionViewBar.frame) - 10);
- }
- return CGSizeMake(_pageBarWidth/7,CGRectGetHeight(_collectionViewBar.frame) - 10);
- }
- // text size
- - (CGSize)boundingSizeWithString:(NSString *)string font:(UIFont *)font constrainedToSize:(CGSize)size
- {
- CGSize textSize = CGSizeZero;
-
- #if (__IPHONE_OS_VERSION_MIN_REQUIRED && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0)
-
- if (![string respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
- // below ios7
- textSize = [string sizeWithFont:font
- constrainedToSize:size
- lineBreakMode:NSLineBreakByWordWrapping];
- }
- else
- #endif
- {
- //iOS 7
- CGRect frame = [string boundingRectWithSize:size options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{ NSFontAttributeName:font } context:nil];
- textSize = CGSizeMake(frame.size.width, frame.size.height + 1);
- }
-
- return textSize;
- }
- @end
|