欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

IOS 文本滚动标签效果(Objc/Swift)

程序员文章站 2022-05-31 17:32:21
...

实现效果

IOS 文本滚动标签效果(Objc/Swift)

  • 实现原理:动画改变文本的y坐标,同时使用把移出父布局的视图立即移到父视图的下方,使用一个临时UIView来交替上下两个视图,达到利用的效果
  • 实现核心代码如下:
    Object-c版本:
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

typedef void(^OnClickListener)(NSString* title);

@interface ScrollLabel : UILabel
@property(nonatomic,strong) UIView* parentView;
@property(nonatomic,strong) UIButton* upLabel;
@property(nonatomic,strong) UIButton* bottomLabel;
@property(nonatomic,copy) OnClickListener listener;

-(void) setTargetView:(UIView*) parentView withTitleArray:(NSMutableArray*)array;

-(void) setOnClickListener:(OnClickListener)listener;

-(void) start;

-(void) stop;

@end

NS_ASSUME_NONNULL_END

.m文件:

#import "ScrollLabel.h"
#import "UIView+Resize.h"

@interface  ScrollLabel()
@property(nonatomic,strong)NSMutableArray* titleArray;
@property(nonatomic,strong)NSTimer *timer;
@property(nonatomic,assign)NSInteger index;

@end

@implementation ScrollLabel

-(instancetype) init{
   if (self = [super init]) {
       
   }
   return self;
}

-(void) setTargetView:(UIView*) parentView withTitleArray:(NSMutableArray*)array{
   if (!parentView || !array || array.count == 0) {
       return;
   }
   self.titleArray = array;
   self.parentView = parentView;
   self.index = 0;
   
   self.upLabel = [[UIButton alloc] init];
   self.upLabel.backgroundColor = [UIColor greenColor];
   self.upLabel.tag = 21;
   [self.upLabel addTarget:self action:@selector(onClick:) forControlEvents:UIControlEventTouchUpInside];
   [self.upLabel setTitle:[array objectAtIndex:self.index] forState:UIControlStateNormal];
   self.upLabel.frame = CGRectMake(0, 0, parentView.frame.size.width,parentView.frame.size.height);
   self.index ++;
   
   self.bottomLabel = [[UIButton alloc] init];
   self.bottomLabel.tag = 22;
   [self.bottomLabel addTarget:self action:@selector(onClick:) forControlEvents:UIControlEventTouchUpInside];

   self.bottomLabel.frame = CGRectMake(0, self.upLabel.frame.size.height, parentView.frame.size.width,parentView.frame.size.height);
   [self.bottomLabel setTitle:[array objectAtIndex:self.index] forState:UIControlStateNormal];
   self.bottomLabel.backgroundColor = [UIColor brownColor];
   
   [self.parentView addSubview:self.upLabel];
   [self.parentView addSubview:self.bottomLabel];
   
}

-(void) onClick:(UIButton*) button{
   switch (button.tag) {
       case 21:
       case 22:
           if (self.listener) {
               self.listener(button.titleLabel.text);
           }
           break;
           
       default:
           break;
   }
}
-(void) setOnClickListener:(OnClickListener)listener{
   self.listener = listener;
}


