网易新闻首页demo

1.在storyboard里拖2个scrollView,一个用来显示上面的菜单标题,一个用来显示对应的内容


2.父控制器里添加子控制器

//
//  ViewController.m


#import "ViewController.h"
#import "NewsViewController.h"
#import "HomeLabel.h"

@interface ViewController () <UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *titileScrollView;
@property (weak, nonatomic) IBOutlet UIScrollView *contentScrollView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 不要自动调整UIScrollView的contentInset属性的值
    self.automaticallyAdjustsScrollViewInsets = NO;
    
    
    // 1.添加子控制器
    [self setupChildVc];
    
    // 2.添加菜单标题
    [self setupTitle];
    
    // 3.默认就显示第0个子控制器
    [self scrollViewDidEndScrollingAnimation:self.contentScrollView];
}

/**
 *  初始化所有的子控制器
 */
- (void)setupChildVc
{
    NewsViewController *news0 = [[NewsViewController alloc] init];
    news0.title = @"国际";
    [self addChildViewController:news0];
    
    NewsViewController *news1 = [[NewsViewController alloc] init];
    news1.title = @"热门";
    [self addChildViewController:news1];
    
    NewsViewController *news2 = [[NewsViewController alloc] init];
    news2.title = @"推荐";
    [self addChildViewController:news2];
    
    NewsViewController *news3 = [[NewsViewController alloc] init];
    news3.title = @"财经";
    [self addChildViewController:news3];
    
    NewsViewController *news4 = [[NewsViewController alloc] init];
    news4.title = @"娱乐";
    [self addChildViewController:news4];
    
    NewsViewController *news5 = [[NewsViewController alloc] init];
    news5.title = @"科技";
    [self addChildViewController:news5];
    
    NewsViewController *news6 = [[NewsViewController alloc] init];
    news6.title = @"社会";
    [self addChildViewController:news6];
}

/**
 *  初始化菜单标题
 */
- (void)setupTitle
{
    CGFloat labelY = 0;
    CGFloat labelW = 100;
    CGFloat labelH = self.titileScrollView.frame.size.height;

    // 添加label
    for (NSInteger i=0; i<7; i++) {
        HomeLabel *label = [[HomeLabel alloc] init];
        label.tag = i;
        label.text = [self.childViewControllers[i] title];
       
        CGFloat labelX = i * labelW;
        label.frame = CGRectMake(labelX, labelY, labelW, labelH);
        [self.titileScrollView addSubview:label];
        
        //给label添加手势识别器
        [label addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelClick:)]];
        
        if (i == 0) {
            label.scale = 1.0;
        }
    }
    
    // 设置contentSize
    self.titileScrollView.contentSize = CGSizeMake(7*labelW, 0);
    self.contentScrollView.contentSize = CGSizeMake(7*[UIScreen mainScreen].bounds.size.width, 0);
}

/**
 *  label被点击了会调用
 */
- (void)labelClick:(UITapGestureRecognizer *)recognizer
{
    // 设置contentScrollView的偏移量以达到滚动效果
    NSInteger index = recognizer.view.tag;
    CGPoint offset = self.contentScrollView.contentOffset;
    offset.x = index * self.contentScrollView.frame.size.width;
    [self.contentScrollView setContentOffset:offset animated:YES];
}

#pragma mark - <UIScrollViewDelegate>
/**
 *  scrollView结束了滚动动画以后就会调用这个方法
 *  比如-setContentOffset:animated:YES方法执行的动画完毕后
 */
- (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;
    
    // 让对应的顶部标题居中显示
    HomeLabel *label = self.titileScrollView.subviews[index];
    CGPoint titleOffset = self.titileScrollView.contentOffset;
    titleOffset.x = label.center.x - width * 0.5;
    if (titleOffset.x < 0) {
        titleOffset.x = 0;
    }
    if (titleOffset.x > (self.titileScrollView.contentSize.width - width)) {
        titleOffset.x = self.titileScrollView.contentSize.width - width;
    }
    [self.titileScrollView setContentOffset:titleOffset animated:YES];
    
    // 让其他label回到最初的状态
    for (HomeLabel *otherLabel in self.titileScrollView.subviews) {
        if (otherLabel != label) {
            otherLabel.scale = 0.0;
        }
    }
    
    // 取出需要显示的控制器
    UITableViewController *willShowVc = self.childViewControllers[index];
    // 如果当前位置的控制器已经显示过
    if ([willShowVc isViewLoaded]) return;
    
    // 添加控制器的view到contentScrollView中
    willShowVc.view.frame = CGRectMake(offsetX, 0, width, height);
    [self.contentScrollView addSubview:willShowVc.view];
}

/**
 *  手指松开scrollView后,scrollView停止减速完毕就会调用这个方法
 */
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [self scrollViewDidEndScrollingAnimation:scrollView];
}

/**
 *  只要scrollView在滚动就会一直调用
 */
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGFloat scale = scrollView.contentOffset.x / scrollView.frame.size.width;
    if (scale < 0 || scale > self.titileScrollView.subviews.count-1) return;
    
    // 获取需要操作的左边label
    NSInteger leftIndex = scale;
    HomeLabel *leftLabel = self.titileScrollView.subviews[leftIndex];
    
    // 获取需要操作的右边label
    NSInteger rightIndex = leftIndex + 1;
    HomeLabel *rightLabel = (rightIndex == self.titileScrollView.subviews.count) ? nil :self.titileScrollView.subviews[rightIndex];
        
    // 右边比例
    CGFloat rightScale = scale - leftIndex;
    // 左边比例
    CGFloat leftScale = 1 - rightScale;

    // 设置label的scale属性
    leftLabel.scale = leftScale;
    rightLabel.scale = rightScale;
}

@end
3.自定义的label

//
//  HomeLabel.h


#import <UIKit/UIKit.h>

@interface HomeLabel : UILabel
/**
 *  label的比例值
 */
@property(nonatomic,assign) CGFloat scale;

@end
//
//  HomeLabel.m


#import "HomeLabel.h"

// 定义常量
const CGFloat RED = 0.4;
const CGFloat GREEN = 0.4;
const CGFloat BLUE = 0.4;

@implementation HomeLabel

- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        self.textColor = [UIColor colorWithRed:RED green:GREEN blue:BLUE alpha:1.0];
        self.textAlignment = NSTextAlignmentCenter;
        self.backgroundColor = [UIColor clearColor];
        self.userInteractionEnabled = YES;
    }
    return self;
}

- (void)setScale:(CGFloat)scale
{
    _scale = scale;
    
    CGFloat red = RED + (1 - RED) * scale;
    CGFloat green = GREEN + (0 - GREEN) * scale;
    CGFloat blue = BLUE + (0 - BLUE) * scale;
    
    self.textColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
    
    // 大小缩放比例
    CGFloat transformScale = 1 + scale * 0.2;
    self.transform = CGAffineTransformMakeScale(transformScale, transformScale);
}

@end
4.其他子控制器代理,举例

//
//  NewsViewController.m


#import "NewsViewController.h"

@interface NewsViewController ()

@end

@implementation NewsViewController

static NSString *ID = @"news";

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 注册cell
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID];
}

#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 20;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID forIndexPath:indexPath];
    
    cell.textLabel.text = [NSString stringWithFormat:@"%@ - %zd",self.title,indexPath.row];
    
    return cell;
}

@end






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值