Giter Site home page Giter Site logo

12207480 / typagercontroller Goto Github PK

View Code? Open in Web Editor NEW
1.4K 26.0 233.0 4.32 MB

page scroll view and controller,simple,high custom,and have many tabBar styles,,support Objective-C and swift

License: MIT License

Objective-C 92.44% Ruby 0.57% Swift 6.99%
pager-controller pager

typagercontroller's Introduction

TYPagerController v2.0

TYPagerController 简单,强大,高度定制,页面控制器,水平滚动内容和标题栏,包含多种barStyle。
TYPagerController v2.0 重构优化代码,分离出TYPagerViewLayout布局类,添加更多功能,更加强大,稳定,已经在项目中使用
如果还想使用以前的版本可以查看分支v1.0.6 和 pod 'TYPagerController', '~> 1.0.6'

  • TYPagerViewLayout 水平滚动页面的layout类,只需要initWithScrollView:即可实现水平滚动页面.
  • TYPagerView 包含TYPagerViewLayout的水平滚动页面View
  • TYPagerController 包含TYPagerViewLayout的水平滚动页面Controller。
  • TYTabPagerBar Pager的标题 tabBar
  • TYTabPagerView 包含TabBar的TYPagerView
  • TYTabPagerController 包含TabBar的TYPagerController

注意:获取数据后必须调用reloadData.
更详细的使用请看LovePlayNews项目

CocoaPods

pod 'TYPagerController'

Requirements

  • Xcode 7 or higher
  • iOS 7.0 or higher
  • ARC

ScreenShot

TYPagerBarStyle

New TYPagerBarStyleProgressElasticView
image

1 TYPagerBarStyleProgressBounceView
image

2 TYPagerBarStyleProgressView
image

3 TYPagerBarStyleCoverView
image image

4 TYPagerBarStyleNoneView
image

API

Class

  • TYPagerViewLayout
@interface TYPagerViewLayout<__covariant ItemType> : NSObject

@property (nonatomic, weak, nullable) id<TYPagerViewLayoutDataSource> dataSource;
@property (nonatomic, weak, nullable) id<TYPagerViewLayoutDelegate> delegate;

// strong,will control the delegate,don't set delegate on other place.
@property (nonatomic, strong, readonly) UIScrollView *scrollView;
// if viewcontroller's automaticallyAdjustsScrollViewInsets YES ,will cause frame problems, you can set YES, default YES
@property (nonatomic, assign) BOOL adjustScrollViewInset;

@property (nonatomic, assign, readonly) NSInteger countOfPagerItems;
@property (nonatomic, assign, readonly) NSInteger curIndex;// default -1

@property (nonatomic, strong, readonly) NSCache<NSNumber *,ItemType> *memoryCache;; // will cache pagerView,you can set countLimit
@property (nonatomic, assign) BOOL autoMemoryCache; // default YES

@property (nonatomic, assign) NSInteger prefetchItemCount;// preload left and right item's count , default 0

@property (nonatomic, assign, readonly) NSRange prefetchRange;
@property (nonatomic, assign, readonly) NSRange visibleRange;

@property (nonatomic, strong, nullable, readonly) NSArray<NSNumber *> * visibleIndexs;
@property (nonatomic, strong, nullable, readonly) NSArray<ItemType> * visibleItems;

// default YES, if NO,will not call delegate transitionFromIndex:toIndex:progress:,but will call transitionFromIndex:toIndex:
@property (nonatomic, assign) BOOL progressAnimateEnabel;

// default NO, when scroll visible range change will add item.If YES add item only when scroll animate end, suggest set prefetchItemCount 1 or more
@property (nonatomic, assign) BOOL addVisibleItemOnlyWhenScrollAnimatedEnd;

// default 0.5,when scroll progress percent will change index, only progressAnimateEnabel is NO or don't implement delegate transitionFromIndex: toIndex: progress:
@property (nonatomic, assign) CGFloat changeIndexWhenScrollProgress;
  • TYPagerView
