模仿淘宝店铺首页分段选择的渐变效果

#######首先申明一下:本篇内容不涉及到分段选择( 以下称为:segmentView)功能的实现,仅仅只是对分段选择的渐变效果进行讨论

最近双十一,双十二轮番轰炸,不知道又要有多少小伙伴剁手吃土了。当然,我属于一个例外,因为我老婆帮做了这件事。在我查看我老婆购买的东西的时候,无意间看到淘宝 APP,店铺首页的 segmentView 的动画效果


WechatIMG662.jpeg

然后就想着也来实现一下这个效果,因此也就有了这篇文章。
先看下,我实现的效果图:

简单说一下效果:随着 tableView 上滑,当segmentView接触到导航栏的时候,图片逐渐透明消失,文字逐渐变大;随着 tableView 下滑,当indexPath.row = 0的 cell 出现的时候,文字逐渐变小,图片逐渐显示出来。
实现效果.gif
首先我们还是先来分析一下:

一眼看过去,很容易就可以发现整个界面有三个部分:顶部店铺信息界面(以下称为:storeInfoView)、中间segmentView、底部数据展示界面。
数据展示选用 UITableView,你也可以用 UICollectionView。因为segmentView 有个顶部悬停的效果,所以有的小伙伴可能会想到这个可能是 tableView 的 headView。那么到底是不是呢?我截了一张淘宝 App 的原图。


淘宝 App 店铺首页原图.jpeg

当你向下滑动的时候,会出现一段空白。如果segmentView 是 tableView 的 headView 的话,是不会出现这段空白的。所以不是利用tableView 的 headView 来实现的。

下面来看看如何实现:

先看下视图的层次结构:


视图层次结构

storeInfoView 和 segmentView 是直接罩在 tableView 上面。为了不遮挡住 tableView 的数据展示,设置了 tableView.contentInset。

- (UITableView *)tableView
{
    if (_tableView == nil) {
        _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
        _tableView.contentInset = UIEdgeInsetsMake(200, 0, 0, 0);
        _tableView.backgroundColor = [UIColor colorWithRed:(240 / 255.0) green:(240 / 255.0) blue:(240 / 255.0) alpha:1.0];
        _tableView.dataSource = self;
        _tableView.delegate = self;
        [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];
    }
    return _tableView;
}

那么如何做到 storeInfoView 和 segmentView 随着 tableView 的滑动而移动的呢?主要的实现是在 UIScrollViewDelegate 中的 scrollViewDidScroll: 方法中实现的。因为 UITableView 是继承 UIScrollView 的,所以可以在 scrollViewDidScroll: 中获取到 tableView.contentOffset.y,然后根据这个 y 值来计算 storeInfoView 的 frame 和 segmentView 的 frame。
至于看到 segmentView 悬停在上方,是因为控制了tableView.contentOffset.y的范围。

#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat offSetY = scrollView.contentOffset.y;
    self.segmentView.offSet = offSetY;
    
    if (offSetY >= -113) {
        offSetY = -113;
    }else {
        if (offSetY <= -264) {
            offSetY = -264;
        }
    }
    
    CGRect infoViewFrame = self.infoView.frame;
    infoViewFrame.origin.y = -200 - offSetY;
    self.infoView.frame = infoViewFrame;
    
    CGRect segmentViewFrame = self.segmentView.frame;
    segmentViewFrame.origin.y = -64 - offSetY;
    self.segmentView.frame = segmentViewFrame;
}

完成 stroeInfoView 和 segmentView的移动和悬停,接下来就是要实现 segmentView 中的渐变效果了。这里我自定义了一个GGSegmentView,并且将tableView.contentOffset.y的值传递进去。在这里,我是在segmentView与导航栏接触的时候,再多滑动30的时候来完成效果。所以根据这多余的30可以计算出一个0~1的比值,然后利用这个比值,来设置图片的透明度,文字的大小。同时,我让 segment 有15的高度隐藏在了导航栏下面,然后让label 的高度增加15,这样就会让用户仅仅看到 label,还能产生出 segmentView 变矮的错觉。

- (void)setOffSet:(CGFloat)offSet
{
    if (offSet <= - 128) {
        offSet = - 128;
    }else{
        if (offSet >= -98) {
            offSet = -98;
        }
    }

    CGFloat proportion = (128 + offSet) / 30;
    CGFloat fontSize = 12 + (18 - 12) * proportion;
    
    for (UIImageView *imageView in _imageViewArray) {
        imageView.alpha = 1- proportion;
    }
    
    for (UILabel *label in _labelArray) {
        
        label.font = [UIFont systemFontOfSize:fontSize];
        
        CGRect labelFrame = label.frame;
        labelFrame.origin.y = ImageViewHeigh - 15*proportion;
        labelFrame.size.height = self.bounds.size.height - ImageViewHeigh + 15*proportion;
        label.frame = labelFrame;
    }
}

附上 Demo 地址:https://github.com/Gunial/StroeHomeDemo
#######写在最后,写本文的目的并不在于教会别人,而是在于记录自己的思考过程。如果各位看官有更好的实现思路,可以给我指点一下,帮助我成长,如果你在看的过程中有什么疑问也可以回复我,我会及时回复你。

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

推荐阅读更多精彩内容

  • *7月8日上午 N:Block :跟一个函数块差不多,会对里面所有的内容的引用计数+1,想要解决就用__block...
    炙冰阅读 2,480评论 1 14
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,068评论 4 62
  • 愿你回首仍有笑容​​ 刚上高中的时候,英语老师让我们用英文表达「时光易逝」,她点了几个同学起来回答。成绩好的同学用...
    一条王汪汪阅读 451评论 0 0
  • 1.MongoDB安装 通过Homebrew 安装MongoDB (Mac OS下) 安装步骤简单,关键在mon...
    EnjoyWT阅读 1,418评论 0 4
  • https://objectkuan.gitbooks.io/ucore-docs/content/lab2/la...
    jolanxiao阅读 120评论 0 0