/JXCategoryView

A powerful and easy to use category view (segmentedcontrol, segmentview, pagingview, pagerview, pagecontrol) (腾讯新闻、今日头条、QQ音乐、网易云音乐、京东、爱奇艺、腾讯视频、淘宝、天猫、简书、微博等所有主流APP分类切换滚动视图)

Primary LanguageObjective-CMIT LicenseMIT

platform languages cocoapods support

A powerful and easy to use category view (segmentedcontrol, segmentview, pagingview, pagerview, pagecontrol) (腾讯新闻、今日头条、QQ音乐、网易云音乐、京东、爱奇艺、腾讯视频、淘宝、天猫、简书、微博等所有主流APP分类切换滚动视图)

与其他的同类三方库对比的优点:

  • 使用协议封装指示器逻辑,可以为所欲为的自定义指示器效果;
  • 提供更加全面丰富、高度自定义的效果;
  • 使用子类化管理cell样式,逻辑更清晰,扩展更简单;

Swift版本

如果你在找Swift版本,请点击查看JXSegmentedView

效果预览

指示器效果预览

说明 Gif
LineView
LineView延长
LineView延长+偏移
LineView🌈彩虹风格
DotLineView点线效果
BallView QQ黏性红点
TriangleView 三角形底部
TriangleView 三角形顶部
BackgroundView椭圆形
BackgroundView椭圆形+阴影
BackgroundView长方形
BackgroundView遮罩有背景
BackgroundView遮罩无背景
BackgroundView渐变色
ImageView底部(小船)
ImageView背景(最佳男歌手)
ImageView滚动效果(足球)
混合使用

以下均支持上下位置切换: JXCategoryIndicatorLineView、JXCategoryIndicatorImageView、JXCategoryIndicatorBallView、JXCategoryIndicatorTriangleView

Cell样式效果预览

说明 Gif
颜色渐变
大小缩放
大小缩放+底部锚点
大小缩放+顶部锚点
大小缩放+字体粗细
大小缩放+点击动画
大小缩放+cell宽度缩放
TitleImage_Top
TitleImage_Left
TitleImage_Bottom
TitleImage_Right
cell图文混用
Image
数字
红点
多行文本
多行富文本
Cell背景色渐变
分割线

特殊效果预览

说明 Gif
数据源过少
averageCellSpacingEnabled默认为YES
数据源过少
averageCellSpacingEnabled为NO
SegmentedControl
参考SegmentedControlViewController
导航栏使用
参考NaviSegmentedControlViewController
嵌套使用
参考NestViewController
个人主页(上下左右滚动、header悬浮)
参考PagingViewController
更多样式请点击查看JXPagingView库
垂直列表滚动
参考VerticalListViewController
高仿腾讯视频
(背景色异常是录屏软件bug)
垂直缩放(仿网易圈圈、脉脉首页)
参考ScrollZoomViewController
数据源刷新&列表数据加载
参考LoadDataListContainerViewController

要求

  • iOS 8.0+
  • Xcode 9+
  • Objective-C

安装

手动

Clone代码,把Sources文件夹拖入项目,#import "JXCategoryView.h",就可以使用了;

CocoaPods

target '<Your Target Name>' do
    pod 'JXCategoryView'
end

先执行pod repo update,再执行pod install

结构图

使用

JXCategoryTitleView使用示例

1.初始化JXCategoryTitleView

self.categoryView = [[JXCategoryTitleView alloc] initWithFrame:CGRectMake(0, 0, WindowsSize.width, 50)];
self.categoryView.delegate = self;
[self.view addSubview:self.categoryView];

2.配置JXCategoryTitleView的属性

self.categoryView.titles = @[@"螃蟹", @"麻辣小龙虾", @"苹果"...]
self.categoryView.titleColorGradientEnabled = YES;

3.添加指示器

JXCategoryIndicatorLineView *lineView = [[JXCategoryIndicatorLineView alloc] init];
lineView.indicatorLineViewColor = [UIColor redColor];
lineView.indicatorLineWidth = JXCategoryViewAutomaticDimension;
self.categoryView.indicators = @[lineView];