@interface TYPagerView : UIView

@property (nonatomic, weak, nullable) id<TYPagerViewDataSource> dataSource;
@property (nonatomic, weak, nullable) id<TYPagerViewDelegate> delegate;
// pagerView's layout,don't set layout's dataSource to other
@property (nonatomic, strong, readonly) TYPagerViewLayout<UIView *> *layout;
@property (nonatomic, strong, readonly) UIScrollView *scrollView;

@property (nonatomic, assign, readonly) NSInteger countOfPagerViews;
@property (nonatomic, assign, readonly) NSInteger curIndex;// default -1

@property (nonatomic, assign, nullable, readonly) NSArray<UIView *> *visibleViews;

@property (nonatomic, assign) UIEdgeInsets contentInset;

//if not visible, prefecth, cache view at index, return nil
- (UIView *_Nullable)viewForIndex:(NSInteger)index;

// register && dequeue's usage like tableView
- (void)registerClass:(Class)Class forViewWithReuseIdentifier:(NSString *)identifier;
- (void)registerNib:(UINib *)nib forViewWithReuseIdentifier:(NSString *)identifier;
- (UIView *)dequeueReusableViewWithReuseIdentifier:(NSString *)identifier forIndex:(NSInteger)index;

// scroll to index
- (void)scrollToViewAtIndex:(NSInteger)index animate:(BOOL)animate;

// update data and layout,but don't reset propertys(curIndex,visibleDatas,prefechDatas)
- (void)updateData;

// reload data and reset propertys
- (void)reloadData;
@protocol TYTabPagerControllerDelegate <TYPagerControllerDelegate>

// configre collectionview cell
- (void)pagerController:(TYTabPagerController *)pagerController configreCell:(UICollectionViewCell *)cell forItemTitle:(NSString *)title atIndexPath:(NSIndexPath *)indexPath;

// transition frome cell to cell with animated
- (void)pagerController:(TYTabPagerController *)pagerController transitionFromeCell:(UICollectionViewCell *)fromCell toCell:(UICollectionViewCell *)toCell animated:(BOOL)animated;

// transition frome cell to cell with progress
- (void)pagerController:(TYTabPagerController *)pagerController transitionFromeCell:(UICollectionViewCell *)fromCell toCell:(UICollectionViewCell *)toCell progress:(CGFloat)progress;

@end
  • TYPagerController
@interface TYPagerController : UIViewController

@property (nonatomic, weak, nullable) id<TYPagerControllerDataSource> dataSource;
@property (nonatomic, weak, nullable) id<TYPagerControllerDelegate>   delegate;
// pagerController's layout,don't set layout's dataSource to other
@property (nonatomic, strong, readonly) TYPagerViewLayout<UIViewController *> *layout;
@property (nonatomic, weak, readonly) UIScrollView *scrollView;

@property (nonatomic, assign, readonly) NSInteger countOfControllers;
@property (nonatomic, assign, readonly) NSInteger curIndex;// default -1

@property (nonatomic, strong, nullable, readonly) NSArray<UIViewController *> *visibleControllers;

@property (nonatomic, assign) UIEdgeInsets contentInset;

//if not visible, prefecth, cache view at index, return nil
- (UIViewController *_Nullable)controllerForIndex:(NSInteger)index;

// register && dequeue's usage like tableView
- (void)registerClass:(Class)Class forControllerWithReuseIdentifier:(NSString *)identifier;
- (void)registerNib:(UINib *)nib forControllerWithReuseIdentifier:(NSString *)identifier;
- (UIViewController *)dequeueReusableControllerWithReuseIdentifier:(NSString *)identifier forIndex:(NSInteger)index;

// scroll to index
- (void)scrollToControllerAtIndex:(NSInteger)index animate:(BOOL)animate;

