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

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

作者: 一位小码农 | 来源:发表于2016-12-15 14:39 被阅读0次

#######首先申明一下:本篇内容不涉及到分段选择( 以下称为: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
#######写在最后,写本文的目的并不在于教会别人,而是在于记录自己的思考过程。如果各位看官有更好的实现思路,可以给我指点一下,帮助我成长,如果你在看的过程中有什么疑问也可以回复我,我会及时回复你。

相关文章

网友评论

      本文标题:模仿淘宝店铺首页分段选择的渐变效果

      本文链接:https://www.haomeiwen.com/subject/llxgmttx.html