-(void) start{
   if(self.titleArray.count == 1){
       return;
   }
   
   if (!self.timer) {
       self.timer = [NSTimer timerWithTimeInterval:3 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
       [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
   }
  
}
-(void) timerAction{
   [UIView transitionWithView:self.upLabel duration:2 * 0.5 options:UIViewAnimationOptionCurveEaseInOut animations:^{
       self.upLabel.tx_bottom = 0;
       [UIView transitionWithView:self.upLabel duration:2 * 0.5 options:UIViewAnimationOptionCurveEaseInOut animations:^{
           self.bottomLabel.tx_y = 0;
       } completion:^(BOOL finished) {
           self.upLabel.tx_y = self.parentView.tx_height;
           UIButton *tempLabel = self.upLabel;
           self.upLabel = self.bottomLabel;
           self.bottomLabel = tempLabel;
           self.index ++;
           NSString* title = [self.titleArray objectAtIndex:self.index % self.titleArray.count];
           [tempLabel setTitle:title forState:UIControlStateNormal];
       }];
   } completion:^(BOOL finished){
   }];
   
}

-(void) stop{
   if(self.timer){
       [self.timer invalidate];
       self.timer = nil;
   }
}

@end

分类文件:


#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface UIView (Resize)

/** 设置x值 */
@property (assign, nonatomic) CGFloat tx_x;
/** 设置y值 */
@property (assign, nonatomic) CGFloat tx_y;
/** 设置width */
@property (assign, nonatomic) CGFloat tx_width;
/** 设置height */
@property (assign, nonatomic) CGFloat tx_height;
/** 设置size */
@property (assign, nonatomic) CGSize  tx_size;
/** 设置origin */
@property (assign, nonatomic) CGPoint tx_origin;
/** 设置center */
@property (assign, nonatomic) CGPoint tx_center;
/** 设置center.x */
@property (assign, nonatomic) CGFloat tx_centerX;
/** 设置center.y */
@property (assign, nonatomic) CGFloat tx_centerY;
/** 设置bottom */
@property (assign, nonatomic) CGFloat tx_bottom;

@end




#import "UIView+Resize.h"

@implementation UIView (Resize)

- (CGFloat)tx_x {
    return self.frame.origin.x;
}

- (void)setTx_x:(CGFloat)tx_x {
    CGRect frame = self.frame;
    frame.origin.x = tx_x;
    self.frame = frame;
}

- (CGFloat)tx_y {
    return self.frame.origin.y;
}

- (void)setTx_y:(CGFloat)tx_y {
    CGRect frame = self.frame;
    frame.origin.y = tx_y;
    self.frame = frame;
}

- (CGFloat)tx_width {
    return self.frame.size.width;
}

- (void)setTx_width:(CGFloat)tx_width {
    CGRect frame = self.frame;
    frame.size.width = tx_width;
    self.frame = frame;
}

- (CGFloat)tx_height {
    return self.frame.size.height;
}

- (void)setTx_height:(CGFloat)tx_height {
    CGRect frame = self.frame;
    frame.size.height = tx_height;
    self.frame = frame;
}

- (CGSize)tx_size {
    return self.frame.size;
}

- (void)setTx_size:(CGSize)tx_size {
    CGRect frame = self.frame;
    frame.size = tx_size;
    self.frame = frame;
}

- (CGPoint)tx_origin {
    return self.frame.origin;
}

- (void)setTx_origin:(CGPoint)tx_origin {
    CGRect frame = self.frame;
    frame.origin = tx_origin;
    self.frame = frame;
}

- (CGPoint)tx_center {
    return self.center;
}

- (void)setTx_center:(CGPoint)tx_center {
    self.center = tx_center;
}

- (CGFloat)tx_centerX {
    return self.center.x;
}

- (void)setTx_centerX:(CGFloat)tx_centerX {
    CGPoint center = self.center;
    center.x = tx_centerX;
    self.center = center;
}

- (CGFloat)tx_centerY {
    return self.center.y;
}

- (void)setTx_centerY:(CGFloat)tx_centerY {
    CGPoint center = self.center;
    center.y = tx_centerY;
    self.center = center;
}

- (CGFloat)tx_bottom {
    return CGRectGetMaxY(self.frame);
}

- (void)setTx_bottom:(CGFloat)tx_bottom {
    CGRect frame = self.frame;
    frame.origin.y = tx_bottom - frame.size.height;
    self.frame = frame;
}


@end

  • 测试代码:
self.textView2 = [[UIView alloc] initWithFrame:CGRectMake(30, 160, 240, 40)];
    self.textView2.backgroundColor = [UIColor grayColor];
    self.textView2.clipsToBounds = true;
    [self.view addSubview:self.textView2];
    
    self.scrollLabel = [[ScrollLabel alloc] init];
    NSMutableArray* array = [NSMutableArray arrayWithArray:self.texts];
    [self.scrollLabel setTargetView:self.textView2 withTitleArray:array];
    [self.scrollLabel setOnClickListener:^(NSString* title){
        NSLog(@"91--------:%@",title);
    }];
  • swift 文件:
import UIKit

class ScrollLabel: UIView {

    lazy var parentView : UIView = UIView.init();
    lazy var upLabel : UIButton = UIButton.init();
    lazy var bottom : UIButton = UIButton.init();
    lazy var titleArray:NSMutableArray = NSMutableArray.init();
    var index:NSInteger = 0;
    lazy var timer:Timer? = Timer.init()
    
    override init(frame: CGRect) {
        super.init(frame:frame)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    public func setTarget(_ parentView:UIView, withTitleArray array:NSMutableArray) ->Void {
        self.parentView = parentView
        self.titleArray = array
        
        self.upLabel.backgroundColor = UIColor.green;
        self.upLabel.tag = 21;
        self.upLabel.addTarget(self, action: #selector(onClickListener(btn:)), for:.touchUpInside)
        self.upLabel.setTitle(self.titleArray.object(at: self.index) as? String, for:.normal)
        self.upLabel.frame = CGRect.init(x: 0, y: 0, width: parentView.frame.size.width, height: parentView.frame.size.height)
    
        self.index += 1
       self.bottom.backgroundColor = UIColor.brown;
       self.bottom.tag = 22;
       self.bottom.addTarget(self, action: #selector(onClickListener(btn:)), for:.touchUpInside)
        self.bottom.setTitle(self.titleArray.object(at: self.index) as? String, for:.normal)
       self.bottom.frame = CGRect.init(x: 0, y: parentView.frame.size.height, width: parentView.frame.size.width, height: parentView.frame.size.height)
        
        parentView.addSubview(self.upLabel)
        parentView.addSubview(self.bottom)
    }
    
    
    @objc func onClickListener(btn : UIButton?)  {
        switch btn?.tag {
        case 21,22:
            NSLog("----")
            break;
        default:
            break;
        }
    }
    
    public func start() -> Void {
        if self.titleArray.count == 1 {
            return;
        }
        if self.timer == nil {
            
            self.timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(onFire), userInfo: nil, repeats: true);
                
            self.timer?.fire()
        }
        
        
    }
    
    @objc func onFire() -> Void {
        
        UIView.transition(with: self.upLabel, duration: 2 * 0.5, options: .curveEaseInOut, animations: {
            self.upLabel.tx_bottom = 0
            
            UIView.transition(with: self.upLabel, duration: 2 * 0.5, options: .curveEaseInOut, animations: {
                           
                           self.bottom.y = 0;
                           
                       }, completion: {_ in
                           self.upLabel.y = self.parentView.height;
                           let tempLabel = self.upLabel;
                           self.upLabel = self.bottom;
                           self.bottom = tempLabel;
                           self.index += 1;
                           let title = self.titleArray.object(at: self.index % self.titleArray.count) as? String
                           tempLabel.setTitle(title, for:.normal)
                       })
            
            
        }, completion: {_ in
        
        })
        
    }
    
    public func stop(){
        if(self.timer != nil){
            self.timer!.invalidate()
            self.timer = nil;
        }
        
    }
    
}

//UIView 的分类
extension UIView {
    // .x
    public var x: CGFloat {
        get {
            return self.frame.origin.x
        }
        set {
            var rect = self.frame
            rect.origin.x = newValue
            self.frame = rect
        }
    }
    
    // .y
    public var y: CGFloat {
        get {
            return self.frame.origin.y
        }
        set {
            var rect = self.frame
            rect.origin.y = newValue
            self.frame = rect
        }
    }
    
    // .maxX
    public var maxX: CGFloat {
        get {
            return self.frame.maxX
        }
    }
    
    // .maxY
    public var maxY: CGFloat {
        get {
            return self.frame.maxY
        }
    }
    
    // .centerX
    public var centerX: CGFloat {
        get {
            return self.center.x
        }
        set {
            self.center = CGPoint(x: newValue, y: self.center.y)
        }
    }
    
    // .centerY
    public var centerY: CGFloat {
        get {
            return self.center.y
        }
        set {
            self.center = CGPoint(x: self.center.x, y: newValue)
        }
    }
    
    // .width
    public var width: CGFloat {
        get {
            return self.frame.size.width
        }
        set {
            var rect = self.frame
            rect.size.width = newValue
            self.frame = rect
        }
    }
    
    // .height
    public var height: CGFloat {
        get {
            return self.frame.size.height
        }
        set {
            var rect = self.frame
            rect.size.height = newValue
            self.frame = rect
        }
    }
    
    public var tx_bottom:CGFloat{
        get {
            return self.frame.size.height
        }
        set {
            var rect = self.frame
            rect.origin.y = newValue - rect.size.height
            self.frame = rect
        }
    }
}

  • 测试例子
import UIKit


class ViewController: UIViewController {
    
    var scrollLabel:ScrollLabel?
    lazy var upLabel : UIButton = UIButton.init();

    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        self.upLabel.backgroundColor = UIColor.green;
       self.upLabel.tag = 21;
       self.upLabel.addTarget(self, action: #selector(onClickListener(btn:)), for:.touchUpInside)
       self.upLabel.setTitle("start", for:.normal)
       self.upLabel.frame = CGRect.init(x: 10, y: 50, width: 100, height: 50)
        self.view.addSubview(upLabel)
        
        let parentView : UIView = UIView.init(frame: CGRect.init(x: 50, y: 160, width: 180, height: 40))
        self.view.addSubview(parentView)
        parentView.backgroundColor = UIColor.blue
        parentView.clipsToBounds = true
        
        let array:NSMutableArray = NSMutableArray.init(objects: "香辣肉丝","听你讲个故事","听你唱首歌",
        "高考","大学","工作","生活")
        
        scrollLabel = ScrollLabel();
        scrollLabel?.setTarget(parentView, withTitleArray: array)
        
        
    }
    
    @objc func onClickListener(btn : UIButton?)  {
           switch btn?.tag {
           case 21,22:
            scrollLabel?.start()
               break;
           default:
               break;
           }
       }


}