iOS 垂直方向跑马灯 循环滚动 多处高亮显示

由于业务需求,需要实现一个垂直滚动文本的跑马灯,没有办法只有自己去写一个动画效果,下面直接贴出代码。

MTAVerticalLoopView.h文件的代码如下:

 

//
//  UIVerticalLoopView.h
//  Jovi
//
//  Created by yuzhuo on 2016/11/23.
//  Copyright © 2016年 dianping.com. All rights reserved.
//

#import 
#import "MTANewAdviseInfo.h"

@protocol VerticalLoopDelegate

- (void)didClickContentAtIndex:(NSInteger)index;

@end
typedef enum
{
    VerticalLoopDirectionBottom,
    VerticalLoopDirectionDown,
    
}VerticalLoopDirection;

@interface MTAVerticalLoopView : UIView
{
    
    // 创建两个label循环滚动
    UILabel *_firstContentLabel;
    UILabel *_secondContentLabel;
    
    UILabel *_firstclickLabel;
    UILabel *_secondclickLabel;
    // 记录
    int currentIndex;
    
}
/** 动画方向默认往上
 *  跑马灯动画时间
 */
@property(nonatomic) float verticalLoopAnimationDuration;
/**
 *  显示的内容(支持多条数据)
 */
@property(nonatomic, retain) NSMutableArray *data;
/**
 * loop方向(上下/右)
 */
@property(nonatomic) VerticalLoopDirection Direction;
@property (nonatomic, weak)id loopDelegate;
/**
 *  开启
 */
-(void)start;

- (void)loopContentClick;

@end

 

 

 

 

 

MTAVerticalLoopView.m文件的代码如下:

 

//
//  UIVerticalLoopView.m
//  Jovi
//
//  Created by yuzhuo on 2016/11/23.
//  Copyright © 2016年 dianping.com. All rights reserved.
//

#import "MTAVerticalLoopView.h"

@implementation MTAVerticalLoopView
{
    BOOL _animating;
}

#pragma mark - lifecycle
- (id)initWithFrame:(CGRect)frame
{
    
    self = [super initWithFrame:frame];
    if (self) {
        
        [self setupView];
    }
    return self;
}

#pragma mark - private method
-(void)setupView {
    
    _firstclickLabel = [[UILabel alloc]initWithFrame:CGRectMake(self.frame.size.width-50, 10, 50, 25)];
    _firstclickLabel.font = [UIFont systemFontOfSize:11.0];
    [_firstclickLabel.layer setBorderColor:[UIColor colorWithHexString:@"#ff6633"].CGColor];//边框颜色
    [_firstclickLabel.layer setMasksToBounds:YES];
    [_firstclickLabel.layer setCornerRadius:12.5];
    [_firstclickLabel.layer setBorderWidth:1.0];
    _firstclickLabel.textColor = [UIColor colorWithHexString:@"#ff6633"];
    _firstclickLabel.textAlignment = NSTextAlignmentCenter;
    
    _secondclickLabel = [[UILabel alloc]initWithFrame:CGRectMake(self.frame.size.width-50, self.frame.size.height+10, 50, 25)];
    _secondclickLabel.font = [UIFont systemFontOfSize:11.0];
    [_secondclickLabel.layer setBorderColor:[UIColor colorWithHexString:@"#ff6633"].CGColor];//边框颜色
    [_secondclickLabel.layer setMasksToBounds:YES];
    [_secondclickLabel.layer setCornerRadius:12.5];
    [_secondclickLabel.layer setBorderWidth:1.0];
    _secondclickLabel.textColor = [UIColor colorWithHexString:@"#ff6633"];
    _secondclickLabel.textAlignment = NSTextAlignmentCenter;

    _firstContentLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, self.frame.size.width - 70, self.frame.size.height)];
    [_firstContentLabel setBackgroundColor:[UIColor clearColor]];
    [_firstContentLabel setNumberOfLines:0];
    _firstContentLabel.userInteractionEnabled = YES;
    UITapGestureRecognizer *tapGesturRecongnizer1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(loopContentClick)];
    tapGesturRecongnizer1.numberOfTapsRequired = 1;
    [_firstContentLabel addGestureRecognizer:tapGesturRecongnizer1];
    
//    _firstContentLabel.lineBreakMode = NSLineBreakByTruncatingTail;
    [_firstContentLabel setTextColor:[UIColor colorWithHexString:@"#333333"]];
    _firstContentLabel.font=[UIFont boldSystemFontOfSize:12.f];
    
    _secondContentLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, self.frame.size.height , self.frame.size.width - 70, self.frame.size.height)];
    [_secondContentLabel setBackgroundColor:[UIColor clearColor]];
    [_secondContentLabel setTextColor:[UIColor colorWithHexString:@"#333333"]];
