一个可灵活定制的iOS文字水平轮播组件LBHorizontalTextLoopView

首先看下效果图
请添加图片描述

水平文字轮播

实现原理

将一个文字数组传给该组件,
该组件先判断文字是否足够长,在足够长的情况下
添加轮播功能。
轮播功能的实现,为了达到无限轮播效果,创建了三组同样的文案,
我们默认展示的是中间的那一组,当滚动到最后那一第一条的时候,马上返回到中间那一组的第一条,这样就达到了无缝衔接的效果

逻辑可用下面的图简单理解
当滚动到第三组的时候,迅速切换到第二组,
达到无缝衔接的效果
请添加图片描述

核心代码

#pragma mark - 展示数据
- (void)loadWithContentArray:(NSArray <NSString *> *)contentArray
{
    if ([contentArray isEqualToArray:_contentArray]) {
        return;
    }
    if (self.superview && CGSizeEqualToSize(self.scrollview.bounds.size, CGSizeZero)) {
        //初始化没有设置scrollviewFrame 的时候需要更新 scrollview的frame
        [self.superview layoutIfNeeded];
        self.scrollview.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
    }
    _contentArray = contentArray;
    NSMutableArray *marray = [NSMutableArray array];
    //为达到循环轮播的效果添加三个相同数组
    [marray addObjectsFromArray:contentArray];
    [marray addObjectsFromArray:contentArray];
    [marray addObjectsFromArray:contentArray];
    [self.scrollview.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    [self showContentWithArray:marray.copy];
}

- (void)showContentWithArray:(NSArray *)array
{
    CGFloat x = 0;
    NSInteger i = 0;
    
    for (NSString *string  in array)
    {
        CGFloat width = [string boundingRectWithSize:CGSizeMake(100000, 16) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: self.font} context:nil].size.width + 40;
        
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        [button setTitle:string forState:UIControlStateNormal];
        button.titleLabel.font = self.font;
        button.titleEdgeInsets = UIEdgeInsetsMake(button.titleEdgeInsets.top, 0, button.titleEdgeInsets.bottom, button.titleEdgeInsets.right + button.titleEdgeInsets.left);
        [button setTitleColor:self.textColor forState:UIControlStateNormal];
        button.frame = CGRectMake(x, 0, width, self.bounds.size.height);
        button.tag = 300 + i;
        
        [button addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
        [self.scrollview addSubview:button];
        
        
        x += width;
        if (i == array.count/3 - 1) {
            /// array.cont/3 -1 时最后一条文案的索引序号
            //如果所有的消息加到一起都没有scrollview宽度长,则不轮播
            if (CGRectGetMaxX(button.frame) < self.scrollview.bounds.size.width) {
                [self stopScroll];
                self.hasLinker = NO;
                break;
            }
        }
        
       if (i == array.count - 1) {
            self.scrollview.contentSize = CGSizeMake(CGRectGetMaxX(button.frame), self.bounds.size.height);
            [self.scrollview setContentOffset:CGPointZero animated:NO];
        }
        if (i == array.count - 1) {
            if (!_linker) {
                [self startScroll];
            }
        }
        
        i++;
    }
}

达到临界偏移量的时候,迅速修改偏移量

#pragma mark - scrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if (scrollView.contentOffset.x > scrollView.contentSize.width/3.0 * 2) {
        [self.scrollview setContentOffset:CGPointMake(scrollView.contentSize.width/3.0 + (scrollView.contentOffset.x - scrollView.contentSize.width/3.0 * 2), 0) animated:NO];
    }
}
另外,我这里使用CADisplayLink 实现计时器

```objectivec
   self.linker = [CADisplayLink lb_displayLinkWithTarget:self selector:@selector(displayLinkAction)];
    [self.linker addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
    self.hasLinker = YES;

使用方法

pod ‘LBHorizontalTextLoopView’


- (LBHorizontalTextLoopView *)textLoopView
{
    if (!_textLoopView) {
        _textLoopView = [[LBHorizontalTextLoopView alloc] initWithFrame:CGRectMake(10, 100, 350, 40)];
        _textLoopView.backgroundColor = [UIColor cyanColor];
        _textLoopView.delegate = self;
        _textLoopView.textColor = [UIColor redColor];
        _textLoopView.font = [UIFont systemFontOfSize:18];
    }
    return _textLoopView;
}

#展示文案数组
   [self.textLoopView loadWithContentArray:@[@"预计今年底通车,上海金山最后一条未通车省际道路已完成八成"]];
   
   #点击事件
   #pragma mark - LBHorizontalTextLoopViewDelegate
   - (void)horizontalLoopViewdidSelectItemAtIndex:(NSInteger)index
   {
       NSLog(@"点击点击点击点击%ld",(long)index);
   }

demo
如果对您有用,欢迎star

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值