网易新闻频道标签

版本记录

版本号 时间
V1.0 2017.06.04

前言

网易新闻是门户网站,和今日头条类似,都是标签频道,每个频道都有对应的新闻,这一篇主要就是模拟网易新闻。

网易新闻图例

下面还是先看一下网易新闻的几个截图。

图1
图2

网易新闻模拟实现

下面我们先看一下代码组织结构。

网易新闻代码组织结构

下面直接看代码

1. JJHomeVC.h

#import <UIKit/UIKit.h>

@interface JJHomeVC : UIViewController

@end
2. JJHomeVC.m

#import "JJHomeVC.h"
#import "JJFlowLayout.h"
#import "JJChannelModel.h"
#import "JJChannelLabel.h"
#import "JJCollectionViewCell.h"

@interface JJHomeVC () <UIScrollViewDelegate, UICollectionViewDelegate, UICollectionViewDataSource>

@property (nonatomic, strong) UIScrollView *channelScrollView;
@property (nonatomic, strong) UICollectionView *newsCollectionView;
@property (nonatomic, strong) UICollectionViewFlowLayout *collectionLayout;
@property (nonatomic, strong) NSArray *channelArr;
@property (nonatomic, strong) NSMutableArray <JJChannelLabel *>*channelLabelArrM;

@end

@implementation JJHomeVC

static NSString * const kJJHomeVCCollectionViewReuserIdentify = @"kJJHomeVCCollectionViewReuserIdentify";

#pragma mark - Override Base Function

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.title = @"网易新闻";
    
    self.view.backgroundColor = [UIColor whiteColor];
    self.channelLabelArrM = [NSMutableArray array];
    [self setupUI];
    self.automaticallyAdjustsScrollViewInsets = NO;
    [self createChannelLabels];
    NSLog(@"%@----",self.channelArr);
}

#pragma mark - Object Private Function

- (void)createChannelLabels
{
    self.channelArr = [JJChannelModel gainChannelArr];
    
    CGFloat labelWidth = 80.0;
    CGFloat lableHeight = self.channelScrollView.bounds.size.height;
    
    for (NSInteger i = 0; i < self.channelArr.count; i++) {
        JJChannelLabel *label = [[JJChannelLabel alloc] init];
        [self.channelScrollView addSubview:label];
        CGFloat labelMinX = i * labelWidth;
        label.frame = CGRectMake(labelMinX, 0.0, labelWidth, lableHeight);
        
        JJChannelModel *model = self.channelArr[i];
        label.text = model.tname;
        
        UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapDidTapped:)];
        [label addGestureRecognizer:tapGesture];
        label.userInteractionEnabled = YES;
        label.tag = i;
        [self.channelLabelArrM addObject:label];
        
        if (i == 0) {
            label.scale = 1.0;  //默认第一个为最大的缩放比
        }
    }
    
    self.channelScrollView.contentSize = CGSizeMake(labelWidth * self.channelArr.count, 0);

}

- (void)setupUI
{
    //scrollView
    UIScrollView *channelScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 64.0, kJJCommonScreenWidth, 80.0)];
    channelScrollView.backgroundColor = [UIColor whiteColor];
    channelScrollView.showsHorizontalScrollIndicator = NO;
    [self.view addSubview:channelScrollView];
    self.channelScrollView = channelScrollView;
    
    //collectionView
    JJFlowLayout *layout = [[JJFlowLayout alloc] init];
    UICollectionView *newsCollectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0, 144.0, kJJCommonScreenWidth, kJJCommonScreenHeight - 144.0) collectionViewLayout:layout];
    newsCollectionView.pagingEnabled = YES;
    [newsCollectionView registerClass:[JJCollectionViewCell class] forCellWithReuseIdentifier:kJJHomeVCCollectionViewReuserIdentify];
    newsCollectionView.delegate = self;
    newsCollectionView.dataSource = self;
    [self.view addSubview:newsCollectionView];
    self.newsCollectionView = newsCollectionView;
    
}

#pragma mark - Action && Notification

