【干货】每个APP都用得上的SegmentView

JXCategoryView.png

腾讯新闻今日头条、QQ音乐、网易云音乐、京东、爱奇艺、淘宝、天猫、简书、微博等所有主流APP分类切换滚动视图

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

  • 使用POP(Protocol Oriented Programming面对协议编程)封装指示器逻辑,可以为所欲为的自定义指示器效果;
  • 提供更加全面丰富的效果,交互更加顺畅;
  • 使用子类化管理cell样式,逻辑更清晰,扩展更简单;

Github地址

下载源码,一睹为快!JXCategoryView

效果预览

指示器效果预览

说明 Gif
指示器LineView
LineView.gif
指示器LineView京东风格
JDLineStyle.gif
指示器LineView爱奇艺风格
IQIYILineStyle.gif
指示器EllipseLayer
BackgroundEllipseLayer.gif
指示器EllipseLayer遮罩
TitleMask.gif
指示器EllipseLayer遮罩 (阴影)
BackgroundViewShadow.gif
指示器ImageView(小船)
IndicatorImageView.gif
指示器滚动效果(足球)
Football.gif
QQ黏性红点
QQBall.gif
三角形底部
TriangleBottom.gif
三角形顶部
TriangleTop.gif
文字遮罩(无背景视图)
TitleMaskNoBackgroundView.gif
背景指示图
BackgroundImageView.gif
矩形指示图
Rectangle.gif
混合使用
Mixed.gif
自定义Indicator示例-点线
IndicatorCustomizeGuide.gif

Cell样式效果预览

说明 Gif
颜色渐变
TitleColorGradient.gif
大小缩放
Zoom.gif
分割线
SeparatorLine.gif
TitleImage_Top
TitleImageTop.gif
TitleImage_Left
TitleImageLeft.gif
TitleImage_Bottom
TitleImageBottom.gif
TitleImage_Right
TitleImageRight.gif
TitleImage_OnlyImage
TitleImageOnlyImage.gif
图文混用
CellMixed.gif
自定义-数字
Number.gif
自定义cell-红点
CellRedDot.gif
自定义cell-背景色渐变
CellBackgroundColorGradient.gif
腾讯视频效果
TXVedio.gif
自定义cell示例-多行+富文本
AttributeView.gif

特殊效果预览

