擺脫第三方庫系列(三)- 自己寫頂部滾動標簽欄

309267245 8年前發布 | 11K 次閱讀 iOS開發 移動開發

前言

好久沒寫博客了,最近自己參考了一些源碼寫了一個標簽頁,并把他傳到了CocoaPods上。大家可以集成到項目中進行使用,也可以看看源碼自己寫一個更好的,也希望如果有什么意見可以告訴我,我會進行完善。

成果

自己寫了兩種形式的Demo,一種類似網易云音樂的固定的標簽欄,一種是類似愛奇藝、今日頭條的可滾動的標簽欄。一開始只是草草的寫,后來經過師傅提醒考慮了下優化,只有移動到那個頁面才會對ViewController進行加載,這樣即使是很復雜的頁面很多網絡請求數據加載應該也不會有卡頓的現象。

如果有想加入項目中使用的同學可以利用CocoaPods,具體使用我放在 github 上了,歡迎使用。也可以把github上的zip直接下載下來看使用方法。接下來簡單介紹下實現原理。

實現原理

簡單的說,頂部的標簽欄是UIScrollView,底下也是一個UIScrollView,將多個 ViewController.view 初始化加入到下面ScrollView中的合適位置,并且與頂部的標簽欄相關聯,并且給上面的標簽欄增加點擊事件控制下部分的ScrollView可以移動到合適的位置就行了!

部分源碼解析

感覺其實沒什么難點,比較需要動腦筋的實現應該就是頂部標簽欄隨下面ScrollView的滑動,包括字體顏色,下劃線移動。我就對這一部分進行介紹,對其他地方感興趣的同學可以自己把源碼下載下來看看。

這里先上代碼,先上頂部標簽欄的初始化方法。這一部分比較繁瑣,肯定可以簡化代碼,時間有點緊就沒做了。

- (void)addScrollHeader:(NSArray )titleArray
{
    self.headerView.frame = CGRectMake(0, 0, self.width, self.buttonHeight);
    self.headerView.contentSize = CGSizeMake(self.buttonWidthtitleArray.count, self.buttonHeight);
    [self addSubview:self.headerView];

for (NSInteger index = 0; index < titleArray.count; index++) {
    _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.buttonWidth*index, 0, self.buttonWidth, self.buttonHeight)];
    _titleLabel.textColor = [UIColor blackColor];
    _titleLabel.text = titleArray[index];
    _titleLabel.textAlignment = NSTextAlignmentCenter;
    _titleLabel.adjustsFontSizeToFitWidth = YES;
    [self.headerView addSubview:_titleLabel];

    _segmentBtn = [[UIButton alloc] initWithFrame:CGRectMake(self.buttonWidth*index, 0, self.buttonWidth, self.buttonHeight)];
    _segmentBtn.tag = index;
    [_segmentBtn setBackgroundColor:[UIColor clearColor]];
    [_segmentBtn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
    [self.headerView addSubview:_segmentBtn];
}


self.headerSelectedSuperView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.buttonWidth, self.buttonHeight)];
[self.headerView addSubview:self.headerSelectedSuperView];

self.headerSelectedView.frame =CGRectMake(0, 0, self.buttonWidth, self.buttonHeight);
self.headerSelectedView.contentSize = CGSizeMake(self.buttonWidth*titleArray.count, self.buttonHeight);
[self.headerSelectedSuperView addSubview:self.headerSelectedView];

for (NSInteger index = 0; index < titleArray.count; index++) {
    _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.buttonWidth*index, 0, self.buttonWidth, self.buttonHeight)];
    _titleLabel.textColor = [UIColor blueColor];
    _titleLabel.text = titleArray[index];
    _titleLabel.textAlignment = NSTextAlignmentCenter;
    _titleLabel.adjustsFontSizeToFitWidth = YES;
    [self.headerSelectedView addSubview:_titleLabel];

}

UIImageView *bottomLine = [[UIImageView alloc] initWithFrame:CGRectMake(0, self.headerSelectedView.contentSize.height - self.lineHeight, self.headerSelectedView.contentSize.width, self.lineHeight)];
bottomLine.backgroundColor = [UIColor blueColor];
[self.headerSelectedView addSubview:bottomLine];

} </code></pre>

這里的實現主要分成三個步驟,一開始在頂部加上一個 self.headerView ,這是一個UIScrollView,他是標簽欄視圖的最底層,所以需要最先add上去。在 self.headerView 我們會加上若干個UILabel,這幾個UILabel就是沒選中時的標簽樣子,就是上文gif中黑色的標簽。然后再加上若干個透明的Button方便添加點擊事件,當然也可以用手勢這里隨意。

第二步就是加一個UIView的“父視圖” self.headerSelectedSuperView ,這個父視圖的作用稍后說。

第三步就是再加上一個UIScrollView self.headerSelectedView ,這是當前選中標簽應該展現的外觀的ScrollView,我們在這個ScrollView里加入若干個UILabel,不同的是顏色要設置成選中標簽后的顏色,這里我設置的是藍色。為了美觀,還加了一個藍色的下劃線。第三步有個關健就是將 _headerSelectedView.clipsToBounds = YES; 這個代碼我在headerSelectedView的get方法里面寫了。這個屬性是說子視圖如果比父視圖大,則將超出的部分去掉,默認是NO的。不是很理解的最好取谷歌下,這個屬性是實現上圖效果的關健。

然后看UIScrollView的代理方法。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if (scrollView == _backView) {
        self.headerSelectedSuperView.frame = CGRectMake(scrollView.contentOffset.x * (self.buttonWidth/self.width), self.headerSelectedSuperView.frame.origin.y, self.headerSelectedSuperView.frame.size.width, self.headerSelectedSuperView.frame.size.height);
        self.headerSelectedView.contentOffset = CGPointMake(scrollView.contentOffset.x * (self.buttonWidth/self.width), 0);
    }
}

backView就是下面ViewController存放的ScrollView,當backView滾動時,我們需要改變標簽欄headerSelectedSuperView的frame和headerSelectedView的contentOffset,這樣的結果就是headerSelectedSuperView能移動到合適的位置,并且展示出headerSelectedSuperView子視圖也就是headerSelectedView合適的部分。這樣就能有gif中標簽欄的那種滾動效果了。這里就和 _headerSelectedView.clipsToBounds = YES; 息息相關了。代碼很簡單。

至于其他部分我就不一一解析了,還是推薦大家看看源碼,也希望有什么意見可以告訴我,互相提高互相進步。

相關文章

擺脫第三方庫系列(一)-自己寫一個側拉菜單

擺脫第三方庫系列(二)- 自己寫一個滾動廣告

 

來自:http://cbsfly.github.io/ios/segmentview

 本文由用戶 309267245 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!