- (void)tapDidTapped:(UITapGestureRecognizer *)tapGesture
{
    JJChannelLabel *selectedChannelLabel = (JJChannelLabel *)tapGesture.view;
    
    //计算选中标签滚动到居中时,需要的偏移量
    CGFloat offsetX = selectedChannelLabel.center.x - (self.view.bounds.size.width * 0.5);
    //设置最大和最小滚动的临界值
    CGFloat minOffset = 0;
    CGFloat maxOffset = self.channelScrollView.contentSize.width - self.view.bounds.size.width;
    //判断是否超出了最大和最小滚动范围
    if (offsetX < minOffset) {
        offsetX = minOffset;
    }
    if(offsetX > maxOffset){
        offsetX = maxOffset;
    }
    
    //把channelScrollView滚动到指定的位置
    [self.channelScrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES];
    
    //把新闻滚动视图滚动到指定的位置
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:selectedChannelLabel.tag inSection:0];
    [self.newsCollectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
    
    NSInteger index = selectedChannelLabel.tag;
    
    // 需要把选中的标签设置最大的缩放比,非选中的还原
    for (NSInteger i = 0; i < self.channelLabelArrM.count; i++) {
        JJChannelLabel *label  = self.channelLabelArrM[i];
        if (index == i) {
            label.scale = 1.0;
        }
        else {
            label.scale = 0.0;
        }
    }
}

#pragma mark - UIScrollViewDelegate

//底部滚动视图联动频道标签
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    //获取新闻滚动视图的偏移量,然后简介获取滚动的到index
    NSInteger index = scrollView.contentOffset.x/kJJCommonScreenWidth;
    
    //拿着新闻滚动视图是滚动时,获取的index,去标签数组里面找对应的标签,计算居中时需要滚动的偏移量
    JJChannelLabel *selectedLabel = self.channelLabelArrM[index];
    
    //计算选中标签滚动到居中时,需要的偏移量
    CGFloat offsetX = selectedLabel.center.x - (self.view.bounds.size.width * 0.5);
    //设置最大和最小滚动的临界值
    CGFloat minOffset = 0;
    CGFloat maxOffset = self.channelScrollView.contentSize.width - self.view.bounds.size.width;
    //判断是否超出了最大和最小滚动范围
    if (offsetX < minOffset) {
        offsetX = minOffset;
    }
    else if(offsetX > maxOffset){
        offsetX = maxOffset;
    }
    [self.channelScrollView setContentOffset:CGPointMake(offsetX, 0) animated:YES];
}

//频道标签的缩放
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    //获取偏移量
    CGFloat indexOffsetX = scrollView.contentOffset.x / self.view.bounds.size.width;
    
    //滚动的索引
    NSInteger index = scrollView.contentOffset.x / self.view.bounds.size.width;
    
    //偏移百分比
    CGFloat percent = indexOffsetX - index;
    
    //要实现标签的缩放,需要计算四个值:左边标签索引,右边标签索引,左边标签缩放比,右边标签缩放比
    CGFloat rightScale = percent;
    CGFloat leftScale = 1 - rightScale;
    NSInteger leftIndex = index;
    NSInteger rightIndex = leftIndex + 1;

    
    //获取左边的标签
    JJChannelLabel *leftChannelLabel = self.channelLabelArrM[leftIndex];
    leftChannelLabel.scale = leftScale;
    
    //获取右边的标签:防止脚标越界崩溃
    if (rightIndex < self.channelLabelArrM.count) {
        JJChannelLabel *rightLabel = self.channelLabelArrM[rightIndex];
        rightLabel.scale = rightScale;
    }
}

#pragma mark - UICollectionViewDataSource && UITableViewDelegate

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return self.channelArr.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    JJCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kJJHomeVCCollectionViewReuserIdentify forIndexPath:indexPath];
    JJChannelModel *model = self.channelArr[indexPath.item];
    NSString *URLStr = [NSString stringWithFormat:@"article/list/%@/0-20.html",model.tid];
    cell.URLStr = URLStr;
    return cell;
}

@end
3. JJChannelModel.h

#import <Foundation/Foundation.h>

