首先,預(yù)覽一下實(shí)現(xiàn)效果:

? ? ?滾動標(biāo)簽條在應(yīng)用中起到導(dǎo)航的功能,可將正文內(nèi)容分成具體的內(nèi)容模塊,用戶點(diǎn)擊標(biāo)簽時相對應(yīng)的內(nèi)容視圖同步切換,反之,滑動內(nèi)容視圖的頁面時標(biāo)簽條也會跟隨變換。ps.圖中的label為自定義控件GYLabel,可達(dá)到點(diǎn)擊時字體放大變色的效果,本文中就先不贅述。
為達(dá)到以上需求,實(shí)現(xiàn)方式如下:
主框架由兩個scrollview組成:
1.滾動標(biāo)題條smallScroll
2.對應(yīng)于標(biāo)題的內(nèi)容視圖bigScroll
==== 完成點(diǎn)擊標(biāo)簽顯示對應(yīng)的內(nèi)容視圖====
a.滾動標(biāo)題條綁定用戶點(diǎn)擊響應(yīng)
滾動標(biāo)題條的視圖是由GYLabel組合而成的,每add一個子視圖,配置tag屬性,由0開始逐個遞增;給每一個標(biāo)簽添加手勢:
addGestureRecognizer:[ [UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(lblClick:) ]
響應(yīng)方法lblClick中拿到點(diǎn)擊視圖,根據(jù)標(biāo)簽的tag值算出大的滾動內(nèi)容視圖的位移值,這樣可做到標(biāo)簽與內(nèi)容視圖以及用戶交互動作的三者綁定。
ps.不要忘記label.userInteractionEnabled = YES
-(void)lblClick:(UITapGestureRecognizer*)recognizer
//點(diǎn)擊標(biāo)簽時內(nèi)容視圖滑動到指定的坐標(biāo),并且?guī)赢嬓Ч?br>
{ [self.bigScroll setContentOffset:
CGPointMake(recognizer.view.tag*self.bigScroll.bounds.size.width, 0)
animated:YES]; }
b.顯示bigScroll的內(nèi)容視圖
分析一下:致使bigScroll發(fā)生滑動的有可能是用戶點(diǎn)擊了標(biāo)簽或者直接滑動屏幕,而在這兩種情況下都會調(diào)用的方法應(yīng)該是系統(tǒng)的UIScrollViewDelegate中的委托響應(yīng)方法。
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{ ? ?[self scrollViewDidEndScrollingAnimation:scrollView]; ?}
選用以上的委托代理響應(yīng)順序,在view停止滑動并且動畫結(jié)束時調(diào)用,在方法中講子控制器的view加載到bigScroll,子控制器的實(shí)例對象在viewDidLoad時機(jī)中已經(jīng)生成。
此處用子控制器來完成是考慮到界面如果比較復(fù)雜,其相關(guān)設(shè)置可由子控制器去完成。
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{
NSUInteger index=scrollView.contentOffset.x/self.bigScroll.bounds.size.width;
UIViewController* vc=self.childViewControllers[index];
vc.view.frame=scrollView.bounds;
[self.bigScroll addSubview:vc.view]; }
==== 手動滑動內(nèi)容視圖滾動標(biāo)簽條跟隨變化====
因?yàn)槭前殡S著滑動時頁面顯示一起變化的,所以這部分的邏輯實(shí)現(xiàn)應(yīng)該和頁面生成是在同一個時機(jī)。
分析一下:用戶的點(diǎn)擊區(qū)域分成屏幕可視部分的左半邊和右半邊
a.如果點(diǎn)擊的標(biāo)簽中心點(diǎn)的位置在左半邊,則點(diǎn)擊不發(fā)生位移;
b.如果點(diǎn)擊的標(biāo)簽中心點(diǎn)的位置在右半邊,則點(diǎn)擊時標(biāo)簽水平位移到屏幕中心點(diǎn);
c.需要考慮標(biāo)簽的最大水平位移距離(滾動標(biāo)題條smallScroll內(nèi)容視圖超出屏幕部分的水平距離),如果位移到屏幕中心點(diǎn)的位移量大于最大水平位移距離,則此時的水平位移量應(yīng)該設(shè)定為最大水平位移距離。
`
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{
NSUInteger index=scrollView.contentOffset.x/self.bigScroll.bounds.size.width;
UILabel* label=self.smallScroll.subviews[index];
//中心點(diǎn)在左半邊
CGFloat offsetx=label.center.x-self.smallScroll.bounds.size.width*0.5;
//最大水平位移距離
CGFloat offsetMax=
self.smallScroll.contentSize.width-self.smallScroll.bounds.size.width;
if (offsetx<0) {offsetx=0;}
else if(offsetx>offsetMax) {offsetx=offsetMax; }
[self.smallScroll setContentOffset:CGPointMake(offsetx, 0) animated:YES]; }
`