iOS时间轴展示实现

作者: 见哥哥长高了 | 来源:发表于2017-06-21 15:45 被阅读703次

    大家先看一下其显示效果


    时间轴展示效果

    看起来虽丑,但那不是重点。以上只是一个简单的例子,其实现起来方法很多,我列举出了其中能实现其效果的两种实现方式。

    第一种:借助UITableView自定义UITableViewCell####

    我们大致观察时间轴的UI效果,虽然显示内容不同,但样式还是有规律可循的。
    首先,我们自定义LGJTimeLineCell 继承UITableViewCell

    LGJTimeLineCell.png

    其具体实现代码如下:
    LGJTimeLineCell.h

    #import <UIKit/UIKit.h>
    @class LGJTimeLineModel;
    @interface LGJTimeLineCell : UITableViewCell
    
    @property(nonatomic,copy)NSString *numberStr;
    
    @property(nonatomic,strong)LGJTimeLineModel *model;
    
    -(void)setUITopViewShow:(BOOL)topLineShow bottomViewShow:(BOOL)bottomLineShow;
    
    @end
    

    LGJTimeLineCell.m

    #import "LGJTimeLineCell.h"
    #import "LGJTimeLineModel.h"
    @interface LGJTimeLineCell ()
    
    @property (weak, nonatomic) IBOutlet UIView *topLine;
    @property (weak, nonatomic) IBOutlet UIButton *circleButton;
    @property (weak, nonatomic) IBOutlet UIView *bottomLine;
    @property (weak, nonatomic) IBOutlet UILabel *titleLabel;
    @property (weak, nonatomic) IBOutlet UILabel *contentLabel;
    
    @end
    @implementation LGJTimeLineCell
    - (void)awakeFromNib {
        [super awakeFromNib];
        self.circleButton.layer.cornerRadius = 15.0f;
        self.circleButton.layer.masksToBounds = YES;
    }
    -(void)setUITopViewShow:(BOOL)topLineShow bottomViewShow:(BOOL)bottomLineShow{
        self.topLine.hidden = topLineShow ? YES : NO;
        self.bottomLine.hidden = bottomLineShow ? YES : NO;
    }
    -(void)setNumberStr:(NSString *)numberStr{
        [self.circleButton setTitle:numberStr forState:UIControlStateNormal];
    }
    -(void)setModel:(LGJTimeLineModel *)model{
        self.titleLabel.text = model.title;
        self.contentLabel.text = model.content;
    }
    - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
        [super setSelected:selected animated:animated];
        // Configure the view for the selected state
    }
    @end
    

    创建展示模型类

    #import <Foundation/Foundation.h>
    @interface LGJTimeLineModel : NSObject
    @property(nonatomic,copy)NSString *title;
    @property(nonatomic,copy)NSString *content;
    @end
    

    接下来借助tableView的展示,并实现其数据源和代理方法

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        return [self.dataSourse count];
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        LGJTimeLineModel *model = self.dataSourse[indexPath.row];
        LGJTimeLineCell *cell = [tableView dequeueReusableCellWithIdentifier:@"LGJTimeLineCell"];
        if (cell == nil) {
            cell = [[[NSBundle mainBundle]loadNibNamed:@"LGJTimeLineCell" owner:nil options:nil]lastObject];
        }
        cell.model = model;
        [cell setUITopViewShow:NO bottomViewShow:NO];
        if (indexPath.row == 0) {
            [cell setUITopViewShow:NO bottomViewShow:YES];
        }
        if (indexPath.row == [self.dataSourse count] - 1) {
            [cell setUITopViewShow:YES bottomViewShow:NO];
        }
        cell.numberStr = [NSString stringWithFormat:@"%ld",indexPath.row + 1];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        return cell;
    }
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    
        LGJTimeLineModel *model = self.dataSourse[indexPath.row];
        CGFloat title_Height = [self returnHeightWithString:model.title font:[UIFont systemFontOfSize:15]];
        CGFloat content_Height = [self returnHeightWithString:model.content font:[UIFont systemFontOfSize:13]];
        return title_Height + content_Height + 60;
    }
    -(CGFloat)returnHeightWithString:(NSString *)str font:(UIFont *)font{
        return [str boundingRectWithSize:CGSizeMake(self.view.frame.size.width - 70, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil].size.height;
    }
    

    第二种:借助UIScollView的滚动特性添加子视图完成####

    首先自定义LGJTimelineView类
    LGJTimelineView.h

    #import <UIKit/UIKit.h>
    @class LGJTimelineView;
    
    @protocol LGJTimelineViewDelegate <NSObject>
    
    - (void)clickedViewWithTimelineView:(LGJTimelineView *)timelineView sender:(UIButton *)sender;
    
    
    @end
    
    @interface LGJTimelineView : UIView
    
    @property(nonatomic,weak)id<LGJTimelineViewDelegate> delegate;
    
    -(void)setContentWithTitleArray:(NSArray *)titleArray contentArray:(NSArray *)contentArray scollView:(UIScrollView *)scollView titleFont:(UIFont *)titleFont contentFont:(UIFont *)contentFont;
    @end
    

    LGJTimelineView.m

    #import "LGJTimelineView.h"
    
    #define kColor(hex) [UIColor colorWithRed:((CGFloat)((hex & 0xFF0000) >> 16)) / 255.0 green:((CGFloat)((hex & 0xFF00) >> 8)) / 255.0 blue:((CGFloat)(hex & 0xFF)) / 255.0 alpha:1]
    
    // 起始位置的Y
    #define Start_Position_Y  0
    // 起始位置的X
    #define Start_Position_X  15
    // 直径
    #define Round_Directly  23
    // 连接的线长
    #define Line_Length  88
    
    
    
    @implementation LGJTimelineView
    
    -(void)setContentWithTitleArray:(NSArray *)titleArray contentArray:(NSArray *)contentArray scollView:(UIScrollView *)scollView titleFont:(UIFont *)titleFont contentFont:(UIFont *)contentFont{
        CGFloat content_H = 0;
        CGFloat view_H = 0;
        for (NSInteger i = 0; i < [titleArray count]; i++) {
            
            CGFloat content_Width = self.frame.size.width - Round_Directly -Start_Position_X * 3;
            CGFloat content_Height = [self calculteTheSizeWithContent:contentArray[i] rect:CGSizeMake(content_Width, MAXFLOAT) font:[UIFont systemFontOfSize:14]].height;
    
            CGFloat labelH = content_Height + Round_Directly;
            content_H += labelH ;
            view_H += content_Height;
            CGFloat contentY = Start_Position_Y + content_H - labelH + ( Round_Directly) * (i+1);
            
            // 阶段
            UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(Start_Position_X, contentY, Round_Directly, Round_Directly)];
            btn.layer.cornerRadius = Round_Directly * 0.5;
            btn.layer.masksToBounds = YES;
            btn.layer.borderColor = kColor(0x358fd7).CGColor;
            btn.layer.borderWidth = 1;
            [btn setTitle:[NSString stringWithFormat:@"%ld", i + 1] forState:UIControlStateNormal];
            [btn setTitleColor:kColor(0x358fd7) forState:UIControlStateNormal];
            btn.tag = i + 1;
            [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
            [self addSubview:btn];
            
            // 标题
            UILabel *titleLable = [self lableWithFrame:CGRectMake(CGRectGetMaxX(btn.frame) + 15, CGRectGetMidY(btn.frame) - Round_Directly*0.5,content_Width , Round_Directly) text:titleArray[i] textColor:kColor(0x358fd7) font:19];
            titleLable.numberOfLines = 0;
            [self addSubview:titleLable];
            
            // 内容
            UILabel *contentlable = [self lableWithFrame:CGRectMake(CGRectGetMinX(titleLable.frame), CGRectGetMaxY(titleLable.frame) + Round_Directly * 0.5, titleLable.frame.size.width, content_Height) text:contentArray[i] textColor:kColor(0x666666) font:14];
            contentlable.numberOfLines = 0;
            [self addSubview:contentlable];
            
            // 连接线
            if (i < contentArray.count - 1) {
                
                UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(Start_Position_X + Round_Directly * 0.5 - 0.5,CGRectGetMaxY(titleLable.frame) , 1, labelH)];
                lineView.backgroundColor = kColor(0x358fd7);
                [self addSubview:lineView];
            }
        }
        CGFloat H = Start_Position_Y + view_H + Round_Directly * titleArray.count * 2 + Round_Directly * 0.5;
        scollView.contentSize = CGSizeMake(self.frame.size.width, H);
    }
    - (UILabel *)lableWithFrame:(CGRect)frame text:(NSString *)text textColor:(UIColor *)textColor font:(NSInteger)font {
        
        UILabel *label = [[UILabel alloc] initWithFrame:frame];
        label.text = text;
        label.textColor = textColor;
        label.font = [UIFont systemFontOfSize:font];
        label.textAlignment = NSTextAlignmentLeft;
        return label;
    }
    - (CGSize)calculteTheSizeWithContent:(NSString*)content rect:(CGSize)rect font:(UIFont*)font {
        
        NSDictionary *attribute = @{NSFontAttributeName: font};
        
        CGSize size = [content  boundingRectWithSize:rect                                        options:
                       NSStringDrawingTruncatesLastVisibleLine |
                       NSStringDrawingUsesLineFragmentOrigin |
                       NSStringDrawingUsesFontLeading
                                          attributes:attribute
                                             context:nil].size;
        return size;
    }
    - (void)btnClick: (UIButton *)sender {
        
        if ([self.delegate respondsToSelector:@selector(clickedViewWithTimelineView:sender:)]) {
            [self.delegate clickedViewWithTimelineView:self sender:sender];
        }
    }
    

    其使用也是非常简单,在我们需要的地方直接调用,至于UI丑美,这个根绝个人情况来:

        LGJTimelineView *timeLineView = [[LGJTimelineView alloc] initWithFrame:self.view.bounds];
        [timeLineView setContentWithTitleArray:self.titleArray contentArray:self.contentArray scollView:scrollView titleFont:[UIFont systemFontOfSize:15] contentFont:[UIFont systemFontOfSize:13]];
        timeLineView.delegate = self;
        [scrollView addSubview:timeLineView];
      
    }
    - (void)clickedViewWithTimelineView:(LGJTimelineView *)timelineView sender:(UIButton *)sender{
        NSLog(@"%ld",sender.tag);
    }
    

    其实现效果如下:


    第二种

    相关文章

      网友评论

      本文标题:iOS时间轴展示实现

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