@interface JJChannelModel : NSObject

@property (nonatomic, copy) NSString *tname;
@property (nonatomic, copy) NSString *tid;

+ (NSArray *)gainChannelArr;

@end
4. JJChannelModel.m

#import "JJChannelModel.h"

@implementation JJChannelModel

#pragma mark - Override Base Function

- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
    //这里什么都不做
}

- (NSString *)description
{
    return [NSString stringWithFormat:@"%@ -- %@",self.tname,self.tid];
}

#pragma mark - Class Private Function

+ (instancetype)channelModelWithDict:(NSDictionary *)dict
{
    JJChannelModel *model = [[JJChannelModel alloc] init];
    [model setValuesForKeysWithDictionary:dict];
    return model;
}

#pragma mark - Class Public Function

+ (NSArray *)gainChannelArr
{
    NSString *filePathStr = [[NSBundle mainBundle] pathForResource:@"topic_news.json"  ofType:nil];
    NSData *jsonData = [NSData dataWithContentsOfFile:filePathStr];
    NSDictionary *resultDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:NULL];
    NSArray *contentArr = [resultDict objectForKey:@"tList"];
    NSMutableArray *contentArrM = [NSMutableArray arrayWithCapacity:contentArr.count];
    [contentArr enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        JJChannelModel *model = [JJChannelModel channelModelWithDict:obj];
        [contentArrM addObject:model];
    }];
    
    //按照tid从小到大排序
    [contentArrM sortUsingComparator:^NSComparisonResult(JJChannelModel* obj1,JJChannelModel* obj2) {
        return [obj1.tid compare:obj2.tid];
    }];

    return contentArrM.copy;
}

@end

5. JJNewsModel.h

#import <Foundation/Foundation.h>

@interface JJNewsModel : NSObject

@property (nonatomic,copy) NSString *title;             // 新闻标题
@property (nonatomic,copy) NSString *imgsrc;            // 新闻图标
@property (nonatomic,copy) NSString *source;            // 新闻来源
@property (nonatomic,strong) NSNumber *replyCount;      // 新闻回复数
@property (nonatomic, strong) NSArray *imgextra;        // 多张配图
@property (nonatomic, assign) BOOL imgType;             // 大图标记

@end
6. JJNewsModel.m

#import "JJNewsModel.h"

@implementation JJNewsModel

- (NSString *)description
{
    return [NSString stringWithFormat:@"%@-%@-%@",self.title,self.source,self.replyCount];
}

@end
7. JJNetworkTool.h

#import <AFNetworking/AFNetworking.h>

@interface JJNetworkTool : AFHTTPSessionManager

/// 单例的全局访问点
+ (instancetype)sharedTool;

/**
 封装的网络请求工具类的GET方法
 
 @param URLString  请求的地址
 @param parameters 请求的参数
 @param success    成功的回调
 @param failed     失败的回调
 */
- (void)GETWithURLString:(NSString *)URLString parameters:(id)parameters success:(void(^)(id responseObject))success failed:(void(^)(NSError *error))failed;

@end

8. JJNetworkTool.m

#import "JJNetworkTool.h"

@implementation JJNetworkTool

#pragma mark - Class Public Function

+ (instancetype)sharedTool
{
    static JJNetworkTool *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        NSURL *baseURL = [NSURL URLWithString:@"http://c.m.163.com/nc/"];
        instance = [[self alloc] initWithBaseURL:baseURL];
        // 增加AFN支持的文件类型
        instance.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", @"text/plain", nil];
    });
    return instance;
}

#pragma mark - Object Private Function

// AFHTTPSessionManager发送GET请求
- (void)GETWithURLString:(NSString *)URLString parameters:(id)parameters success:(void (^)(id))success failed:(void (^)(NSError *))failed
{
    [self GET:URLString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        if (success) {
            success(responseObject);
        }
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (failed) {
            failed(error);
        }
    }];
}

@end
9. JJFlowLayout.h

#import <UIKit/UIKit.h>

@interface JJFlowLayout : UICollectionViewFlowLayout

@end

