導(dǎo)讀:
下面這個(gè)效果(多視圖滑動(dòng)點(diǎn)擊切換)在很多App都有用到.
我相信大家都寫過很多遍了.網(wǎng)上也有大量的Demo,設(shè)計(jì)思路,大致差不多,但代碼繁雜程度不忍直視.
筆者自己對(duì)這個(gè)視圖效果進(jìn)行了封裝,幾次優(yōu)化后,目前代碼,精簡(jiǎn)美觀,接口簡(jiǎn)單.
外界只需要調(diào)用一個(gè)接口,就能輕松實(shí)現(xiàn)這個(gè)效果.
使用方法和系統(tǒng)的tabbarController相似,只需要給HYTabbarView添加對(duì)應(yīng)控制器即可.
github源碼分享https://github.com/HelloYeah/HYTabbarView.
大家checkout時(shí)順手點(diǎn)個(gè)星星,與人為樂,自得其樂.
HYTabbarView效果圖如下

HYTabbarView可靈活配置UI界面
static CGFloat const topBarItemMargin = 15; ///標(biāo)題之間的間距
static CGFloat const topBarHeight = 40; //頂部標(biāo)簽條的高度
實(shí)現(xiàn)思路詳解
界面分析:分為上下部分,頂部UIScrollView,底部UICollectionView.再實(shí)現(xiàn)兩部分的聯(lián)動(dòng)即可實(shí)現(xiàn) (底部視圖相對(duì)復(fù)雜,占用內(nèi)存大,底部用UICollectionView實(shí)現(xiàn)會(huì)比用UIScrollView性能好很多)
每一個(gè)標(biāo)題對(duì)應(yīng)一個(gè)View視圖,View視圖交由相應(yīng)的控制器來管理,代碼結(jié)構(gòu)十分清晰.做到不同View上的業(yè)務(wù)邏輯高聚合.也不會(huì)產(chǎn)生耦合性
上下兩部分的聯(lián)動(dòng),這里是同過KVO實(shí)現(xiàn)的,監(jiān)聽當(dāng)前的selectedIndex,底部視圖滾動(dòng)時(shí),修改selectedIndex的值.在KVO監(jiān)聽的回調(diào)方法里讓標(biāo)題居中.
其他細(xì)節(jié)相對(duì)簡(jiǎn)單,大家不看代碼都知道如何處理,比如:點(diǎn)擊頂部標(biāo)題,設(shè)置按鈕選中,切換到對(duì)應(yīng)的CollectionCell等
代碼片段:
外界傳個(gè)控制器和一個(gè)標(biāo)題,添加一個(gè)欄目
//外界傳個(gè)控制器,添加一個(gè)欄目
- (void)addSubItemWithViewController:(UIViewController *)viewController{
UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
[self.tabbar addSubview:btn];
[self setupBtn:btn withTitle:viewController.title];
[btn addTarget:self action:@selector(itemSelected:) forControlEvents:UIControlEventTouchUpInside];
[self.subViewControllers addObject:viewController];
}
KVO監(jiān)聽當(dāng)前選中View的序號(hào)值
//viewDidLoad中添加觀察者
[self addObserver:self forKeyPath:@"selectedIndex" options:NSKeyValueObservingOptionOld |NSKeyValueObservingOptionNew context:@"scrollToNextItem"];
//讓標(biāo)題按鈕居中算法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (context == @"scrollToNextItem") {
//設(shè)置按鈕選中
[self itemSelectedIndex:self.selectedIndex];
UIButton * btn = self.titles[self.selectedIndex];
// 計(jì)算偏移量
CGFloat offsetX = btn.center.x - HYScreenW * 0.5;
if (offsetX < 0) offsetX = 0;
// 獲取最大滾動(dòng)范圍
CGFloat maxOffsetX = self.tabbar.contentSize.width - HYScreenW;
if (offsetX > maxOffsetX) offsetX = maxOffsetX;
// 滾動(dòng)標(biāo)題滾動(dòng)條
[self.tabbar setContentOffset:CGPointMake(offsetX, 0) animated:YES];
}
}
點(diǎn)擊按鈕,滾動(dòng)視圖,字體放大動(dòng)畫
- (void)itemSelectedIndex:(NSInteger)index{
UIButton * preSelectedBtn = self.titles[_preSelectedIndex];
preSelectedBtn.selected = NO;
_selectedIndex = index;
_preSelectedIndex = _selectedIndex;
UIButton * selectedBtn = self.titles[index];
selectedBtn.selected = YES;
[UIView animateWithDuration:0.25 animations:^{
preSelectedBtn.titleLabel.font = [UIFont systemFontOfSize:15];
selectedBtn.titleLabel.font = [UIFont systemFontOfSize:18];
}];
}
控制器代碼如下
使用方法類似系統(tǒng)的UITabbarController,外界只需直接傳入控制器.
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.tabbarView];
}
//懶加載
- (HYTabbarView *)tabbarView{
if (!_tabbarView) {
_tabbarView = ({
HYTabbarView * tabbar = [[HYTabbarView alloc]initWithFrame:CGRectMake(0, 64, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - 64)];
//傳入九個(gè)控制器,每個(gè)控制器分別管理對(duì)應(yīng)的視圖
UIViewController * vc0 = [[UIViewController alloc]init];
vc0.title = @"推薦";
[tabbar addSubItemWithViewController:vc0];
UIViewController * vc1 = [[UIViewController alloc]init];
vc1.title = @"熱點(diǎn)";
[tabbar addSubItemWithViewController:vc1];
UIViewController * vc2 = [[UIViewController alloc]init];
vc2.title = @"視頻";
[tabbar addSubItemWithViewController:vc2];
UIViewController * vc3 = [[UIViewController alloc]init];
vc3.title = @"中國好聲音";
[tabbar addSubItemWithViewController:vc3];
UIViewController * vc4 = [[UIViewController alloc]init];
vc4.title = @"數(shù)碼";
[tabbar addSubItemWithViewController:vc4];
UIViewController * vc5 = [[UIViewController alloc]init];
vc5.title = @"頭條號(hào)";
[tabbar addSubItemWithViewController:vc5];
UIViewController * vc6 = [[UIViewController alloc]init];
vc6.title = @"房產(chǎn)";
[tabbar addSubItemWithViewController:vc6];
UIViewController * vc7 = [[UIViewController alloc]init];
vc7.title = @"奧運(yùn)會(huì)";
[tabbar addSubItemWithViewController:vc7];
UIViewController * vc8 = [[UIViewController alloc]init];
vc8.title = @"時(shí)尚";
[tabbar addSubItemWithViewController:vc8];
tabbar;
});
}
return _tabbarView;
}
總結(jié)
看完后,有沒有覺得很簡(jiǎn)單,很清晰。
要是覺得還不錯(cuò),github源碼Star:https://github.com/HelloYeah/HYTabbarView