//  update data and layout,but don't reset propertys(curIndex,visibleDatas,prefechDatas)
- (void)updateData;

// reload data and reset propertys
- (void)reloadData;

##Usage Demo

  • TYTabPagerView
- (void)addTabPagerView {
    TYTabPagerView *pagerView = [[TYTabPagerView alloc]init];
    pagerView.tabBar.layout.barStyle = TYPagerBarStyleCoverView;
    pagerView.tabBar.progressView.backgroundColor = [UIColor lightGrayColor];
    pagerView.dataSource = self;
    pagerView.delegate = self;
    [self.view addSubview:pagerView];
    _pagerView = pagerView;
}

#pragma mark - TYTabPagerViewDataSource

- (NSInteger)numberOfViewsInTabPagerView {
    return _datas.count;
}

- (UIView *)tabPagerView:(TYTabPagerView *)tabPagerView viewForIndex:(NSInteger)index prefetching:(BOOL)prefetching {
    UIView *view = [[UIView alloc]initWithFrame:[tabPagerView.layout frameForItemAtIndex:index]];
    view.backgroundColor = [UIColor colorWithRed:arc4random()%255/255.0 green:arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:arc4random()%255/255.0];
    //NSLog(@"viewForIndex:%ld prefetching:%d",index,prefetching);
    return view;
}

- (NSString *)tabPagerView:(TYTabPagerView *)tabPagerView titleForIndex:(NSInteger)index {
    NSString *title = _datas[index];
    return title;
}
  • TYTabPagerController
@interface TabPagerControllerDemoController : TYTabPagerController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.title = @"TabPagerControllerDemoController";
    self.tabBar.layout.barStyle = TYPagerBarStyleProgressView;
    self.dataSource = self;
    self.delegate = self;
    
    [self loadData];
}

- (void)loadData {
    _datas = [datas copy];
    // must call reloadData
    [self reloadData];
}

#pragma mark - TYTabPagerControllerDataSource

- (NSInteger)numberOfControllersInTabPagerController {
    return _datas.count;
}

- (UIViewController *)tabPagerController:(TYTabPagerController *)tabPagerController controllerForIndex:(NSInteger)index prefetching:(BOOL)prefetching {
    if (index%3 == 0) {
        CustomViewController *VC = [[CustomViewController alloc]init];
        VC.text = [@(index) stringValue];
        return VC;
    }else if (index%3 == 1) {
        ListViewController *VC = [[ListViewController alloc]init];
        VC.text = [@(index) stringValue];
        return VC;
    }else {
        CollectionViewController *VC = [[CollectionViewController alloc]init];
        VC.text = [@(index) stringValue];
        return VC;
    }
}

- (NSString *)tabPagerController:(TYTabPagerController *)tabPagerController titleForIndex:(NSInteger)index {
    NSString *title = _datas[index];
    return title;
}

更多的使用方法 请查看 demo。

Contact

如果你发现bug,please pull reqeust me
如果你有更好的改进,please pull reqeust me

typagercontroller's People

Contributors

12207480 avatar zhengqi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

typagercontroller's Issues

切换childController时的性能问题

通过添加移除ChildController的方式调用page 子页面的生命周期方法,是有一定性能损耗的。可以用iphone4 ios7设备上尝试一下,有卡顿。我也没有更好的方案,不过生命周期对于很多场景来说还是很重要的。

发现一个Bug

我用的是iPhone4S,系统8.1.2. 当tabBar滑动最后一个后,再次往右边滑动,tabbar会选中倒数第二个cell(正常情况应该选中最后一个),用的测试程序就是从这里下载的demo.

自定collectionBar Nib 必须放在mainBundle下面

这种写法只能通过mainBundle的xib处理
_cellContainXib 这个属性 可以直接改成cellNib 传入一个UINib

    if (_cellContainXib) {
        UINib *nib = [UINib nibWithNibName:_cellId bundle:nil];
        [collectionView registerNib:nib forCellWithReuseIdentifier:_cellId];
    }else {
        [collectionView registerClass:_cellClass forCellWithReuseIdentifier:_cellId];
    }

