美文网首页iOS Developer
仿网易新闻架构

仿网易新闻架构

作者: 45b645c5912e | 来源:发表于2017-02-10 13:01 被阅读71次
  • 头部标题选择,切换控制器


    WechatIMG1.jpeg
  • 实现思路

  • 类似于tabbar 首先添加子控制器

  • 添加标题选择按钮

  • 通过实现scrollView的代理方法,实现控制器的切换,懒加载

  • 默认启动时选择第一个头部标题

-(void)viewDidLoad {
    [super viewDidLoad];
    //添加子控制器
    [self setUpChildVc];
    //添加标题选择按钮
    [self setUpTitle];
    //选择第一个
    [self scrollViewDidEndScrollingAnimation:self.contentScrollView]; 
}
  • 添加子控制器 [self addChildViewController:social0];将控制器加到子控制器数组中对其引用,否则控制器创建后就会被杀死
  • 如下添加七个控制器
-(void)setUpChildVc{
    ZZHTableViewController *social0 = [[ZZHTableViewController alloc] init];
    social0.title = @"头1";
    [self addChildViewController:social0];
    ZZHTableViewController *social1 = [[ZZHTableViewController alloc] init];
    social1.title = @"头2";
    [self addChildViewController:social1];    
    ZZHTableViewController *social2 = [[ZZHTableViewController alloc] init];
    social2.title = @"头3";
    [self addChildViewController:social2];   
    ZZHTableViewController *social3 = [[ZZHTableViewController alloc] init];
    social3.title = @"头4";
    [self addChildViewController:social3];   
    ZZHTableViewController *social4 = [[ZZHTableViewController alloc] init];
    social4.title = @"头5";
    [self addChildViewController:social4];    
    ZZHTableViewController *social5 = [[ZZHTableViewController alloc] init];
    social5.title = @"头6";
    [self addChildViewController:social5];    
    ZZHTableViewController *social6 = [[ZZHTableViewController alloc] init];
    social6.title = @"头7";
    [self addChildViewController:social6]; 
}
  • 添加头部标题选择按钮
  • 如下根据子控制器数组中的数量,添加标题,标题即为控制器的title,social0.title = @"头1"
-(void)setUpTitle{
    // 定义临时变量
    CGFloat labelW = 100;
    CGFloat labelY = 0;
    CGFloat labelH = self.titleScrollView.frame.size.height;
    NSInteger count = self.childViewControllers.count;
    // 添加label
    for (NSInteger i = 0; i<count; i++) {
        ZZHLabel *label = [[ZZHLabel alloc] init];
        label.text = [self.childViewControllers[i] title];
        CGFloat labelX = i * labelW;
        label.frame = CGRectMake(labelX, labelY, labelW, labelH);
        label.tag = i;
        [self.titleScrollView addSubview:label];
        //label添加点击手势
        UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];
        [label addGestureRecognizer:tap];
    }
    // 设置contentSize
    self.titleScrollView.contentSize = CGSizeMake(count * labelW, 0);
    self.contentScrollView.contentSize = CGSizeMake(count * [UIScreen mainScreen].bounds.size.width, 0);
}
  • 给每个label添加点击事件,通过tag记录每个label的index,通过点击设置scrollView的ContentOffset来切换控制器
-(void)tap:(UITapGestureRecognizer *)tap{
    // 取出被点击label的索引
    NSInteger index = tap.view.tag;
    // 让底部的内容scrollView滚动到对应位置
    CGPoint offset = self.contentScrollView.contentOffset;
    offset.x = index * self.contentScrollView.frame.size.width;
    [self.contentScrollView setContentOffset:offset animated:YES];
}
  • 实现scrollView 的代理方法
  • 用户用手滑动scroll时 和通过点击头部标题用代码控制scroll滑动触发的代理方法是不同的,所以这里要实现两个代理方法
  • scrollView结束了滚动动画以后就会调用这个方法(比如-(void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated;方法执行的动画完毕后)
#pragma mark - <UIScrollViewDelegate>
//scrollView结束了滚动动画以后就会调用这个方法(比如- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated;方法执行的动画完毕后)
-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
    // 一些临时变量
    CGFloat width = scrollView.frame.size.width;
    CGFloat height = scrollView.frame.size.height;
    CGFloat offsetX = scrollView.contentOffset.x;
    // 当前位置需要显示的控制器的索引
    NSInteger index = offsetX / width;
    // 让对应的顶部标题居中显示
    ZZHLabel *label = self.titleScrollView.subviews[index];
    CGPoint titleOffset = self.titleScrollView.contentOffset;
    titleOffset.x = label.center.x - width * 0.5;
    // 左边超出处理
    if (titleOffset.x < 0) titleOffset.x = 0;
    // 右边超出处理
    CGFloat maxTitleOffsetX = self.titleScrollView.contentSize.width - width;
    if (titleOffset.x > maxTitleOffsetX) titleOffset.x = maxTitleOffsetX;
    [self.titleScrollView setContentOffset:titleOffset animated:YES];
    // 让其他label回到最初的状态
    for (ZZHLabel *otherLabel in self.titleScrollView.subviews) {
        if (otherLabel != label) otherLabel.scale = 0.0;
    }
    // 取出需要显示的控制器
    UIViewController *willShowVc = self.childViewControllers[index];
    // 如果当前位置的位置已经显示过了,就直接返回
    if ([willShowVc isViewLoaded]) return;
    // 添加控制器的view到contentScrollView中;
    willShowVc.view.frame = CGRectMake(offsetX, -64, width, height);
    [scrollView addSubview:willShowVc.view]; 
}
  • 手指松开scrollView后,scrollView停止减速完毕就会调用这个-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
