美文网首页
iOS之网易效果

iOS之网易效果

作者: 凡尘一笑 | 来源:发表于2016-11-22 15:44 被阅读108次

    代码:https://gitee.com/lanyingwei/codes/eif1n95gctksl7jxp6u0m97
    这个是高仿了一个百思不得姐,然后里面的标题栏是固定死了的。比较局限,于是又写了一个滚动的标题栏。就和网易效果非常像了。看效果图

    wyxg.gif
    实现思路:
    1.利用控制器的父子关系,还有UIScrollView的一些代理方法,还有标题栏UILable添加手势点击事件去联动。
    2.标题栏使用一个UIScrollView,偏移量就是自控制器的个数乘以每隔标题的宽度。给UILable添加手势,点击让UIScrollView滚动到对应标题的控制器
    3.中间内容使用一个UIScorllView去装所有子控制器的View, 利用UIScrollView的代理方法,手动拖拽滚动时候,让标题也对应滚动。
    主要代码
    注意我这里的两个UIScrollView是利用xib拖拽的。
    源码:https://github.com/LYWGod/wyxg
    #import "NewsViewController.h"
    
    #import "TopLineViewController.h"
    #import "HotViewController.h"
    #import "SocietyViewController.h"
    #import "VideoViewController.h"
    #import "ReaderViewController.h"
    #import "ScienceViewController.h"
    
    static CGFloat const labelW = 100;  // 标题文字宽度
    
    static CGFloat const radio = 1.3;   // 点击或者滑动scrollView 标题Label放大倍数
    
    #define KscreenWidth [UIScreen mainScreen].bounds.size.width
    
    #define KscreenHeight [UIScreen mainScreen].bounds.size.height
    
    @interface NewsViewController ()<UIScrollViewDelegate>
    
    @property (nonatomic, weak) UILabel *selLabel;
    
    @property (weak, nonatomic) IBOutlet UIScrollView *titleScrollView;
    
    @property (weak, nonatomic) IBOutlet UIScrollView *contentScrollView;
    
    @property (nonatomic, strong) NSMutableArray *titleLabels;
    
    @end
    
    @implementation NewsViewController
    
    /*
     网易新闻实现步骤:
     1.搭建结构(导航控制器)
     * 自定义导航控制器根控制器NewsViewController
     * 搭建NewsViewController界面(上下滚动条)
     * 确定NewsViewController有多少个子控制器,添加子控制器
     2.设置上面滚动条标题
     * 遍历所有子控制器
     3.监听滚动条标题点击
     * 3.1 让标题选中,文字变为红色
     * 3.2 滚动到对应的位置
     * 3.3 在对应的位置添加子控制器view
     4.监听滚动完成时候
     * 4.1 在对应的位置添加子控制器view
     * 4.2 选中子控制器对应的标题
     */
    
    
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 1.添加所有子控制器
        [self setUpChildViewController];
        
        // 2.添加所有子控制器对应标题
        [self setUpTitleLabel];
        
        // iOS7会给导航控制器下所有的UIScrollView顶部添加额外滚动区域
        // 不想要添加
        self.automaticallyAdjustsScrollViewInsets = NO;
        
        // 3.初始化UIScrollView
        [self setUpScrollView];
    }
    
    
    // 初始化UIScrollView
    - (void)setUpScrollView
    {
        NSUInteger count = self.childViewControllers.count;
        // 设置标题滚动条
        self.titleScrollView.contentSize = CGSizeMake(count * labelW, 0);
        self.titleScrollView.showsHorizontalScrollIndicator = NO;
        
        // 设置内容滚动条
        self.contentScrollView.contentSize = CGSizeMake(count * KscreenWidth, 0);
        // 开启分页
        self.contentScrollView.pagingEnabled = YES;
        // 没有弹簧效果
        self.contentScrollView.bounces = NO;
        // 隐藏水平滚动条
        self.contentScrollView.showsHorizontalScrollIndicator = NO;
        // 设置代理
        self.contentScrollView.delegate = self;
    }
    
    
    // 添加所有子控制器对应标题
    - (void)setUpTitleLabel
    {
        NSUInteger count = self.childViewControllers.count;
        
        CGFloat labelX = 0;
        CGFloat labelY = 0;
        CGFloat labelH = 44;
        
        for (int i = 0; i < count; i++) {
            // 获取对应子控制器
            UIViewController *vc = self.childViewControllers[i];
            
            // 创建label
            UILabel *label = [[UILabel alloc] init];
            
            labelX = i * labelW;
            
            // 设置尺寸
            label.frame = CGRectMake(labelX, labelY, labelW, labelH);
            
            // 设置label文字
            label.text = vc.title;
            
            // 设置高亮文字颜色
            label.highlightedTextColor = [UIColor redColor];
            
            // 设置label的tag
            label.tag = i;
            
            // 设置用户的交互
            label.userInteractionEnabled = YES;
            
            // 文字居中
            label.textAlignment = NSTextAlignmentCenter;
            
            
            // 添加到titleLabels数组
            [self.titleLabels addObject:label];
            
            // 添加点按手势
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(titleClick:)];
            [label addGestureRecognizer:tap];
            
            // 默认选中第0个label
            if (i == 0) {
                [self titleClick:tap];
            }
            
            // 添加label到标题滚动条上
            [self.titleScrollView addSubview:label];
        }
        
    }
    
    // 设置标题居中
    - (void)setUpTitleCenter:(UILabel *)centerLabel
    {
        // 计算偏移量
        CGFloat offsetX = centerLabel.center.x - KscreenWidth * 0.5;
        
        if (offsetX < 0) offsetX = 0;
        
        // 获取最大滚动范围
        CGFloat maxOffsetX = self.titleScrollView.contentSize.width - KscreenWidth;
        
        if (offsetX > maxOffsetX) offsetX = maxOffsetX;
        
        
        // 滚动标题滚动条
        [self.titleScrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES];
        
    }
    
    #pragma mark - UIScrollViewDelegate
    // scrollView一滚动就会调用
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        CGFloat curPage = scrollView.contentOffset.x / scrollView.bounds.size.width;
        
        // 左边label角标
        NSInteger leftIndex = curPage;
        // 右边的label角标
        NSInteger rightIndex = leftIndex + 1;
        
        // 获取左边的label
        UILabel *leftLabel = self.titleLabels[leftIndex];
        
        // 获取右边的label
        UILabel *rightLabel;
        if (rightIndex < self.titleLabels.count - 1) {
            rightLabel = self.titleLabels[rightIndex];
        }
        
        // 计算下右边缩放比例
        CGFloat rightScale = curPage - leftIndex;
        NSLog(@"rightScale--%f",rightScale);
        
        // 计算下左边缩放比例
        CGFloat leftScale = 1 - rightScale;
        NSLog(@"leftScale--%f",leftScale);
        
        // 0 ~ 1
        // 1 ~ 2
        // 左边缩放
        leftLabel.transform = CGAffineTransformMakeScale(leftScale * 0.3 + 1, leftScale * 0.3+ 1);
        
        // 右边缩放
        rightLabel.transform = CGAffineTransformMakeScale(rightScale * 0.3 + 1, rightScale * 0.3+ 1);
        
        // 设置文字颜色渐变
        /*
         R G B
         黑色 0 0 0
         红色 1 0 0
         */
        leftLabel.textColor = [UIColor colorWithRed:leftScale green:0 blue:0 alpha:1];
        rightLabel.textColor = [UIColor colorWithRed:rightScale green:0 blue:0 alpha:1];
        
        NSLog(@"%f",curPage);
        
        
    }
    
    #pragma mark - 结束滚动 需要做的事情
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
        
        // 计算滚动到哪一页
        NSInteger index = scrollView.contentOffset.x / scrollView.bounds.size.width;
        
    //    CGFloat offsetX = scrollView.contentOffset.x;
        
        // 1.添加子控制器view
        [self showVc:index];
        
        // 2.把对应的标题选中
        UILabel *selLabel = self.titleLabels[index];
        
        [self selectLabel:selLabel];
        
        // 3.让选中的标题居中
        [self setUpTitleCenter:selLabel];
    }
    
    // 显示控制器的view
    - (void)showVc:(NSInteger)index
    {
        CGFloat offsetX = index * KscreenWidth;
        
        UIViewController *vc = self.childViewControllers[index];
        
        // 判断控制器的view有没有加载过,如果已经加载过,就不需要加载
        if (vc.isViewLoaded) return;
        
        [self.contentScrollView addSubview:vc.view];
        vc.view.frame = CGRectMake(offsetX, 0, KscreenWidth, KscreenHeight);
    }
    
    // 点击标题的时候就会调用
    - (void)titleClick:(UITapGestureRecognizer *)tap
    {
        
        // 0.获取选中的label
        UILabel *selLabel = (UILabel *)tap.view;
        
        // 1.标题颜色变成红色,设置高亮状态下的颜色
        [self selectLabel:selLabel];
        
        // 2.滚动到对应的位置
        NSInteger index = selLabel.tag;
        // 2.1 计算滚动的位置
        CGFloat offsetX = index * KscreenWidth;
        self.contentScrollView.contentOffset = CGPointMake(offsetX, 0);
        
        // 3.给对应位置添加对应子控制器
        [self showVc:index];
        
        // 4.让选中的标题居中
        [self setUpTitleCenter:selLabel];
        
    }
    
    // 选中label
    - (void)selectLabel:(UILabel *)label
    {
        // 取消之前Label高亮
        _selLabel.highlighted = NO;
        // 取消之前Label形变
        _selLabel.transform = CGAffineTransformIdentity;
        // 恢复之前Label颜色
        _selLabel.textColor = [UIColor blackColor];
        
        // 高亮当前label
        label.highlighted = YES;
        // 形变当前label
        label.transform = CGAffineTransformMakeScale(radio, radio);
        
        // 记录当前label
        _selLabel = label;
        
    }
    
    // 添加所有子控制器
    - (void)setUpChildViewController
    {
        // 头条
        TopLineViewController *topLine = [[TopLineViewController alloc] init];
        topLine.title = @"头条";
        [self addChildViewController:topLine];
        
        // 热点
        HotViewController *hot = [[HotViewController alloc] init];
        hot.title = @"热点";
        [self addChildViewController:hot];
        
        // 视频
        VideoViewController *video = [[VideoViewController alloc] init];
        video.title = @"视频";
        [self addChildViewController:video];
        
        // 社会
        SocietyViewController *society = [[SocietyViewController alloc] init];
        society.title = @"社会";
        [self addChildViewController:society];
        
        // 阅读
        ReaderViewController *reader = [[ReaderViewController alloc] init];
        reader.title = @"阅读";
        [self addChildViewController:reader];
        
        // 科技
        ScienceViewController *science = [[ScienceViewController alloc] init];
        science.title = @"科技";
        [self addChildViewController:science];
        
        
    }
    
    // 懒加载
    - (NSMutableArray *)titleLabels
    {
        if (_titleLabels == nil) {
            _titleLabels = [NSMutableArray array];
        }
        return _titleLabels;
    }
    
    

    相关文章

      网友评论

          本文标题:iOS之网易效果

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