说明 Gif
SegmentedControl
SegmentedControl.gif
导航栏使用
SegmentedControlNavi.gif
个人主页(上下左右滚动、header悬浮)
UserProfile.gif
嵌套使用
Nest.gif
垂直列表滚动
高仿腾讯视频
(背景色异常是录屏软件bug
VerticalList.gif
数据源刷新&列表数据加载 示例
LoadData.gif

要求

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

安装

手动

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

CocoaPods

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

结构图

JXCategoryViewStructure.png
  • 指示器样式自定义:使用POP(Protocol Oriented Programming面对协议编程)封装指示器逻辑,只要遵从JXCategoryIndicatorProtocol协议,就可以实现你的指示器效果。参考:JXCategoryIndicatorLineView;
  • Cell样式自定义:使用子类化,基类搭建基础,子类实现特殊效果。便于代码管理,功能扩展;参考:JXCategoryNumberView;

特殊说明

  • 自定义:即使提供了灵活扩展,我的源码也不可能满足所有情况,建议大家可以通过fork仓库,维护自己的一套效果。也可以直接拖入源文件进行修改。
  • 个人主页效果:上下左右滚动且HeaderView悬浮的实现,用的是我写的这个库JXPagingView
  • 垂直列表滚动:参考demo工程的VerticalListViewController,未做功能封装,参考里面的代码做,多注意注释,就可以实现了。

POP说明

通过将指示器的行为抽象出来,再通过JXCategoryIndicatorProtocol协议进行约束。这样指示器效果就可以无限扩展,为所欲为的添加指示器了,不再受上一个版本继承的束缚了。更多POP内容,推荐喵神的文章面向协议编程与 Cocoa 的邂逅

常用属性说明

JXCategoryView常用属性说明

属性 说明
defaultSelectedIndex 默认选中的index,用于初始化时指定选中某个index
selectedIndex 只读属性,当前选中的index
cellWidth cell的宽度,默认:JXCategoryViewAutomaticDimension
cellSpacing cell之间的间距,默认20
cellWidthIncrement cell宽度的补偿值,默认0
averageCellWidthEnabled 当cell内容总宽度小于JXCategoryBaseView的宽度,是否将cellWidth均分。默认为YES。
contentScrollView 需要关联的contentScrollView,内部监听contentOffset

Cell样式常用属性说明

属性 说明
titleColor titleLabel未选中颜色 默认:[UIColor blackColor]
titleSelectedColor titleLabel选中颜色 默认:[UIColor redColor]
titleFont titleLabel的字体 默认:[UIFont systemFontOfSize:15]
titleColorGradientEnabled title的颜色是否渐变过渡 默认:NO
titleLabelMaskEnabled titleLabel是否遮罩过滤 默认:NO
titleLabelZoomEnabled titleLabel是否缩放 默认:NO
titleLabelZoomScale citleLabel缩放比例 默认:1.2
imageZoomEnabled imageView是否缩放 默认:NO
imageZoomScale imageView缩放比例 默认:1.2
separatorLineShowEnabled cell分割线是否展示 默认:NO (颜色、宽高可以设置)
JXCategoryTitleImageType 图片所在位置:上面、左边、下面、右边 默认:左边

指示器常用属性说明

属性 说明
JXCategoryIndicatorComponentView.componentPosition 指示器的位置 默认:Bottom
JXCategoryIndicatorComponentView.scrollEnabled 手势滚动、点击切换的时候,是否允许滚动,默认YES
JXCategoryIndicatorLineView.lineStyle 普通、京东、爱奇艺效果 默认:Normal
JXCategoryIndicatorLineView.lineScrollOffsetX 爱奇艺效果专用,line滚动时x的偏移量,默认为10;
JXCategoryIndicatorLineView.indicatorLineWidth 默认JXCategoryViewAutomaticDimension(与cellWidth相等)
JXCategoryIndicatorLineView.indicatorLineViewHeight 默认:3
JXCategoryIndicatorLineView.indicatorLineViewCornerRadius 默认JXCategoryViewAutomaticDimension (等于self.indicatorLineViewHeight/2)
JXCategoryIndicatorLineView.indicatorLineViewColor 默认为[UIColor redColor]
JXCategoryIndicatorTriangleView.triangleViewSize 默认:CGSizeMake(14, 10)
JXCategoryIndicatorTriangleView.triangleViewColor 默认为[UIColor redColor]
JXCategoryIndicatorImageView.indicatorImageView 设置image
JXCategoryIndicatorImageView.indicatorImageViewRollEnabled 是否允许滚动,默认:NO
JXCategoryIndicatorImageView.indicatorImageViewSize 默认:CGSizeMake(30, 20)
JXCategoryIndicatorBackgroundView.backgroundViewWidth 默认JXCategoryViewAutomaticDimension(与cellWidth相等)
JXCategoryIndicatorBackgroundView.backgroundViewWidthIncrement 宽度增量补偿,因为backgroundEllipseLayer一般会比实际内容大一些。默认10
JXCategoryIndicatorBackgroundView.backgroundViewHeight 默认JXCategoryViewAutomaticDimension(与cell高度相等)
JXCategoryIndicatorBackgroundView.backgroundViewCornerRadius 默认JXCategoryViewAutomaticDimension(即backgroundViewHeight/2)
JXCategoryIndicatorBackgroundView.backgroundViewColor 默认为[UIColor redColor]
JXCategoryIndicatorBallView.ballViewSize 默认:CGSizeMake(15, 15)
JXCategoryIndicatorBallView.ballScrollOffsetX 小红点的偏移量 默认:20
JXCategoryIndicatorBallView.ballViewColor 默认为[UIColor redColor]

可以多个IndicatorView搭配使用,但是效果需要自己把控,效果不是越多越好。参考混合使用;

使用

//1、初始化JXCategoryTitleView
self.categoryView = [[JXCategoryTitleView alloc] initWithFrame:CGRectMake(0, 0, WindowsSize.width, categoryViewHeight)];
self.categoryView.delegate = self;

//2、添加并配置指示器
//lineView
JXCategoryIndicatorLineView *lineView = [[JXCategoryIndicatorLineView alloc] init];
lineView.indicatorLineViewColor = [UIColor redColor];
lineView.indicatorLineWidth = JXCategoryViewAutomaticDimension;
//backgroundView
JXCategoryIndicatorBackgroundView *backgroundView = [[JXCategoryIndicatorBackgroundView alloc] init];
backgroundView.backgroundViewColor = [UIColor redColor];
backgroundView.backgroundViewWidth = JXCategoryViewAutomaticDimension;
titleCategoryView.indicators = @[lineView, backgroundView];

//3、绑定contentScrollView。self.scrollView的初始化细节参考源码。
self.categoryView.contentScrollView = self.scrollView;
[self.view addSubview:self.categoryView];
  • 单个cell刷新:比如红点示例里面,调用- (void)reloadCell:(NSUInteger)index
  • 所有状态重置:数据源、属性配置有变动时(比如从服务器拉取回来数据),需要调用reloadData方法刷新状态。

指示器样式自定义

仓库自带:JXCategoryIndicatorLineView、JXCategoryIndicatorTriangleView、JXCategoryIndicatorImageView、JXCategoryIndicatorBackgroundView、JXCategoryIndicatorBallView

主要实现的方法:

  • 继承JXCategoryIndicatorComponentView,内部遵从了JXCategoryIndicatorProtocol协议;
  • 实现协议方法,自定义效果:
    • - (void)jx_refreshState:(CGRect)selectedCellFrame初始化或reloadData,重置状态;
    • - (void)jx_contentScrollViewDidScrollWithLeftCellFrame:(CGRect)leftCellFrame rightCellFrame:(CGRect)rightCellFrame selectedPosition:(JXCategoryCellClickedPosition)selectedPosition percent:(CGFloat)percent contentScrollView在进行手势滑动时,处理指示器跟随手势变化UI逻辑;
    • - (void)jx_selectedCell:(CGRect)cellFrame clickedRelativePosition:(JXCategoryCellClickedPosition)clickedRelativePosition根据选中的某个cell,处理过渡效果;

具体实例:参考demo工程里面的JXCategoryIndicatorDotLineView

Cell子类化注意事项

仓库自带:JXCategoryTitleView、JXCategoryTitleImageView、JXCategoryNumberView、JXCategoryDotView、JXCategoryImageView

主要实现的方法:

  • - (Class)preferredCellClass返回自定义的cell;
  • - (void)refreshDataSource刷新数据源,使用自定义的cellModel;
  • - (void)refreshCellModel:(JXCategoryBaseCellModel *)cellModel index:(NSInteger)index初始化、reloadData时对数据源重置;
  • - (CGFloat)preferredCellWidthAtIndex:(NSInteger)index根据cell的内容返回对应的宽度;
  • - (void)refreshSelectedCellModel:(JXCategoryBaseCellModel *)selectedCellModel unselectedCellModel:(JXCategoryBaseCellModel *)unselectedCellModelcell选中时进行状态刷新;
  • - (void)refreshLeftCellModel:(JXCategoryBaseCellModel *)leftCellModel rightCellModel:(JXCategoryBaseCellModel *)rightCellModel ratio:(CGFloat)ratiocell左右滚动切换的时候,进行状态刷新;

具体实例:参考demo工程里面的JXCategoryTitleAttributeView

继承提示

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

侧滑手势

首先,在viewDidAppear加上下面代码:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    self.navigationController.interactivePopGestureRecognizer.enabled = (self.categoryView.selectedIndex == 0);
}

