美文网首页UI进价常用的第三方iOS开发技巧
iOS开发之带你5分钟封装一个时间轴

iOS开发之带你5分钟封装一个时间轴

作者: Qinz | 来源:发表于2017-05-23 17:58 被阅读5054次
    Qinz
    时间轴在一些app中用的场景还不少,原理实现起来较为简单,下面我们就来动手封装一个比较常用的时间轴,具体效果看下图:
    Qinz
    • 1.首先我们创建一个UIView,在上面放一个tableView,声明一个方法,传递两个参数,第一个参数是需要将该时间轴放在哪个视图上,第二个参数是传递数据源,头文件下:
    #import <UIKit/UIKit.h>
    
    @interface QinzTimeLine : UIView
    
    @property (nonatomic, strong) NSArray *titleArr;
    
    -(void)setSuperView:(UIView*)superView DataArr:(NSMutableArray*)dataArr;
    
    @end
    
    • 2.我们再来看看.m文件,也就是最简单的tableView的应用,这里有一个 [self.tableView cellHeightForIndexPath:indexPath model:model keyPath:@"model" cellClass:[TimeLineCell class] contentViewWidth:self.frame.size.width]方法是用到了SDAutoLayout这个库用来自动计算cell高度的
    #import "QinzTimeLine.h"
    #import "SDAutoLayout.h"
    #import "TimeLineCell.h"
    
    @interface QinzTimeLine ()<UITableViewDelegate,UITableViewDataSource>
    
    @property (nonatomic, strong) UITableView *tableView;
    @property (nonatomic, strong) NSMutableArray *dataArr;
    
    @end
    
    @implementation QinzTimeLine
    
    -(void)setSuperView:(UIView *)superView DataArr:(NSMutableArray *)dataArr{
    
        self.frame = superView.bounds;
        [superView addSubview:self];
        
        [self setUp];
        self.dataArr = dataArr;
    }
    -(void)setUp{
    
        self.tableView = [[UITableView alloc]init];
        self.tableView.delegate = self;
        self.tableView.dataSource = self;
        self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        
        [self addSubview:self.tableView];
     
        self.tableView.sd_layout.topEqualToView(self).leftEqualToView(self).bottomEqualToView(self).rightEqualToView(self);
    }
    
    #pragma mark -- tableView的代理方法
    #pragma mark -- 返回多少组
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return 1;
    }
    #pragma mark -- 每组返回多少个
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return self.dataArr.count;
    }
    #pragma mark -- 每个cell的高度
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        
        TimeLineModel*model = self.dataArr[indexPath.row];
       
        return [self.tableView cellHeightForIndexPath:indexPath model:model keyPath:@"model" cellClass:[TimeLineCell class] contentViewWidth:self.frame.size.width];
    }
    #pragma mark -- 每个cell显示的内容
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        TimeLineCell*cell = [TimeLineCell timeLineCell:tableView];
        
        if (indexPath.row == 0) {
            cell.lineView.sd_layout.topSpaceToView(cell.pointView, 0);
            cell.lineView.backgroundColor = [UIColor grayColor];
            cell.pointView.backgroundColor = [UIColor redColor];
        }else{
            cell.lineView.sd_layout.topSpaceToView(cell.contentView, 0);
            cell.pointView.backgroundColor = [UIColor grayColor];
            cell.lineView.backgroundColor = [UIColor grayColor];
        }
        cell.model = self.dataArr[indexPath.row];
        
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        return cell;
    }
    #pragma mark -- 选择每个cell执行的操作
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
        
        [tableView deselectRowAtIndexPath:indexPath animated:NO];
    }
    
    • 3.关键在于tableViewCell布局,采用了Xib,方便对样式进行设置,布局依然采用的是SDAutoLayout这个库
    图片.png
    • 4.看下布局代码,这里对titleLB的布局做高度自适应,及设置autoHeightRatio为0即可,然后我们直接在设置模型中调用 [self setupAutoHeightWithBottomView:self.titleLB bottomMargin:0]就自动完成了高度自适应,是不是很方便
    - (void)awakeFromNib {
        [super awakeFromNib];
        
        self.pointView.sd_layout.topSpaceToView(self.contentView, 20).leftSpaceToView(self.contentView, 5).widthIs(8).heightEqualToWidth();
        self.pointView.sd_cornerRadius = @(4);
        
        self.lineView.sd_layout.topEqualToView(self.contentView).centerXEqualToView(self.pointView).widthIs(1).bottomSpaceToView(self.contentView, 0);
        
        self.ttimeLB.sd_layout.centerYEqualToView(self.pointView).leftSpaceToView(self.pointView, 10).rightSpaceToView(self.contentView, 10).heightIs(20);
        self.titleLB.sd_layout.topSpaceToView(self.ttimeLB, 15).leftEqualToView(self.ttimeLB).rightSpaceToView(self.contentView, 10).autoHeightRatio(0);
    }
    
    -(void)setModel:(TimeLineModel *)model{
    
        _model = model;
        self.titleLB.text=  model.title;
        self.ttimeLB.text = model.time;
        
        [self setupAutoHeightWithBottomView:self.titleLB bottomMargin:0];
    }
    
    • 5.到此,封装完毕,最后我们来看看控制器调用代码
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.automaticallyAdjustsScrollViewInsets = YES;
        
        self.timeLine = [[QinzTimeLine alloc]init];
        [self setData];
        
        [self.timeLine setSuperView:self.view DataArr:self.dataArr];
        
    }
    

    总结:整体主要采用tableView进行布局,然后让cell的高度自适应,需要注意的地方就是Cell中时间轴中的线条需要保持连贯,所以需要对第一个cell进行判断,让线条刚好与原点连接。
    最后,附上demo供参考:http://git.oschina.net/Qinz_323/qinztimeline

    我是Qinz,希望我的文章对你有帮助。

    相关文章

      网友评论

      • aee79f239e71:不要把线放在cell中,这样会显得很low,你可以试着用一条长线,来做tableview的背景,通过scrolldidscroll方法来处理,线条的滚动
        杰克道长:@年少当轻狂 一脸懵逼. 还是没懂你的思路。
        Qinz:@年少当轻狂 这个想法挺好,挺受用!而如果考虑每个cell中要对线条样式和颜色进行处理就比较麻烦了
        aee79f239e71:而且如果这么处理的话,可以做出很多其他优化的操作,比如线条渐变色。整体性会更好
      • 天地不仁以万物为刍狗:我有两种更简便的实现方法,对原来的代码结构不产生大的改动:
        第一种:
        1、分区头:一点圆形标签,一条竖线(top=0 bottom=0),一个label
        2、cell:同上
        第二种:
        用三目运算法,indexPath.row%2==1,取时间数据源的数据。其他则取具体内容
        Qinz:@天地不仁以万物为刍狗 挺好的建议!关于取时间的问题这里只是模拟了数据,实际还是要从网络获取赋值给模型的
        天地不仁以万物为刍狗:个人想法,仅供交流,当然楼主封装一下更好

      本文标题:iOS开发之带你5分钟封装一个时间轴

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