4.实现JXCategoryViewDelegate代理

//点击选中或者滚动选中都会调用该方法。适用于只关心选中事件,不关心具体是点击还是滚动选中的。
- (void)categoryView:(JXCategoryBaseView *)categoryView didSelectedItemAtIndex:(NSInteger)index;

//点击选中的情况才会调用该方法
- (void)categoryView:(JXCategoryBaseView *)categoryView didClickSelectedItemAtIndex:(NSInteger)index;

//滚动选中的情况才会调用该方法
- (void)categoryView:(JXCategoryBaseView *)categoryView didScrollSelectedItemAtIndex:(NSInteger)index;

//正在滚动中的回调
- (void)categoryView:(JXCategoryBaseView *)categoryView scrollingFromLeftIndex:(NSInteger)leftIndex toRightIndex:(NSInteger)rightIndex ratio:(CGFloat)ratio;

//自定义contentScrollView点击选中切换效果
- (void)categoryView:(JXCategoryBaseView *)categoryView didClickedItemContentScrollViewTransitionToIndex:(NSInteger)index;

contentScrollView列表容器使用示例

直接使用UIScrollView自定义

因为代码比较分散,而且代码量也比较多,所有不推荐使用该方法。要正确使用需要注意的地方比较多,尤其对于刚接触iOS的同学来说不太友好。

不直接贴代码了,具体点击LoadDataListCustomViewController查看源代码了解。

作为替代,官方使用&强烈推荐使用下面这种方式👇👇👇。

JXCategoryListContainerView封装类使用示例

JXCategoryListContainerView是对列表视图高度封装的类,具有以下优点:

  • 相对于直接使用UIScrollView自定义,封装度高、代码集中、使用简单;
  • 列表懒加载:当显示某个列表的时候,才进行列表初始化。而不是一次性加载全部列表,性能更优;

1.初始化JXCategoryListContainerView

self.listContainerView = [[JXCategoryListContainerView alloc] initWithDelegate:self];
[self.view addSubview:self.listContainerView];
//关联cotentScrollView,关联之后才可以互相联动!!!
self.categoryView.contentScrollView = self.listContainerView.scrollView;

2.实现JXCategoryListContainerViewDelegate代理方法

//返回列表的数量
- (NSInteger)numberOfListsInlistContainerView:(JXCategoryListContainerView *)listContainerView {
    return self.titles.count;
}
//返回遵从`JXCategoryListContentViewDelegate`协议的实例
- (id<JXCategoryListContentViewDelegate>)listContainerView:(JXCategoryListContainerView *)listContainerView initListForIndex:(NSInteger)index {
    return [[ListViewController alloc] init];
}

3.列表实现JXCategoryListContainerViewDelegate代理方法

不管列表是UIView还是UIViewController都可以,提高使用灵活性,更便于现有的业务接入。

// 返回列表视图
// 如果列表是VC,就返回VC.view
// 如果列表是View,就返回View自己
- (UIView *)listView {
    return self.view;
}

//可选使用,列表显示的时候调用
- (void)listDidAppear {}

//可选使用,列表消失的时候调用
- (void)listDidDisappear {}

4.将关键事件告知JXCategoryListContainerView

在下面两个JXCategoryViewDelegate代理方法里面调用对应的代码,一定不要忘记这一条❗️❗️❗️

//传递didClickSelectedItemAt事件给listContainerView,必须调用!!!
- (void)categoryView:(JXCategoryBaseView *)categoryView didClickSelectedItemAtIndex:(NSInteger)index {
    [self.listContainerView didClickSelectedItemAtIndex:index];
}

//传递scrolling事件给listContainerView,必须调用!!!
- (void)categoryView:(JXCategoryBaseView *)categoryView scrollingFromLeftIndex:(NSInteger)leftIndex toRightIndex:(NSInteger)rightIndex ratio:(CGFloat)ratio {
    [self.listContainerView scrollingFromLeftIndex:leftIndex toRightIndex:rightIndex ratio:ratio selectedIndex:categoryView.selectedIndex];
}