10. JJFlowLayout.m
#import "JJFlowLayout.h"

@implementation JJFlowLayout

- (void)prepareLayout
{
    [super prepareLayout];
    
    self.itemSize = CGSizeMake(kJJCommonScreenWidth, kJJCommonScreenHeight - 144.0);
    self.minimumLineSpacing = 0.0;
    self.minimumInteritemSpacing = 0.0;
    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
}

@end

11. JJChannelLabel.h

#import <UIKit/UIKit.h>

@interface JJChannelLabel : UILabel

@property (nonatomic, assign) CGFloat scale;    //缩放比 0.0~1.0

@end
12. JJChannelLabel.m

#import "JJChannelLabel.h"

@implementation JJChannelLabel

#pragma mark - Override Base Function

- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self setupUI];
    }
    return self;
}

#pragma mark - Object Private Function

- (void)setupUI
{
    self.textAlignment = NSTextAlignmentCenter;
    self.font = [UIFont systemFontOfSize:16.0];
}

#pragma mark - Getter && Setter

- (void)setScale:(CGFloat)scale
{
    _scale = scale;
    
    //标签渐变色 黑---红
    self.textColor = [UIColor colorWithRed:scale green:0 blue:0 alpha:1.0];
    
    //标签缩放
    CGFloat minScale = 1.0;
    CGFloat maxScale = 1.5;
    scale = minScale + scale * (maxScale - minScale);
    self.transform = CGAffineTransformMakeScale(scale, scale);
    
}

@end

13. JJCollectionViewCell.h

#import <UIKit/UIKit.h>

@interface JJCollectionViewCell : UICollectionViewCell

@property (nonatomic, copy) NSString *URLStr;

@end
14. JJCollectionViewCell.m

#import "JJCollectionViewCell.h"
#import "JJThreeMiddlePictureCell.h"
#import "JJOneBigPictureCell.h"
#import "JJOneSmallPictureCell.h"
#import "JJNewsModel.h"
#import "JJNetworkTool.h"

@interface JJCollectionViewCell () <UITableViewDelegate, UITableViewDataSource>

@property (nonatomic, strong) UITableView *newsTableView;
@property (nonatomic, strong) NSMutableArray *newsListArrM;

@end

@implementation JJCollectionViewCell

static NSString * const kJJOneBigPictureCellReuseIdentify = @"kJJOneBigPictureCellReuseIdentify";
static NSString * const kJJOneSmallPictureCellReuseIdentify = @"kJJJOneSmallPictureCellReuseIdentify";
static NSString * const kJJThreeMiddlePictureCellReuseIdentify = @"kJJThreeMiddlePictureCellReuseIdentify";

#pragma mark - Override Base Function

- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self setupUI];
        self.backgroundColor = [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1];//随机色
        self.newsListArrM = [NSMutableArray array];
    }
    return self;
}

#pragma mark - Object Private Function

- (void)setupUI
{
    //tableView
    UITableView *newsTableView = [[UITableView alloc] initWithFrame:self.frame];
    newsTableView.delegate = self;
    newsTableView.dataSource = self;
    [newsTableView registerClass:[JJOneBigPictureCell class] forCellReuseIdentifier:kJJOneBigPictureCellReuseIdentify];
    [newsTableView registerClass:[JJThreeMiddlePictureCell class] forCellReuseIdentifier:kJJThreeMiddlePictureCellReuseIdentify];
    [newsTableView registerClass:[JJOneSmallPictureCell class] forCellReuseIdentifier:kJJOneSmallPictureCellReuseIdentify];
    [self.contentView addSubview:newsTableView];
    self.newsTableView = newsTableView;
}

#pragma mark - Setter && Getter

- (void)setURLStr:(NSString *)URLStr
{
    _URLStr = URLStr;
    
    [[JJNetworkTool sharedTool] GETWithURLString:URLStr parameters:nil success:^(NSDictionary *responseObject) {
        
        NSString *key = responseObject.keyEnumerator.nextObject;
        NSArray *dictArr = responseObject[key];
        NSArray *listArr = [NSArray yy_modelArrayWithClass:[JJNewsModel class] json:dictArr];
        [self.newsListArrM addObjectsFromArray:listArr];
        [self.newsTableView reloadData];
        
    } failed:^(NSError *error) {
        NSLog(@"%@",error);
    }];
}