//手指松开scrollView后,scrollView停止减速完毕就会调用这个
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [self scrollViewDidEndScrollingAnimation:scrollView];
}
  • 在滑动中获得需要处理的两个label 对label的font和color进行缩放,渐变处理
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat scale = scrollView.contentOffset.x / scrollView.frame.size.width;
    if (scale < 0 || scale > self.titleScrollView.subviews.count - 1) return;
    // 获得需要操作的左边label
    NSInteger leftIndex = scale;
    ZZHLabel *leftLabel = self.titleScrollView.subviews[leftIndex];
    // 获得需要操作的右边label
    NSInteger rightIndex = leftIndex + 1;
    ZZHLabel *rightLabel = (rightIndex == self.titleScrollView.subviews.count) ? nil : self.titleScrollView.subviews[rightIndex];
    // 右边比例
    CGFloat rightScale = scale - leftIndex;
    // 左边比例
    CGFloat leftScale = 1 - rightScale;
    // 设置label的比例
    leftLabel.scale = leftScale;
    rightLabel.scale = rightScale;
}
  • 将label的font缩放color渐变的效果封装到ZZHLabel中,通过暴露@property (nonatomic, assign) CGFloat scale;属性,重写- (void)setScale:(CGFloat)scale对label进行设置
const CGFloat XMGRed = 0.4;
const CGFloat XMGGreen = 0.6;
const CGFloat XMGBlue = 0.7;
const CGFloat XMGAlpha = 1.0;
-(void)setScale:(CGFloat)scale
{
    _scale = scale;
    //      R G B
    // 默认:0.4 0.6 0.7
    // 红色:1   0   0
    CGFloat red = XMGRed + (1 - XMGRed) * scale;
    CGFloat green = XMGGreen + (0 - XMGGreen) * scale;
    CGFloat blue = XMGBlue + (0 - XMGBlue) * scale;
    self.textColor = [UIColor colorWithRed:red green:green blue:blue alpha:XMGAlpha];
    // 大小缩放比例
    CGFloat transformScale = 1 + scale * 0.3; // [1, 1.3]
    self.transform = CGAffineTransformMakeScale(transformScale, transformScale);
}

相关文章

  • 仿网易新闻架构

    头部标题选择,切换控制器WechatIMG1.jpeg 实现思路 类似于tabbar 首先添加子控制器 添加标题选...

  • 仿网易新闻首页UI布局

    title : 仿网易新闻首页UI布局category : UI 仿网易新闻首页UI布局 标签(空格分隔): UI...

  • 自己看的github

    1.ARKit 太阳系 2.仿网易新闻

  • iOS 一些第三方资料

    一:源代码实例一个针对iOS模块化开发的解决方案 快速搭建项目源代码 模仿网易新闻做的精仿网易新闻 支付宝高仿版 ...

  • iOS比较常用的第三方及实例

    一:源代码实例 一个针对iOS模块化开发的解决方案 快速搭建项目源代码 模仿网易新闻做的精仿网易新闻 支付宝高仿版...

  • IOS

    一:源代码实例 一个针对iOS模块化开发的解决方案 快速搭建项目源代码 模仿网易新闻做的精仿网易新闻 支付宝高仿版...

  • 2016年优秀项目

    一:源代码实例一个针对iOS模块化开发的解决方案 快速搭建项目源代码 模仿网易新闻做的精仿网易新闻 支付宝高仿版 ...

  • 开源一个仿网易新闻的iosApp

    仿网易新闻git地址https://github.com/xinqin2496/TTNews

  • 仿网易新闻框架实现

    基于OC简要模仿网易新闻头部标题栏,实现点击对应标题时相关性标题居中功能。供小伙伴学习参考,高手忽略。详细代码参考...

  • Android实战:仿网易新闻app--简介

    最近写了一个简单的新闻app客户端,仿网易新闻的,实时获取网易新闻客户端的数据。话不多说,先上图。 项目结构 项目...

网友评论

    本文标题:仿网易新闻架构

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