摆脱第三方库系列(三)- 自己写顶部滚动标签栏

前言

好久没写博客了,最近自己参考了一些源码写了一个标签页,并把他传到了CocoaPods上。大家可以集成到项目中进行使用,也可以看看源码自己写一个更好的,也希望如果有什么意见可以告诉我,我会进行完善。

成果

自己写了两种形式的Demo,一种类似网易云音乐的固定的标签栏,一种是类似爱奇艺、今日头条的可滚动的标签栏。一开始只是草草的写,后来经过师傅提醒考虑了下优化,只有移动到那个页面才会对ViewController进行加载,这样即使是很复杂的页面很多网络请求数据加载应该也不会有卡顿的现象。

wait
wait
wait
wait

如果有想加入项目中使用的同学可以利用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.buttonWidth*titleArray.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];
}

这里的实现主要分成三个步骤,一开始在顶部加上一个self.headerView,这是一个UIScrollView,他是标签栏视图的最底层,所以需要最先add上去。在self.headerView我们会加上若干个UILabel,这几个UILabel就是没选中时的标签样子,就是上文gif中黑色的标签。然后再加上若干个透明的Button方便添加点击事件,当然也可以用手势这里随意。

第二步就是加一个UIView的“父视图”self.headerSelectedSuperView,这个父视图的作用稍后说。

第三步就是再加上一个UIScrollViewself.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;息息相关了。代码很简单。

至于其他部分我就不一一解析了,还是推荐大家看看源码,也希望有什么意见可以告诉我,互相提高互相进步。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • WebSocket-Swift Starscream的使用 WebSocket 是 HTML5 一种新的协议。它实...
    香橙柚子阅读 23,686评论 8 183
  • 那年她十八,他亦十八, 她常常穿一条梨花色的连衣裙, 他常常穿一件雪花般的白衬衫, 她喜欢听民谣,他喜欢弹吉他。 ...
    安落汐阅读 1,074评论 18 22
  • 的确是悲哀,为何我要满腹牢骚,诧异来的就不知不觉,像是判的刑,挂在心尖,攥的人疼。有人说,人们都不是太喜欢活天才,...
    小橙君阅读 495评论 0 1
  • “学无止境”是我们每个人对于知识的应有态度。同时,这也是我们想要成为一个内心强大者的基础准则! 在如今...
    舞宝宝阅读 354评论 3 1