#pragma mark - UITableViewDelegate && UITableViewDataSource

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.newsListArrM.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    JJNewsModel *newModel = self.newsListArrM[indexPath.row];
    if (newModel.imgType == YES) {
        JJOneBigPictureCell *cell = [tableView dequeueReusableCellWithIdentifier:kJJOneBigPictureCellReuseIdentify forIndexPath:indexPath];
        cell.newsModel = newModel;
        return cell;
    }
    else if(newModel.imgextra.count == 2) {
        JJThreeMiddlePictureCell *cell = [tableView dequeueReusableCellWithIdentifier:kJJThreeMiddlePictureCellReuseIdentify forIndexPath:indexPath];
        cell.newsModel = newModel;
        return cell;
    }
    else {
        JJOneSmallPictureCell *cell = [tableView dequeueReusableCellWithIdentifier:kJJOneSmallPictureCellReuseIdentify forIndexPath:indexPath];
        cell.newsModel = newModel;
        return cell;
    }
    
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    JJNewsModel *newModel = self.newsListArrM[indexPath.row];
    if (newModel.imgType == YES) {
        return  180.0;
    }
    else if (newModel.imgextra.count == 2) {
        return 140.0;
    }
    return 100.0;
}

@end

15. JJOneSmallPictureCell.h

#import <UIKit/UIKit.h>

@class JJNewsModel;

@interface JJOneSmallPictureCell : UITableViewCell

@property (nonatomic, strong) JJNewsModel *newsModel;

@end

16. JJOneSmallPictureCell.m
#import "JJOneSmallPictureCell.h"
#import "JJNewsModel.h"

@interface JJOneSmallPictureCell ()

@property (nonatomic, strong) UIImageView *picImageView;
@property (nonatomic, strong) UILabel *desclabel;
@property (nonatomic, strong) UILabel *sourceLabel;
@property (nonatomic, strong) UILabel *numLabel;

@end

@implementation JJOneSmallPictureCell

#pragma mark - Override Base Function

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        [self setupUI];
    }
    return self;
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    //新闻图片
    [self.picImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        
        make.width.height.equalTo(@80);
        make.centerY.equalTo(self);
        make.left.equalTo(self).offset(10.0);
    }];
    
//    self.picImageView.frame = CGRectMake(10.0, CGRectGetMidY(self.frame), 80, 80);
    
    //新闻简介
    [self.desclabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.picImageView);
        make.left.equalTo(self.picImageView.mas_right).offset(6.0);
        make.width.equalTo(@(kJJCommonScreenWidth - 80 - 10 - 10 - 6));
        make.height.equalTo(@15);
    }];
//    self.desclabel.frame = CGRectMake(CGRectGetMaxX(self.picImageView.frame) + 6.0, CGRectGetMinY(self.picImageView.frame), kJJCommonScreenWidth - 80 - 10 - 10 - 6, 15);
    
    //新闻来源
    [self.sourceLabel sizeToFit];
    [self.sourceLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(self.picImageView);
        make.left.equalTo(self.desclabel);
    }];
    
//    self.sourceLabel.frame = CGRectMake(CGRectGetMinX(self.desclabel.frame), CGRectGetMaxY(self.picImageView.frame) - CGRectGetHeight(self.sourceLabel.frame), CGRectGetWidth(self.sourceLabel.frame), CGRectGetHeight(self.sourceLabel.frame));
    
    //新闻评论数
    [self.numLabel sizeToFit];
    [self.numLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(self).offset(- 10.0);
        make.bottom.equalTo(self.sourceLabel);
    }];
//    self.numLabel.frame = CGRectMake(CGRectGetWidth(self.frame) - 10.0 - CGRectGetWidth(self.numLabel.frame), CGRectGetMinY(self.sourceLabel.frame), CGRectGetWidth(self.numLabel.frame), CGRectGetHeight(self.numLabel.frame));
}