//    _secondContentLabel.lineBreakMode = NSLineBreakByTruncatingTail;
    [_secondContentLabel setNumberOfLines:0];
    _secondContentLabel.userInteractionEnabled = YES;
    _secondContentLabel.font=[UIFont boldSystemFontOfSize:12.f];
    
    UITapGestureRecognizer *tapGesturRecongnizer2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(loopContentClick)];
    tapGesturRecongnizer2.numberOfTapsRequired = 1;
    [_secondContentLabel addGestureRecognizer:tapGesturRecongnizer2];
    
    [self addSubview:_firstContentLabel];
    [self addSubview:_secondContentLabel];
    [self addSubview:_firstclickLabel];
    [self addSubview:_secondclickLabel];
    
    // 默认初始方向是向上
    _Direction = VerticalLoopDirectionDown;
    _verticalLoopAnimationDuration = 0.5;
    self.clipsToBounds = YES;
}

-(void) setData:(NSMutableArray *) data{
    _data = data;
}



-(void)startVerticalLoopAnimation{
    NSMutableArray *data = [self.data copy];
    if (currentIndex >= data.count) {
        [self verticalLoopAnimationDidStop:nil finished:nil context:nil];
        return;
    }
    
    NSMutableParagraphStyle * paragraphStyle1 = [[NSMutableParagraphStyle alloc] init];
    [paragraphStyle1 setLineSpacing:4];
    //创建 NSMutableAttributedString
    MTANewAdviseInfo * firstAd = [data objectAtIndex:currentIndex];
    NSMutableAttributedString *attributedStr01 = [[NSMutableAttributedString alloc] initWithString: firstAd.desc];
    [attributedStr01 addAttribute:NSParagraphStyleAttributeName value:paragraphStyle1 range:NSMakeRange(0, [firstAd.desc length])];
    //添加属性
    //分段控制,最开始4个字符颜色设置成颜色
    
    for(int i = 0;i0){
            [attributedStr01 addAttribute: NSForegroundColorAttributeName value: [UIColor colorWithHexString:firstAd.styleArray[i].color] range: [firstAd.desc rangeOfString:firstAd.styleArray[i].target]];
        }
        
        if(firstAd.styleArray[i].bold && targetLength >0){
            [attributedStr01 addAttribute:NSStrokeWidthAttributeName value:@(-3) range:[firstAd.desc rangeOfString:firstAd.styleArray[i].target]];
        }
    }
    
    //赋值给显示控件label01的 attributedText
    _firstContentLabel.attributedText = attributedStr01;
    [_firstContentLabel setNeedsDisplay];
    
    _firstclickLabel.text = firstAd.operateDesc;
    
    float firstContentLaStartY = 0;
    float firstContentLaEndY = 0;
    float secondContentLaStartY = 0;
    float secondContentLaEndY = 0;
    
    int secondCurrentIndex  = currentIndex + 1;
    if (secondCurrentIndex > data.count - 1) {
        secondCurrentIndex = 0;
    }
    
    switch (_Direction) {
        case VerticalLoopDirectionBottom:
            
            firstContentLaStartY = 0;
            firstContentLaEndY = self.frame.size.height;
            
            secondContentLaStartY = firstContentLaStartY - self.frame.size.height;
            secondContentLaEndY = firstContentLaEndY - self.frame.size.height;
            
            break;
        case VerticalLoopDirectionDown:
            
            firstContentLaStartY = 0;
            firstContentLaEndY = -self.frame.size.height;
            
            secondContentLaStartY = firstContentLaStartY + self.frame.size.height;
            secondContentLaEndY = firstContentLaEndY + self.frame.size.height;
            
            break;
        default:
            break;
    }
    
    MTANewAdviseInfo * secondAd = [data objectAtIndex:secondCurrentIndex];
    NSMutableAttributedString *attributedStr02 = [[NSMutableAttributedString alloc] initWithString: secondAd.desc];
    
    
    [attributedStr02 addAttribute:NSParagraphStyleAttributeName value:paragraphStyle1 range:NSMakeRange(0, [secondAd.desc length])];
    
    //添加属性
    //分段控制,最开始4个字符颜色设置成颜色
    for(int i = 0;i0){
            [attributedStr02 addAttribute: NSForegroundColorAttributeName value: [UIColor colorWithHexString:secondAd.styleArray[i].color] range: [secondAd.desc rangeOfString:secondAd.styleArray[i].target]];
        }
        if(secondAd.styleArray[i].bold && targetLength02 >0){
            [attributedStr02 addAttribute:NSStrokeWidthAttributeName value:@(-3) range:[secondAd.desc rangeOfString:secondAd.styleArray[i].target]];
        }

    }
    
    _secondContentLabel.attributedText = attributedStr02;
    [_secondContentLabel setNeedsDisplay];
    _secondclickLabel.text = secondAd.operateDesc;
    
    _firstContentLabel.frame = CGRectMake(10, firstContentLaStartY, self.frame.size.width - 70, self.frame.size.height);
    _secondContentLabel.frame = CGRectMake(10, secondContentLaStartY, self.frame.size.width - 70, self.frame.size.height);
    
    _firstclickLabel.frame = CGRectMake(self.frame.size.width-50, firstContentLaStartY+10, 50, 25);
    _secondclickLabel.frame = CGRectMake(self.frame.size.width-50, secondContentLaStartY+10, 50, 25);
    
    @weakify(self);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        @strongify(self);
        [self didAnimation:firstContentLaEndY secondContent:secondContentLaEndY];
    });
    
}

