【乾貨】每一個APP都用得上的SegmentView

JXCategoryView.png

騰訊新聞今日頭條、QQ音樂、網易雲音樂、京東、愛奇藝、淘寶、天貓、簡書、微博等全部主流APP分類切換滾動視圖git

與其餘的同類三方庫對比的優勢:github

  • 使用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",就可使用了;ruby

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 的邂逅bash

經常使用屬性說明

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搭配使用,可是效果須要本身把控,效果不是越多越好。參考混合使用;服務器

使用

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

//二、添加並配置指示器
//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];

//三、綁定contentScrollView。self.scrollView的初始化細節參考源碼。
self.categoryView.contentScrollView = self.scrollView;
[self.view addSubview:self.categoryView];
複製代碼
  • 單個cell刷新:好比紅點示例裏面,調用- (void)reloadCell:(NSUInteger)index
  • 全部狀態重置:數據源、屬性配置有變更時(好比從服務器拉取回來數據),須要調用reloadData方法刷新狀態。

指示器樣式自定義

倉庫自帶:JXCategoryIndicatorLineView、JXCategoryIndicatorTriangleView、JXCategoryIndicatorImageView、JXCategoryIndicatorBackgroundView、JXCategoryIndicatorBallViewide

主要實現的方法:佈局

  • 繼承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、JXCategoryImageViewui

主要實現的方法:

  • - (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

相關文章
相關標籤/搜索