騰訊新聞今日頭條、QQ音樂、網易雲音樂、京東、愛奇藝、淘寶、天貓、簡書、微博等所有主流APP分類切換滾動檢視
與其他的同類三方庫對比的優點:
- 使用POP(Protocol Oriented Programming面對協議程式設計)封裝指示器邏輯,可以為所欲為的自定義指示器效果;
- 提供更加全面豐富的效果,互動更加順暢;
- 使用子類化管理cell樣式,邏輯更清晰,擴充套件更簡單;
Github地址
下載原始碼,一睹為快!JXCategoryView
效果預覽
指示器效果預覽
說明 | Gif |
---|---|
指示器LineView | |
指示器LineView京東風格 | |
指示器LineView愛奇藝風格 | |
指示器EllipseLayer | |
指示器EllipseLayer遮罩 | |
指示器EllipseLayer遮罩 (陰影) | |
指示器ImageView(小船) | |
指示器滾動效果(足球) | |
QQ黏性紅點 | |
三角形底部 | |
三角形頂部 | |
文字遮罩(無背景檢視) | |
背景指示圖 | |
矩形指示圖 | |
混合使用 | |
自定義Indicator示例-點線 |
Cell樣式效果預覽
說明 | Gif |
---|---|
顏色漸變 | |
大小縮放 | |
分割線 | |
TitleImage_Top | |
TitleImage_Left | |
TitleImage_Bottom | |
TitleImage_Right | |
TitleImage_OnlyImage | |
圖文混用 | |
自定義-數字 | |
自定義cell-紅點 | |
自定義cell-背景色漸變 | |
騰訊視訊效果 | |
自定義cell示例-多行+富文字 |
特殊效果預覽
說明 | Gif |
---|---|
SegmentedControl | |
導航欄使用 | |
個人主頁(上下左右滾動、header懸浮) | |
巢狀使用 | |
垂直列表滾動 高仿騰訊視訊 (背景色異常是錄屏軟體bug |
|
資料來源重新整理&列表資料載入 示例 |
要求
- iOS 8.0+
- Xcode 9+
- Objective-C
安裝
手動
Clone程式碼,把Sources資料夾拖入專案,#import "JXCategoryView.h",就可以使用了;
CocoaPods
target '<Your Target Name>' do
pod 'JXCategoryView'
end
複製程式碼
結構圖
- 指示器樣式自定義:使用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 *)unselectedCellModel
cell選中時進行狀態重新整理;- (void)refreshLeftCellModel:(JXCategoryBaseCellModel *)leftCellModel rightCellModel:(JXCategoryBaseCellModel *)rightCellModel ratio:(CGFloat)ratio
cell左右滾動切換的時候,進行狀態重新整理;
具體例項:參考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