#pragma mark - Object Private Function

- (void)setupUI
{
    self.backgroundColor = [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1];//随机色
    
    //图示
    UIImageView *picImageView = [[UIImageView alloc] init];
    [self.contentView addSubview:picImageView];
    picImageView.image = [UIImage imageNamed:@"placeholderImage"];
    self.picImageView = picImageView;
    
    //新闻简介
    UILabel *desclabel = [[UILabel alloc] init];
    desclabel.text = @"我来自火星";
    desclabel.font = [UIFont systemFontOfSize:14.0];
    [self.contentView addSubview:desclabel];
    self.desclabel = desclabel;
    
    //新闻来源
    UILabel *sourceLabel = [[UILabel alloc] init];
    sourceLabel.text = @"网易新闻";
    sourceLabel.font = [UIFont systemFontOfSize:14.0];
    [self.contentView addSubview:sourceLabel];
    self.sourceLabel = sourceLabel;

    //评论数
    UILabel *numLabel = [[UILabel alloc] init];
    numLabel.text = @"99999";
    numLabel.font = [UIFont systemFontOfSize:14.0];
    [self.contentView addSubview:numLabel];
    self.numLabel = numLabel;

}

#pragma mark - Getter && Setter 

- (void)setNewsModel:(JJNewsModel *)newsModel
{
    _newsModel = newsModel;
    
    [self.picImageView sd_setImageWithURL:[NSURL URLWithString:newsModel.imgsrc] placeholderImage:[UIImage imageNamed:@"placeholderImage"]];
    self.desclabel.text = newsModel.title;
    self.sourceLabel.text = newsModel.source;
    // 需要把NSNumber转成NSString
    self.numLabel.text = [NSString stringWithFormat:@"%@",newsModel.replyCount]?:@"";
}

@end
17. JJOneBigPictureCell.h

#import <UIKit/UIKit.h>

@class JJNewsModel;

@interface JJOneBigPictureCell : UITableViewCell

@property (nonatomic, strong) JJNewsModel *newsModel;

@end
18. JJOneBigPictureCell.m

#import "JJOneBigPictureCell.h"
#import "JJNewsModel.h"

@interface JJOneBigPictureCell ()

@property (nonatomic, strong) UIImageView *picImageView;
@property (nonatomic, strong) UILabel *desclabel;
@property (nonatomic, strong) UILabel *sourceLabel;
@property (nonatomic, strong) UILabel *numLabel;

@end

@implementation JJOneBigPictureCell

#pragma mark - Override Base Function

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        [self setupUI];
    }
    return self;
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    //新闻图片
    [self.picImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.height.equalTo(@120);
        make.left.equalTo(self).offset(10.0);
        make.width.equalTo(@(kJJCommonScreenWidth - 10 - 10));
        make.centerY.equalTo(self);
    }];
    
    //新闻简介
    [self.desclabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(self.picImageView.mas_top).offset(-6.0);
        make.left.equalTo(self.picImageView);
        make.width.equalTo(@(kJJCommonScreenWidth - 10 - 10));
    }];
    
    //新闻来源
    [self.sourceLabel sizeToFit];
    [self.sourceLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.picImageView.mas_bottom).offset(6.0);
        make.left.equalTo(self.picImageView);
    }];
    
    //新闻评论数
    [self.numLabel sizeToFit];
    [self.numLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(self.picImageView);
        make.centerY.equalTo(self.sourceLabel);
    }];
}

#pragma mark - Object Private Function