单词拼写 与建议

*isProgressScrollEnabel --> isProgressScrollEnabled

  • reSize -> resize
  • TYPagerControllerDataSource- (NSInteger)numberOfControllersInPagerController;应该加上PagerController
  • - (void)configurePropertys --> - (void)configureProperties
  • #define kCollectionViewBarHieght 36
    #define kUnderLineViewHeight 2 用静态常量
  • - (void)addUnderLineView --> - (void)addUnderlineView

设置了delegate以后 标签的title就不见了

本身是一个viewController。

[self addChildViewController:self.pagerController];
[self.view addSubview:_pagerController.view];
_pagerController.view.frame = self.view.bounds;
_arrTitle = [[NSArray alloc]initWithObjects:@"最新",@"最热", nil];


    _pagerController = [[TYTabButtonPagerController alloc]init];

// _pagerController.delegate = self;
_pagerController.dataSource = self;
_pagerController.adjustStatusBarHeight = YES;
_pagerController.cellSpacing = 2KScreeScasle;
_pagerController.cellEdging = 10
KScreeScasle;
_pagerController.cellWidth = 70KScreeScasle;
_pagerController.normalTextFont = [UIFont systemFontOfSize:15
KScreeScasle];
_pagerController.selectedTextFont = [UIFont systemFontOfSize:15KScreeScasle];
_pagerController.barStyle = TYPagerBarStyleProgressBounceView;
_pagerController.progressColor = UIColorFromRGB(0xfc3047);
_pagerController.progressWidth = 40
KScreeScasle;
_pagerController.selectedTextColor = UIColorFromRGB(0xfc3047);

使用TYPagerController时bug

左右切换场景的控制器有时候会卡顿,然后滑动切换就失效了向左或者向右无法滑动切换,只能点击item切换,然后左右切换又好了,多次出现过 目前没有找到原因

每次滑动 我需要知道滑动到哪个位置。

每次滑动 我需要知道滑动到哪个位置。我需要一个block 来知道每次滑动当前的currentIndex。
场景描述:nav右上角有功能按钮,在不同页面功能按钮不一样,需要改变。
如果是我对您的代码理解不够,请简单说一下解决方案。
谢谢!!

切换动画、TYPagerControllerDelegate时机/次数

1.点击tab切换不支持pageViewController的动画切换。楼主是否会考虑增加该功能?scrollView的话可能要考虑维护三个页面(当前、左右),点击tab选项切换时用于动画显示。
2.TYPagerControllerDelegate中现有方法:- (void)pagerController:(TYPagerController *)pagerController transitionFromIndex:(NSInteger)formIndex toIndex:(NSInteger)toIndex progress:(CGFloat)progress;会在didScroll的时候多次调用,不适合做切换后的一些处理。是否考虑增加完成切换时的回调方法(只调用一次)。
TYPagerController功能已经很丰富,打算用起来。以上,只是使用您的TYPagerController时遇到的一些场景限制。希望框架越来越完善~

发现一个bug

img_0419
发现一个bug,dang当选中tab2,然后滑动到tab7并选中,在滑动惠tab2,此时tab2还是红色

在点击TYTabBar的某个选项无法动画切换TYPagerView问题。

在点击TYTabBar的某个选项无法动画切换TYPagerView问题。
原因:TYPagerViewLayout.m line:265
`/**
scroll to item at index
*/

  • (void)scrollToItemAtIndex:(NSInteger)index animate:(BOOL)animate {
    if (index < 0 || index >= _countOfPagerItems) {
    return;
    }
    [self scrollViewWillScrollToView:_scrollView animate:animate];
    [_scrollView setContentOffset:CGPointMake(index * CGRectGetWidth(_scrollView.frame),0) animated:NO];// 应改为:animated: animate
    [self scrollViewDidScrollToView:_scrollView animate:animate];
    }`