-(void)verticalLoopAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
    currentIndex++;
    if(currentIndex >= [self.data count]) {
        currentIndex = 0;
    }
    @weakify(self);
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        @strongify(self);
        [self startVerticalLoopAnimation];
    });
    
    
}
- (void)loopContentClick
{
    if ([self.loopDelegate respondsToSelector:@selector(didClickContentAtIndex:)]) {
        [self.loopDelegate didClickContentAtIndex:currentIndex];
    }
}

#pragma mark - verticalLoop Animation Handling
-(void)start {
    
    // 开启动画默认第一条信息
    currentIndex = 0;
    // 开始动画
    if (!_animating) {
        _animating = YES;
        [self performSelectorOnMainThread:@selector(startVerticalLoopAnimation) withObject:nil waitUntilDone:NO];
//        [self startVerticalLoopAnimation];
    }
}

-(void)didAnimation:(float)firstContentLaEndY secondContent:(float)secondContentLaEndY
{
    if([self.data count]>1){
        [UIView beginAnimations:@"" context:nil];
        [UIView setAnimationCurve:UIViewAnimationCurveLinear];
        [UIView setAnimationDuration:_verticalLoopAnimationDuration];
        [UIView setAnimationDelay:5];
        [UIView setAnimationDelegate:self];
        [UIView setAnimationDidStopSelector:@selector(verticalLoopAnimationDidStop:finished:context:)];
        CGRect firstContentLabelFrame = _firstContentLabel.frame;
        firstContentLabelFrame.origin.y = firstContentLaEndY;

        [_firstContentLabel setFrame:firstContentLabelFrame];
        [_secondContentLabel setFrame:CGRectMake(10,secondContentLaEndY, self.frame.size.width - 70, self.frame.size.height)];
        
        CGRect firstClickLabelFrame = _firstclickLabel.frame;
        firstClickLabelFrame.origin.y = firstContentLaEndY+10;
        [_firstclickLabel setFrame:firstClickLabelFrame];
        [_secondclickLabel setFrame:CGRectMake(self.frame.size.width-50, secondContentLaEndY+10, 50, 25)];
        
        [UIView commitAnimations];
    }else{
        _animating = NO;
    }

}

@end

 

 

 

加入了多处高亮加粗显示功能:

 

NSMutableAttributedString这个类是用于高亮显示

iOS 垂直方向跑马灯 循环滚动 多处高亮显示_第1张图片

 

 

 

不同颜色显示和加粗显示

iOS 垂直方向跑马灯 循环滚动 多处高亮显示_第2张图片

 

使用代码如下:(部分方法没有贴出来

 

NSMutableArray *array = [NSMutableArray new];
    for (int i =0; i< [self.detialData count]; i++) {
        //添加内容
        [array addObject:[self flattenHTML:self.detialData[i].adviseDesc trimWhiteSpace:YES]];
        if(self.detialData[i].adviseAction == nil || [self.detialData[i].adviseAction length]==0){
            array[i].operateDesc = @"详情";
        }else{
            array[i].operateDesc = self.detialData[i].adviseAction;
        }
        
    }
    if(!self.userInfo)
    {
        for (int i =0; i< [self.detialData count]; i++) {
            //添加内容
            [self ga_withView:self.detialData[i]];
        }
    }
    _content.data = array;
    _content.verticalLoopAnimationDuration = 0.5;
    _content.Direction = VerticalLoopDirectionDown;
    [_content start];

 

 

 

 

 

展示结果:

iOS 垂直方向跑马灯 循环滚动 多处高亮显示_第3张图片

 

最后贴出源码地址:点击打开链接

csdn资源下载地址:点击打开链接

你可能感兴趣的:(ios)