具体点击LoadDataListContainerViewController查看源代码了解

JXCategoryListCollectionContainerView封装类使用示例

  • 有了JXCategoryListContainerView为什么还要JXCategoryListCollectionContainerView类呢?

    • 因为JXCategoryListContainerView内部使用的是UIScrollView,当所有列表都加载出来后,所有的列表都被addSubview到UIScrollView上面了。所以,在视图内存这一块会比较大,对于一些列表复杂且数量多的应用,内存表现不太好。
  • JXCategoryListCollectionContainerView的优势

    • 只有当前显示的列表才会被addSubview,视图内存表现良好;
    • 因为内部使用UICollectionView,在api设计上更加简洁;

具体使用示例,点击参看JXCategoryListCollectionContainerView使用示例

指示器样式自定义

  • 需要继承JXCategoryIndicatorProtocol协议,点击参看JXCategoryIndicatorProtocol
  • 提供了继承JXCategoryIndicatorProtocol协议的基类JXCategoryIndicatorComponentView,里面提供了许多基础属性。点击参看JXCategoryIndicatorComponentView
  • 自定义指示器,请参考已实现的指示器视图,多尝试、多思考,再有问题请提Issue或加入反馈QQ群

Cell自定义

  • 任何子类化需求,view、cell、cellModel三个都要子类化,即使某个子类cell什么事情都不做。用于维护继承链,以免以后子类化都不知道要继承谁了;
  • 如果你想完全自定义cell里面的内容,那就继承JXCategoryIndicatorView、JXCategoryIndicatorCell、JXCategoryIndicatorCellModel,就像JXCategoryTitleView、JXCategoryTitleCell、JXCategoryTitleCellModel那样去做;
  • 如果你只是在父类进行一些微调,那就继承目标view、cell、cellModel,对cell原有控件微调、或者加入新的控件皆可。就像JXCategoryTitleImageView系列、JXCategoryTitleAttributeView系列那样去做;
  • Cell自定义,请参考已实现的cell样式,多尝试、多思考,再有问题请提Issue或加入反馈QQ群

常见问题和答案

❗️❗️❗️这里面包含了许多常见问题和答案,使用之前请务必浏览此文档,或者遇到问题先看此文档❗️❗️❗️

常见问题和答案

常用属性说明

常用属性说明文档地址

更新记录

  • 2018.8.21 发布1.0.0版本,更新内容:使用POP(面向协议编程)重构指示器视图;迁移指南
  • 2018.8.22 发布1.0.1版本,更新内容:删除zoomEnabled,新增titleLabelZoomEnabled、imageZoomEnabled;
  • 2018.8.23 发布1.0.2版本,更新内容:添加cellWidthZoomEnabled实现腾讯视频效果;
  • 2018.8.24 发布1.0.3版本,更新内容:添加垂直列表滚动效果、指示器添加verticalMargin属性、JXCategoryViewDelegate代理方法优化;
  • 2018.9.4 发布1.0.4版本,更新内容:修复bug、添加cell图文混用示例;
  • 2018.12.19 发布1.1.7版本,更新内容:添加JXCategoryListContainerView,高度封装列表逻辑,支持懒加载列表,提升初始化性能;
  • 2019.1.24 发布1.2.2版本,更新内容:非兼容更新接口- (BOOL)selectCellAtIndex:(NSInteger)index selectedType:(JXCategoryCellSelectedType)selectedType,自定义有用到该接口的请及时更新。

补充

如果刚开始使用JXCategoryView,当开发过程中需要支持某种特性时,请务必先搜索使用文档或者源代码。确认是否已经实现支持了想要的特性。请别不要文档和源代码都没有看,就直接提问,这对于大家都是一种时间浪费。如果没有支持想要的特性,欢迎提Issue讨论,或者自己实现提一个PullRequest。

该仓库保持随时更新,对于主流新的分类选择效果会第一时间支持。使用过程中,有任何建议或问题,可以通过以下方式联系我:
邮箱:317437084@qq.com
QQ群: 112440151

喜欢就star❤️一下吧

License

JXCategoryView is released under the MIT license.