关于标题栏的建议,

首先下滑线最好和标题等宽,在滑动的过程中应该预估两个标题宽度的差距进行下划线长度动画显示,而不是先拉长再缩短,最好在滑动下边子控制器的时候让标题栏的动画保持和点击标题切换的动画一致(点击标题的时候(下划线几乎不动,标题栏滚动这种感觉和安卓原生的很像用户体验好些,),建议在标题栏的左右部分可以添加按钮:建议参考XTPageControl,他做的比较美观标题栏可以有多种样式:居左显示,居中显示,均分头部宽度功能,但是性能方面不是很好,如果考虑性能优化建议参考WMPageController,目前还是比较成熟的一个开源库。

自定义cell

如果实现自定义的cell ,一个UILable,一个UIImageView,我是继承与TYTabPagerController 还是TYPagerController 呢,谢谢

自定义样式问题

screen shot 2017-08-31 at 22 05 26

你好 如何实现 分页视图 为图中的效果? 在导航栏的最中间 ?

在Tabbar的上面添加自定义控件

您好,请教一个问题,如果我想在Tabbar的上面添加一个自定义的view,然后在滑动列表的时候让view向上滑动,当滑动到Tabbar时,Tabbar停在上面,请问您有什么好的思路呢?

delegate无法响应

调试方法如下: NSLog断点设置在TYTabPagerController.m内

  • (void)setDelegate:(id)delegate
    {
    [super setDelegate:delegate];
    _tabDelegateFlags.didSelectAtIndexPath = [self.delegate respondsToSelector:@selector(pagerController:didSelectAtIndexPath:)];
    NSLog(@"_tabDelegateFlags.didSelectAtIndexPath: %d",_tabDelegateFlags.didSelectAtIndexPath);
    }

会得到如下结果,导致delegate二次初始化后无法正确响应
2016-07-11 12:06:06.660 Pay@Table[18925:6885761] _tabDelegateFlags.didSelectAtIndexPath: 1
2016-07-11 12:06:06.661 Pay@Table[18925:6885761] _tabDelegateFlags.didSelectAtIndexPath: 0

计算滚动目标页面index错误.

不应该在scrollViewDidScroll中计算滚动目标页面的index,而是scrollViewDidEndDecelerating中计算.
(这个在你的demo中是没有出现问题的,但是一旦我只是想用pageViewController而不用那个上面的菜单,那暴露出来的两个代理方法调用时间就有问题了,我这样说不知道你能不能理解==)

已经提了PR给你,你看一下.

如果不对,请指正.

遇到了复用问题

我用的这种方式[pagerView.layout dequeueReusableItemWithReuseIdentifier:identifier forIndex:index]
但我想每一页view对应一组数据,但是当我翻到第三页的时候 会复用第一页的数据
我的解决方式是
NSString *identifier=[NSString stringWithFormat:@"%ld",index];
[_pageView.layout registerClass:[UIView class] forItemWithReuseIdentifier:identifier];
[pagerView.layout dequeueReusableItemWithReuseIdentifier:identifier forIndex:index]
这两句放在了一起,问题是解决了,但是想请教下有没有更好的解决方式

使用问题

在不直接继承的情况下,单独添加到界面上。 在使用- (void)pagerController:(TYTabPagerController *)pagerController didScrollToTabPageIndex:(NSInteger)index {} 方法后 会造成 title不显示。在继承情况下正常。

請教一下如何預先設定 scroll index

我在 viewDidLoad 裡面做 setupPagerController, 然後用[self.pagerController scrollToControllerAtIndex:self.selectedIndex animate:NO];
可是出來後仍然預設在page 0 , 請問大家是怎樣set的?

感谢

自己用了UIPageViewController走了很多坑,感觉还是ScorllView做容器比较好。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.