首先,預(yù)覽一下實(shí)現(xiàn)效果:
? ? ?滾動(dòng)標(biāo)簽條在應(yīng)用中起到導(dǎo)航的功能,可將正文內(nèi)容分成具體的內(nèi)容模塊棋返,用戶點(diǎn)擊標(biāo)簽時(shí)相對(duì)應(yīng)的內(nèi)容視圖同步切換,反之雷猪,滑動(dòng)內(nèi)容視圖的頁面時(shí)標(biāo)簽條也會(huì)跟隨變換。ps.圖中的label為自定義控件GYLabel晰房,可達(dá)到點(diǎn)擊時(shí)字體放大變色的效果求摇,本文中就先不贅述。
為達(dá)到以上需求殊者,實(shí)現(xiàn)方式如下:
主框架由兩個(gè)scrollview組成:
1.滾動(dòng)標(biāo)題條smallScroll
2.對(duì)應(yīng)于標(biāo)題的內(nèi)容視圖bigScroll
==== 完成點(diǎn)擊標(biāo)簽顯示對(duì)應(yīng)的內(nèi)容視圖====
a.滾動(dòng)標(biāo)題條綁定用戶點(diǎn)擊響應(yīng)
滾動(dòng)標(biāo)題條的視圖是由GYLabel組合而成的与境,每add一個(gè)子視圖,配置tag屬性猖吴,由0開始逐個(gè)遞增摔刁;給每一個(gè)標(biāo)簽添加手勢(shì):
addGestureRecognizer:[ [UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(lblClick:) ]
響應(yīng)方法lblClick中拿到點(diǎn)擊視圖,根據(jù)標(biāo)簽的tag值算出大的滾動(dòng)內(nèi)容視圖的位移值海蔽,這樣可做到標(biāo)簽與內(nèi)容視圖以及用戶交互動(dòng)作的三者綁定共屈。
ps.不要忘記label.userInteractionEnabled = YES
-(void)lblClick:(UITapGestureRecognizer*)recognizer
//點(diǎn)擊標(biāo)簽時(shí)內(nèi)容視圖滑動(dòng)到指定的坐標(biāo),并且?guī)?dòng)畫效果
{ [self.bigScroll setContentOffset:
CGPointMake(recognizer.view.tag*self.bigScroll.bounds.size.width, 0)
animated:YES]; }
b.顯示bigScroll的內(nèi)容視圖
分析一下:致使bigScroll發(fā)生滑動(dòng)的有可能是用戶點(diǎn)擊了標(biāo)簽或者直接滑動(dòng)屏幕党窜,而在這兩種情況下都會(huì)調(diào)用的方法應(yīng)該是系統(tǒng)的UIScrollViewDelegate中的委托響應(yīng)方法拗引。
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{ ? ?[self scrollViewDidEndScrollingAnimation:scrollView]; ?}
選用以上的委托代理響應(yīng)順序,在view停止滑動(dòng)并且動(dòng)畫結(jié)束時(shí)調(diào)用幌衣,在方法中講子控制器的view加載到bigScroll矾削,子控制器的實(shí)例對(duì)象在viewDidLoad時(shí)機(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]; }
==== 手動(dòng)滑動(dòng)內(nèi)容視圖滾動(dòng)標(biāo)簽條跟隨變化====
因?yàn)槭前殡S著滑動(dòng)時(shí)頁面顯示一起變化的,所以這部分的邏輯實(shí)現(xiàn)應(yīng)該和頁面生成是在同一個(gè)時(shí)機(jī)楚里。
分析一下:用戶的點(diǎn)擊區(qū)域分成屏幕可視部分的左半邊和右半邊
a.如果點(diǎn)擊的標(biāo)簽中心點(diǎn)的位置在左半邊断部,則點(diǎn)擊不發(fā)生位移;
b.如果點(diǎn)擊的標(biāo)簽中心點(diǎn)的位置在右半邊腻豌,則點(diǎn)擊時(shí)標(biāo)簽水平位移到屏幕中心點(diǎn)家坎;
c.需要考慮標(biāo)簽的最大水平位移距離(滾動(dòng)標(biāo)題條smallScroll內(nèi)容視圖超出屏幕部分的水平距離)嘱能,如果位移到屏幕中心點(diǎn)的位移量大于最大水平位移距離,則此時(shí)的水平位移量應(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]; }
`