系统默认返回Item

  • 点击处理:
#pragma mark - JXCategoryViewDelegate
- (void)categoryView:(JXCategoryBaseView *)categoryView didSelectedItemAtIndex:(NSInteger)index {
    self.navigationController.interactivePopGestureRecognizer.enabled = (index == 0);
}

自定义导航栏返回Item

  • 设置代理:self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;
  • 实现代理方法:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}
  • 点击处理:
#pragma mark - JXCategoryViewDelegate
- (void)categoryView:(JXCategoryBaseView *)categoryView didSelectedItemAtIndex:(NSInteger)index {
    self.navigationController.interactivePopGestureRecognizer.enabled = (index == 0);
}

contentScrollView

  • 布局灵活:JXCategoryView没有与contentScrollView强关联,你甚至可以不设置这个属性,把它当做简单的SegmentedControl。他们之间布局没有任何要求,可以把JXCategoryView放入导航栏、UITableViewSectionHeader等任何你想要的地方。
  • 点击处理:因为充分解耦,在JXCategoryView点击回调中,你需要添加如下代码进行内容滚动切换:
#pragma mark - JXCategoryViewDelegate
- (void)categoryView:(JXCategoryBaseView *)categoryView didSelectedItemAtIndex:(NSInteger)index {
    [self.scrollView setContentOffset:CGPointMake(self.scrollView.bounds.size.width*index, 0) animated:YES];
}

补充

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

Github地址

下载源码,一睹为快!JXCategoryView

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,639评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,277评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,221评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,474评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,570评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,816评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,957评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,718评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,176评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,511评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,646评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,322评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,934评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,755评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,987评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,358评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,514评论 2 348

推荐阅读更多精彩内容