iOS仿今日头条顶部新闻分页

仿今日头条顶部新闻分页

近日闲来无事总是刷头条,突然发现了一个有趣的现象,如下图:


当你滑动或者点击分页的名字的时候,不管当时那个分页在哪,最后都会被滚动到最中间.我又去翻了其他的资讯类的app,发现基本很多都是这样做的.抱着求知的心态,自己也搞一个类似的新闻分页,分析一下其中的原理.

本文的目录结构:

一.确定需求

我们来分解以下我们的需求,新闻分页一般包括两个部分,一个头部的滚动部分,一个底部的内容显示部分;

给张图更清晰:

  1. 分页部分要做的效果就是点击标题5的时候,标题5要滚动标题三的位置.
  2. 为了方便以后可以复用,我们需要将两个部分的代码隔离起来,独立成两个类
  3. 添加相关的控制代码,当不需要将标题居中的时候,也可以达到不居中的效果.
  4. 顶部标题最好是一个UIView视图,便于我们去自定义每个TAB的样子.

以上就是大概的设计和需求了,接下来就开始了我们最喜欢的动手环节了!!

二.代码架构

2.1 顶部分页设计

滚动视图在ios中有很多种,UIScrollView,UICollectionView和UITableView都可以达到要求,这里我们采用UIScrollView来制作我们的顶部滚动区域.

至于为啥要选择UIScrollView来作为滚动视图,我这说明一下:

  1. 根据需求,我们如果要将制定的标题滚动到中间,就需要计算到精确的偏移量,而UIScrollView刚好就可以帮我们实现到这点,当然UICollectionView和UITableView也是可以精确到的,因为他们继承了UIScrollView.但是能直接使用UIScrollView为啥我们要使用一个继承的备胎呢!!
  2. UICollectionView和UITableView的机制就是系统会回收屏幕以外区域的item以便于减少资源消耗.但是在这里我们有时需要计算屏幕以外的tab偏移量,显然他们是无法或者不方便做到的.
2.1.1 当我们需要顶部选中标题自动居中的情况

创建一个名叫TabScrollview的类集成UIScrollView,定义几个我们需要的关键属性


/**
 装载视图的数组
 */
@property (nonatomic,strong)NSArray<UIView*> *viewArr;


/**
 tab的宽度
 */
@property (nonatomic,assign)NSInteger tabWidth;

/**
 tab的高度
 */
@property (nonatomic,assign)NSInteger tabHeight;

/**
 tab下方标记线
 */
@property (nonatomic,strong)UIView *tagLine;
/**
 滚动的方向
 */
@property DirectionStyle direction;
/**
 记录位置下标
 */
@property (nonatomic,assign)NSInteger tagIndex;
/**
 tab下方标记线
 */
@property (nonatomic,strong)TabClickBlock clickBlock ;

viewArr是装载了所有头部tab视图(每栏的视图)的数组,假如你头部标题只想显示文字,你可以直接装载uiLabel.定义tab的宽度高度,以及一根标记线,方便我们标记滚动到哪个标题了,假如你不要标记线,只需要将标记线的颜色透明即可,
block 是为了回调我们选中的tab的下标,方便底部视图的切换.

#define tagLineheight 2 //默认标记线高度
#define tagLineColor [UIColor redColor]  //默认标记颜色
#define defTag 0  //默认标记0号位
#define openAutoCorrection true  //默认开启选中标题自动居中功能
typedef void(^TabClickBlock)(NSInteger index);
typedef NS_ENUM(NSInteger, DirectionStyle) {
    horizontal = 0,
    vertical = 1
};

然后定义一些基本的常量,比如标记线高度,颜色,默认的标题显示的小标,滚动的方向等等,还有一个重要的常量openAutoCorrection 就是我们设置的是否要将选中的标题居中的开关,不需要的时候直接这里设置false即可

另外我们要需要一个供外部调用的配置接口,该接口承担着大部分的赋值操作

-(void)configParameter:(DirectionStyle)directionStyle viewArr:(NSArray<UIView*>*)viewArr tabWidth:(NSInteger)tabWidth tabHeight:(NSInteger)tabHeight index:(NSInteger)index block:(TabClickBlock) clickBlock{
    _viewArr=viewArr;
    _tabHeight=tabHeight;
    _tabWidth=tabWidth;
    _direction=directionStyle;
    _clickBlock=clickBlock;
    if(_direction==horizontal){

        [self updateTag:index];
        [_viewArr enumerateObjectsUsingBlock:^(UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            obj.frame=CGRectMake(idx*_tabWidth, 0, _tabWidth, _tabHeight);
            [self addSubview:obj];
            [self setListener:obj index:idx];
        }];

        //添加标记线
        [self addSubview:_tagLine];
        self.contentSize=CGSizeMake(_tabWidth*_viewArr.count, 0);

    }else{
        [self updateTag:index];

        [_viewArr enumerateObjectsUsingBlock:^(UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            obj.frame=CGRectMake(0, idx*_tabHeight, _tabWidth, _tabHeight);
            [self addSubview:obj];
            [self setListener:obj index:idx];

        }];
        [self addSubview:_tagLine]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值