iOS知识收集20首页投稿(暂停使用,暂停投稿)

仿网易新闻首页UI布局

2016-04-14  本文已影响929人  袁俊亮技术博客

title : 仿网易新闻首页UI布局
category : UI


仿网易新闻首页UI布局

标签(空格分隔): UI


[TOC]

源码下载

链接: http://pan.baidu.com/s/1sliRak1 密码: 89jn

效果图(通过Storyboard+代码的方式实现)

仿网易新闻首页UI效果图.png

实现代码

JLHomeViewController

继承自UIViewController,主要文件,负责整个效果的逻辑和实现


#import "JLHomeViewController.h"
#import "JLTestViewController.h"
#import "JLHomeLabel.h"
#import "JLConst.h"

@interface JLHomeViewController ()<UIScrollViewDelegate>
/** 标题 */
@property (weak, nonatomic) IBOutlet UIScrollView *titleScrollView;
/** 内容 */
@property (weak, nonatomic) IBOutlet UIScrollView *contentScrollView;

@end

@implementation JLHomeViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.automaticallyAdjustsScrollViewInsets = NO;
    
    // 添加标题
    [self setupChildVc];
    
    // 添加子控制器
    [self setupTitle];
    
    // 默认显示第0个子控制器的
    [self scrollViewDidEndScrollingAnimation:self.contentScrollView];
}

#pragma mark - 初始化

/**
 *  添加标题
 */
- (void)setupTitle
{
    CGFloat labelW = 100;
    CGFloat labelY = 0;
    CGFloat labelH = self.titleScrollView.frame.size.height;
    for (int i = 0; i < 7; i++) {
        JLHomeLabel *label = [[JLHomeLabel alloc] init];
        CGFloat labelX = labelW * i;
        label.frame = CGRectMake(labelX, labelY, labelW, labelH);
        label.text = [self.childViewControllers[i] title];
        // 给label添加手势监听事件
        [label addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelClick:)]];
        
        // 给label绑定tag
        label.tag = i;
        [self.titleScrollView addSubview:label];
        
        if (i == 0) {
            label.scale = 1.0;
        }
    }
    
    // 设置titleScrollView的contentSize
    self.titleScrollView.contentSize = CGSizeMake(labelW * 7, 0);
    // 设置contentScrollView的contentSize
    // 注意这里的width要用屏幕的宽度,因为这时候加载出来的self.contentScrollView.frame.size.width是XIB的初始宽度600.
    // 由于self.view.autoresizingMask的原因使得控制器的view的宽度随着父控制器的frame的改变而改变。所以显示出来以后,self.contentScrollView.frame.size.width为正常的屏幕的宽度
    self.contentScrollView.contentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width * 7, 0);
}


/**
 *  添加子控制器
 */
- (void)setupChildVc
{
    JLTestViewController *testVc0 = [[JLTestViewController alloc] init];
    testVc0.title = @"国际";
    [self addChildViewController:testVc0];
    
    JLTestViewController *testVc1 = [[JLTestViewController alloc] init];
    testVc1.title = @"军事";
    [self addChildViewController:testVc1];
    
    JLTestViewController *testVc2 = [[JLTestViewController alloc] init];
    testVc2.title = @"社会";
    [self addChildViewController:testVc2];
    
    JLTestViewController *testVc3 = [[JLTestViewController alloc] init];
    testVc3.title = @"政治";
    [self addChildViewController:testVc3];
    
    JLTestViewController *testVc4 = [[JLTestViewController alloc] init];
    testVc4.title = @"经济";
    [self addChildViewController:testVc4];
    
    JLTestViewController *testVc5 = [[JLTestViewController alloc] init];
    testVc5.title = @"体育";
    [self addChildViewController:testVc5];
    
    JLTestViewController *testVc6 = [[JLTestViewController alloc] init];
    testVc6.title = @"娱乐";
    [self addChildViewController:testVc6];
}

#pragma mark - 手势监听事件
/**
 *  label被点击以后调用
 *
 *  @param tap 手势
 */
