iOS中利用父子控制器快速建立新闻框架

作者: 打电话记错号码的人 | 来源:发表于2016-07-27 00:52 被阅读739次

    作品链接:http://www.jianshu.com/users/1e0f5e6f73f6/top_articles

    1.新闻实现步骤:

     1.搭建结构(导航控制器)
     * 自定义导航控制器根控制器NewsViewController
     * 搭建NewsViewController界面(上下滚动条)
     * 确定NewsViewController有多少个子控制器,添加子控制器
     2.设置上面滚动条标题
     * 遍历所有子控制器
     3.监听滚动条标题点击
     * 3.1 让标题选中,文字变为红色
     * 3.2 滚动到对应的位置
     * 3.3 在对应的位置添加子控制器view
     4.监听滚动完成时候
     * 4.1 在对应的位置添加子控制器view
     * 4.2 选中子控制器对应的标题
    

    2.实现代码

    1.所用到的宏及全局常量
    // 标题缩放比例
    static CGFloat const radio = 1.4;
    // 标题的宽度
    static CGFloat const labelW = 100;
    // 控制器的宽度
    #define PHScreenW [UIScreen mainScreen].bounds.size.width
    // 控制器的高度
    #define PHScreenH [UIScreen mainScreen].bounds.size.height
    
    2.声明及连线
    // 选中的标题
    @property (nonatomic, weak) UILabel *selLabel;
    // 标题的ScrollView
    @property (weak, nonatomic) IBOutlet UIScrollView *titleScrollView;
    // 控制器的ScrollView
    @property (weak, nonatomic) IBOutlet UIScrollView *contentScrollView;
    // 可变的标题Label数组
    @property (nonatomic, strong) NSMutableArray *titleLabels;
    
    
    3.懒加载,创建titleLabels
    - (NSMutableArray *)titleLabels
    {
        if (_titleLabels == nil) {
            _titleLabels = [NSMutableArray array];
        }
        return _titleLabels;
    }
    
    
    4.初始化
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        [self setupChildViewController];
        [self setupTitleLabel];
        // iOS7会给导航控制器下所有的UIScrollView顶部添加额外滚动区域
        // 不想要添加
        self.automaticallyAdjustsScrollViewInsets = NO;
        [self setupScrollView];
    
    }
    
    

    4.1 初始化UIScrollView

    - (void)setupScrollView
    {
        NSUInteger count = self.childViewControllers.count;
        // 设置滚动条
        self.titleScrollView.contentSize = CGSizeMake(count * labelW, 0);
        self.titleScrollView.showsHorizontalScrollIndicator = NO;
    
        // 设置内容滚动条
        self.contentScrollView.contentSize = CGSizeMake(count * PHScreenW, 0);
        // 开启分页
        self.contentScrollView.pagingEnabled = YES;
        // 没有弹簧效果
        self.contentScrollView.bounces = NO;
        // 隐藏水平滚动条
        self.contentScrollView.showsHorizontalScrollIndicator = NO;
        // 设置代理
        self.contentScrollView.delegate = self;
    }
    
    

    4.2 添加所有子控制器对应标题

    - (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.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个
            if (i == 0) {
                [self titleClick:tap];
            }
    
            // 添加label到标题滚动条上
            [self.titleScrollView addSubview:label];
        }
    
    }
    
    

    4.3 点击标题的时候就会调用

    - (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 * PHScreenW;
        self.contentScrollView.contentOffset = CGPointMake(offsetX, 0);
        // 3.给对应位置添加对应子控制器
        [self showVc:index];
    
        // 4.让选中的标题居中
        [self setupTitleCenter:selLabel];
    }
    
    

    4.4添加所有子控制器

    - (void)setupChildViewController
    {
        // 全部
        AllViewController *all = [[AllViewController alloc] init];
    
        all.title = @"全部";
        [self addChildViewController:all];
    
        // 头条
        TopViewController *top = [[TopViewController alloc] init];
    
        top.title = @"头条";
        [self addChildViewController:top];
    
        // 热点
        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];
    
        // 阅读
        ReadViewController *read = [[ReadViewController alloc] init];
    
        read.title = @"阅读";
        [self addChildViewController:read];
    
        // 科技
        ScienceViewController *science = [[ScienceViewController alloc] init];
    
        science.title = @"科技";
        [self addChildViewController:science];
    
    }
    
    
    5.UIScrollViewDelegate代理方法

    5.1 scrollView一滚动就会调用

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        CGFloat curentPage = scrollView.contentOffset.x / scrollView.bounds.size.width;
        // 左边label角标
        NSInteger leftIndex = curentPage;
    
        // 右边的label角标
        NSInteger rightIndex = leftIndex + 1;
    
        // 获取左边的label
        UILabel *leftabel = self.titleLabels[leftIndex];
        // 获取右边的label
        UILabel *rightLabel;
        if (rightIndex < self.titleLabels.count) {
            rightLabel = self.titleLabels[rightIndex];
        }
        // 计算右边的缩放比例
        CGFloat rightScale = curentPage - leftIndex;
        // 计算下左边的缩放比例
        CGFloat leftScale = 1 - rightScale;
        // 左边缩放
        leftabel.transform = CGAffineTransformMakeScale(radio, radio);
        // 右边缩放
        rightLabel.transform = CGAffineTransformMakeScale(radio, radio);
        // 设置文字颜色渐变
        /*
         R G B
         黑色 0 0 0
         红色 1 0 0
    
         */
        leftabel.textColor = [UIColor colorWithRed:leftScale green:0 blue:0 alpha:1];
        rightLabel.textColor = [UIColor colorWithRed:rightScale green:0 blue:0 alpha:1];
    }
    
    

    5.2 计算滚动到哪一页

    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    {
        // 计算滚动到哪一页
        NSInteger index = scrollView.contentOffset.x / scrollView.bounds.size.width;
      //  CGFloat offsetX = scrollView.contentOffset.x;
        // 1.添加子控制器
        [self showVc:index];
        // 2.把对应的标题选中
        UILabel *selLabel = self.titleLabels[index];
        [self selectLabel:selLabel];
        // 3. 让选中的标题居中
        [self setupTitleCenter:selLabel];
    }
    
    
    6. 代理中所调用的方法

    6.1 显示控制器的View

    - (void)showVc:(NSInteger)index
    {
        CGFloat offsetX = index * PHScreenW;
        UIViewController *vc = self.childViewControllers[index];
        //判断控制器的view有没有加载过,如果已经加载过,就不需要加载
        if (vc.isViewLoaded) {
            return;
        }
        vc.view.frame = CGRectMake(offsetX, 0, PHScreenW, PHScreenH);
    
        [self.contentScrollView addSubview:vc.view];
    }
    
    

    6.2 设置标题居中

    - (void)setupTitleCenter:(UILabel *)centerLabel
    {
        // 计算偏移量
        CGFloat offsetX = centerLabel.center.x - PHScreenW * 0.5;
        if (offsetX < 0) {
            offsetX = 0;
        }
        // 获取最大滚动范围
        CGFloat maxOffsetX = self.titleScrollView.contentSize.width - PHScreenW;
        if (offsetX > maxOffsetX) offsetX = maxOffsetX;
        // 滚动标题滚动条
        [self.titleScrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES];
    }
    
    

    6.3 选中的label

    - (void)selectLabel:(UILabel *)label
    {
        // 取消高亮
        _selLabel.highlighted = NO;
        //取消渐变
        _selLabel.transform = CGAffineTransformIdentity;
        //颜色恢复
        _selLabel.textColor = [UIColor blackColor];
        // 高亮
        label.highlighted = YES;
    
        // 形变
        label.transform = CGAffineTransformMakeScale(radio, radio);
        _selLabel = label;
    }
    
    

    相关文章

      网友评论

      • huanghy:有没有demo
      • idream:以后可以提供一个demo的地址吗?

      本文标题:iOS中利用父子控制器快速建立新闻框架

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