- (void)setupUI
{
    self.backgroundColor = [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1];//随机色
    
    //图示
    UIImageView *picImageView = [[UIImageView alloc] init];
    picImageView.image = [UIImage imageNamed:@"placeholderImage"];
    [self.contentView addSubview:picImageView];
    self.picImageView = picImageView;
    
    //新闻简介
    UILabel *desclabel = [[UILabel alloc] init];
    desclabel.text = @"我来自火星";
    desclabel.font = [UIFont systemFontOfSize:14.0];
    [self.contentView addSubview:desclabel];
    self.desclabel = desclabel;
    
    //新闻来源
    UILabel *sourceLabel = [[UILabel alloc] init];
    sourceLabel.text = @"网易新闻";
    sourceLabel.font = [UIFont systemFontOfSize:14.0];
    [self.contentView addSubview:sourceLabel];
    self.sourceLabel = sourceLabel;
    
    //评论数
    UILabel *numLabel = [[UILabel alloc] init];
    numLabel.text = @"99999";
    numLabel.font = [UIFont systemFontOfSize:14.0];
    [self.contentView addSubview:numLabel];
    self.numLabel = numLabel;
}

#pragma mark - Getter && Setter

- (void)setNewsModel:(JJNewsModel *)newsModel
{
    _newsModel = newsModel;
    
    [self.picImageView sd_setImageWithURL:[NSURL URLWithString:newsModel.imgsrc] placeholderImage:[UIImage imageNamed:@"placeholderImage"]];
    self.desclabel.text = newsModel.title;
    self.sourceLabel.text = newsModel.source;
    self.numLabel.text = [NSString stringWithFormat:@"%@",newsModel.replyCount]?:@"";

}

@end
19. JJThreeMiddlePictureCell.h

#import <UIKit/UIKit.h>

@class JJNewsModel;

@interface JJThreeMiddlePictureCell : UITableViewCell

@property (nonatomic, strong) JJNewsModel *newsModel;

@end
20. JJThreeMiddlePictureCell.m

#import "JJThreeMiddlePictureCell.h"
#import "JJNewsModel.h"

@interface JJThreeMiddlePictureCell ()

@property (nonatomic, strong) UIImageView *picImageViewLeft;
@property (nonatomic, strong) UIImageView *picImageViewMiddle;
@property (nonatomic, strong) UIImageView *picImageViewRight;
@property (nonatomic, strong) UILabel *desclabel;
@property (nonatomic, strong) UILabel *sourceLabel;
@property (nonatomic, strong) UILabel *numLabel;

@end

@implementation JJThreeMiddlePictureCell

#pragma mark - Override Base Function

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        [self setupUI];
    }
    return self;
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    CGFloat marginWidth = (kJJCommonScreenWidth - 10 * 4)/3;
    
    //左边图片
    [self.picImageViewLeft mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self).offset(10.0);
        make.centerY.equalTo(self);
        make.height.equalTo(@80);
        make.width.equalTo(@(marginWidth));
    }];
    
    //中间图片
    [self.picImageViewMiddle mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.picImageViewLeft);
        make.left.equalTo(self.picImageViewLeft.mas_right).offset(10.0);
        make.height.equalTo(self.picImageViewLeft);
        make.width.equalTo(@(marginWidth));

    }];
    
    //右边图片
    [self.picImageViewRight mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(self.picImageViewLeft);
        make.left.equalTo(self.picImageViewMiddle.mas_right).offset(10.0);
        make.width.height.equalTo(self.picImageViewLeft);
        make.width.equalTo(@(marginWidth));
    }];

    
    //新闻简介
    [self.desclabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(self.picImageViewLeft.mas_top).offset(-10.0);
        make.left.equalTo(self.picImageViewLeft);
        make.width.equalTo(@(kJJCommonScreenWidth - 10 - 10));
    }];
    
    //新闻来源
    [self.sourceLabel sizeToFit];
    [self.sourceLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.picImageViewLeft.mas_bottom).offset(10.0);
        make.left.equalTo(self.picImageViewLeft);
    }];
    
    //新闻评论数
    [self.numLabel sizeToFit];
    [self.numLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(self.picImageViewRight);
        make.centerY.equalTo(self.sourceLabel);
    }];
}

#pragma mark - Object Private Function