- (void)labelClick:(UIGestureRecognizer *)tap
{
    // 取出被点击的label的索引
    NSInteger index = tap.view.tag;
    
    // 让底部的内容scrollView滚动到对应的位置
    CGPoint offset = self.contentScrollView.contentOffset;
    offset.x = self.contentScrollView.frame.size.width * index;
    [self.contentScrollView setContentOffset:offset animated:YES];
}

#pragma mark - <UIScrollViewDelegate>
/**
 *  当scrollView结束了滚动动画以后就会调用这个方法
 *
 *  @param scrollView 当前滚动的scrollView
 */
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
    CGFloat scrollViewW = scrollView.frame.size.width;
    CGFloat scrollViewH = scrollView.frame.size.height;
    CGFloat offsetX = scrollView.contentOffset.x;
    
    // 当前位置需要显示的控制器的索引
    NSInteger index = offsetX / scrollViewW;
    
    // 让对应的顶部标题居中显示
    JLHomeLabel *label = self.titleScrollView.subviews[index];
    CGPoint titleOffset = self.titleScrollView.contentOffset;
    titleOffset.x = label.center.x - scrollViewW * 0.5;
    
    // 左边超出处理
    if (titleOffset.x < 0) titleOffset.x = 0;
    // 右边超出处理
    CGFloat maxTitleOffsetX = self.titleScrollView.contentSize.width - scrollViewW;
    if (titleOffset.x > maxTitleOffsetX) titleOffset.x = maxTitleOffsetX;
    
    [self.titleScrollView setContentOffset:titleOffset animated:YES];
    
    // 让其他label回到最初的状态
    for (JLHomeLabel *otherLabel in self.titleScrollView.subviews) {
        if (otherLabel != label) otherLabel.scale = 0.0;
    }

    // 取出需要显示的控制器
    UIViewController *willShowVc = self.childViewControllers[index];
    
    // 如果当前位置的控制器的view已经显示过了,就直接返回
    if ([willShowVc isViewLoaded]) return;
    
    // 添加控制器的view到contentScrollView中
    willShowVc.view.frame = CGRectMake(offsetX, 0, scrollViewW, scrollViewH);
    [self.contentScrollView addSubview:willShowVc.view];

}

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

- (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;
    JLHomeLabel *leftLabel = self.titleScrollView.subviews[leftIndex];
    
    // 获得需要操作的右边的label
    NSInteger rightIndex = leftIndex + 1;
    JLHomeLabel *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;
}

@end

JLTestViewController

继承自UITableViewController,测试文件,用于颜色内容控制器样式

.m文件


#import "JLTestViewController.h"

@interface JLTestViewController ()

@end
static NSString *ID = @"testCell";

@implementation JLTestViewController


- (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 50;
}


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

@end

JLHomeLabel

继承自UILabel,自定义的label,对UILabel的一个简单封装

.h文件

#import <UIKit/UIKit.h>

@interface JLHomeLabel : UILabel

/** label的缩放比例 */
@property (nonatomic, assign) CGFloat scale;

@end

.m文件


#import "JLHomeLabel.h"
#import "JLConst.h"

@implementation JLHomeLabel

- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        self.font = [UIFont systemFontOfSize:15];
        self.textColor = [UIColor colorWithRed:JLRed green:JLGreen blue:JLBlue alpha:JLAlpha];
        self.textAlignment = NSTextAlignmentCenter;
        // 使label和用户之间可交互
        self.userInteractionEnabled = YES;
    }
    return self;
}

- (void)setScale:(CGFloat)scale
{
    CGFloat red = JLRed + (1 - JLRed) * scale;
    CGFloat green = JLGreen + (0 - JLGreen) * scale;
    CGFloat blue = JLBlue + (0 - JLBlue) * 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

JLConst

用于存放全局的常量

.h文件

#import <UIKit/UIKit.h>

UIKIT_EXTERN const CGFloat JLRed;
UIKIT_EXTERN const CGFloat JLGreen;
UIKIT_EXTERN const CGFloat JLBlue;
UIKIT_EXTERN const CGFloat JLAlpha;

.m文件

#import <UIKit/UIKit.h>

const CGFloat JLRed = 0;
const CGFloat JLGreen = 0;
const CGFloat JLBlue = 0;
const CGFloat JLAlpha = 1.0;

上一篇下一篇

猜你喜欢

热点阅读