- (void)setupUI
{
    self.backgroundColor = [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1];//随机色
    
    //左边图示
    UIImageView *picImageViewLeft = [[UIImageView alloc] init];
    picImageViewLeft.image = [UIImage imageNamed:@"placeholderImage"];
    [self.contentView addSubview:picImageViewLeft];
    self.picImageViewLeft = picImageViewLeft;
    
    //中间图示
    UIImageView *picImageViewMiddle = [[UIImageView alloc] init];
    picImageViewMiddle.image = [UIImage imageNamed:@"placeholderImage"];
    [self.contentView addSubview:picImageViewMiddle];
    self.picImageViewMiddle = picImageViewMiddle;
    
    //右边图示
    UIImageView *picImageViewRight = [[UIImageView alloc] init];
    picImageViewRight.image = [UIImage imageNamed:@"placeholderImage"];
    [self.contentView addSubview:picImageViewRight];
    self.picImageViewRight = picImageViewRight;
    
    //新闻简介
    UILabel *desclabel = [[UILabel alloc] init];
    desclabel.text = @"我来自火星";
    desclabel.font = [UIFont systemFontOfSize:14.0];
    [self.contentView addSubview:desclabel];
    self.desclabel = desclabel;
    
    //新闻来源
    UILabel *sourceLabel = [[UILabel alloc] init];
    sourceLabel.text = @"网易新闻";
    sourceLabel.font = [UIFont systemFontOfSize:14.0];
    [self.contentView addSubview:sourceLabel];
    self.sourceLabel = sourceLabel;
    
    //评论数
    UILabel *numLabel = [[UILabel alloc] init];
    numLabel.text = @"99999";
    numLabel.font = [UIFont systemFontOfSize:14.0];
    [self.contentView addSubview:numLabel];
    self.numLabel = numLabel;
}

#pragma mark - Getter && Setter

- (void)setNewsModel:(JJNewsModel *)newsModel
{
    _newsModel = newsModel;
    
    [self.picImageViewLeft sd_setImageWithURL:[NSURL URLWithString:newsModel.imgsrc] placeholderImage:[UIImage imageNamed:@"placeholderImage"]];
    self.desclabel.text = newsModel.title;
    self.sourceLabel.text = newsModel.source;
    self.numLabel.text = [NSString stringWithFormat:@"%@",newsModel.replyCount]?:@"";
    
    //中间图片
    NSDictionary *imgDict = newsModel.imgextra[0];
    NSString *imgsrc = imgDict[@"imgsrc"];
    [self.picImageViewMiddle sd_setImageWithURL:[NSURL URLWithString:imgsrc] placeholderImage:[UIImage imageNamed:@"placeholderImage"]];
    
    //右边图片
    NSDictionary *imgRightDict = newsModel.imgextra[1];
    NSString *imgsrcRight = imgRightDict[@"imgsrc"];
    [self.picImageViewRight sd_setImageWithURL:[NSURL URLWithString:imgsrcRight] placeholderImage:[UIImage imageNamed:@"placeholderImage"]];
}

@end

网易模拟结果

下面看一下网易新闻的标签滚动和显示结果。

网易新闻

后记

  这个只是网易新闻的demo,模拟标签的滚动和新闻的显示,未完,待续~~~

奋斗
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • 腾讯新闻客户端(V5.1.5.29)产品体验报告 一、概述 1、体验环境 体验产品:腾讯新闻客户端 软件版本:5....
    村里搬砖的月野兔阅读 2,329评论 1 15
  • 父亲前几天给我发了一个红包,16.8元。 父亲给我打电话的时候,刚好手上有点事在忙,于是我告诉他我晚点给他回过去就...
    思洁大太阳啦啦啦阅读 255评论 0 1
  • 我偷偷的把那些自卑,放在记忆的深处.它就像一个无恶不作的恶魔,我想尽无数办法终于打败它.把它封印在我最偏僻最深处的...
    Soul麦芽阅读 1,288评论 51 49
  • 一、说明   笔记主要是记录一些本人在开发当中的学习和使用笔记。笔记内容包含一些本人觉得重要的知识点、本人易犯的错...
    lipyhui阅读 275评论 0 1
  • 河河已经一岁多了,目前似乎还是散养状态,关于她的未来,当父亲的有责任仔细思考规划。 传统的方式是和我这一代相同的路...
    行动是第一生产力阅读 139评论 1 0