当前位置: 移动技术网 > IT编程>移动开发>IOS > iOS 实现跑马灯效果的方法示例

iOS 实现跑马灯效果的方法示例

2019年07月24日  | 移动技术网IT编程  | 我要评论

陈漫个人资料,周立波秀壹周秀2012全集,壹周立波秀2010全集

在网页开发当中跑马灯是常用到的,用来显示通知等,在游戏开发当中也如此。

首先来看看效果图:

接下来就简单看看这效果是怎么实现的。

实现方法

1、首先我们从这个图片里面能联想到如果实现这个效果必然需要使用到动画,或者还有有用scrollview的思路,这里我是用的动画的方式实现的。

2、.h文件

自定义一个继承uiview的lgjautorunlabel类,在.h文件中:

@class lgjautorunlabel;

typedef ns_enum(nsinteger, rundirectiontype) {
 lefttype = 0,
 righttype = 1,
};

@protocol lgjautorunlabeldelegate <nsobject>

@optional
- (void)operatelabel: (lgjautorunlabel *)autolabel animationdidstopfinished: (bool)finished;

@end

@interface lgjautorunlabel : uiview

@property (nonatomic, weak) id <lgjautorunlabeldelegate> delegate;
@property (nonatomic, assign) cgfloat speed;
@property (nonatomic, assign) rundirectiontype directiontype;

- (void)addcontentview: (uiview *)view;
- (void)startanimation;
- (void)stopanimation;

定义一个ns_enum用来判断自动滚动的方向,分别是左和右,声明一个可选类型的协议,用来在controller中调用并对autolabel进行操作。声明对外的属性和方法。这里一目了然,主要的实现思路都集中在.m文件中。

3、.m文件

声明“私有”变量和属性:

@interface lgjautorunlabel()<caanimationdelegate>
{
 cgfloat _width;
 cgfloat _height;
 cgfloat _animationviewwidth;
 cgfloat _animationviewheight;
 bool _stoped;
 uiview *_contentview;//滚动内容视图
}
@property (nonatomic, strong) uiview *animationview;//放置滚动内容视图
@end

初始化方法:

- (instancetype)initwithframe:(cgrect)frame {

 if (self == [super initwithframe:frame]) {
 _width = frame.size.width;
 _height = frame.size.height;

 self.speed = 1.0f;
 self.directiontype = lefttype;
 self.layer.maskstobounds = yes;
 self.animationview = [[uiview alloc] initwithframe:cgrectmake(_width, 0, _width, _height)];
 [self addsubview:self.animationview];
 }
 return self;
}

将滚动内容视图contentview添加到动画视图animationview上:

- (void)addcontentview:(uiview *)view {

 [_contentview removefromsuperview];
 view.frame = view.bounds;
 _contentview = view;
 self.animationview.frame = view.bounds;
 [self.animationview addsubview:_contentview];

 _animationviewwidth = self.animationview.frame.size.width;
 _animationviewheight = self.animationview.frame.size.height;
}

让animationview上的contentview自动滚动起来的主要方法在这儿,重点来了,就是这个- (void)startanimation方法,看一下这个方法里面是怎么样实现的:

- (void)startanimation {
 [self.animationview.layer removeanimationforkey:@"animationviewposition"];
 _stoped = no;

 cgpoint pointrightcenter = cgpointmake(_width + _animationviewwidth / 2.f, _animationviewheight / 2.f);
 cgpoint pointleftcenter = cgpointmake(-_animationviewwidth / 2, _animationviewheight / 2.f);
 cgpoint frompoint = self.directiontype == lefttype ? pointrightcenter : pointleftcenter;
 cgpoint topoint  = self.directiontype == lefttype ? pointleftcenter : pointrightcenter;

 self.animationview.center = frompoint;
 uibezierpath *movepath = [uibezierpath bezierpath];
 [movepath movetopoint:frompoint];
 [movepath addlinetopoint:topoint];

 cakeyframeanimation *moveanimation = [cakeyframeanimation animationwithkeypath:@"position"];
 moveanimation.path   = movepath.cgpath;
 moveanimation.removedoncompletion = yes;
 moveanimation.duration  = _animationviewwidth / 30.f * (1 / self.speed);
 moveanimation.delegate  = self;
 [self.animationview.layer addanimation:moveanimation forkey:@"animationviewposition"];
}

↘️首先先把animationview.layer上的动画移除掉,接下来就是要找到animationview\contentview的pointcenter这里把这个中点当做是animationview或者是contentview都行,因为这两个视图的frame是相等的,这步找左右中点的意义在于,完全显示出文字内容,因为可能会遇到那种比如文字太长了,view长度不够,不能完全显示出来文字的全部内容, 这里我们找到中点,也就相当于确定了内容视图要滑动的范围了,接下来根据起始方向的枚举值设置frompoint和topoint这里我们默认是从右向左滚动的。这里我们做动画设置,用到了贝塞尔曲线,我们设置uibezierpath的起始位置就是frompoint也就是屏幕右方(我们看不见)self.animationview.center。终止位置是屏幕左方topoint此时animationview滚动的起始位置的首和终止位置的尾的距离正好是屏幕的宽度。这里我们使用cakeyframeanimation关键帧动画,moveanimation.path                 = movepath.cgpath; ,moveanimation.removedoncompletion  = yes;动画完成后就将动画移除,不保留最终的状态。 [self.animationview.layer addanimation:moveanimation forkey:@"animationviewposition"];将动画添加到animationview.layer上。

(这段是对上面代码的解释)

-------------------分割线-------------------

接下来的这个就是代理方法的实现了,当动画完成后悔调用lgjautorunlabeldelegate我们自定义的delegate方法。

- (void)stopanimation {
 _stoped = yes;
 [self.animationview.layer removeanimationforkey:@"animationviewposition"];
}

- (void)animationdidstop:(caanimation *)anim finished:(bool)flag {
 if (self.delegate && [self.delegate respondstoselector:@selector(operatelabel:animationdidstopfinished:)]) {
 [self.delegate operatelabel:self animationdidstopfinished:flag];
 }
 if (flag && !_stoped) {
 [self startanimation];
 }
}

4、在controller中使用方法

主要的方法就是声明lgjautorunlabel实例,将代理设为自身,声明directiontype默认为left,在runlabel上创建label也就是我们看到的文字。其余方法一目了然了。

//mark:- createautorunlabel
- (void)createautorunlabel {
 lgjautorunlabel *runlabel = [[lgjautorunlabel alloc] initwithframe:cgrectmake(0, 100, kwidth, 50)];
 runlabel.delegate = self;
 runlabel.directiontype = lefttype;
 [self.view addsubview:runlabel];
 [runlabel addcontentview:[self createlabelwithtext:@"繁华声 遁入空门 折煞了梦偏冷 辗转一生 情债又几 如你默认 生死枯等 枯等一圈 又一圈的 浮图塔 断了几层 断了谁的痛直奔 一盏残灯 倾塌的山门 容我再等 历史转身 等酒香醇 等你弹 一曲古筝" textcolor:[selfrandomcolor] labelfont:[uifont systemfontofsize:14]]];
 [runlabel startanimation];
}

- (uilabel *)createlabelwithtext: (nsstring *)text textcolor:(uicolor *)textcolor labelfont:(uifont *)font {
 nsstring *string = [nsstring stringwithformat:@"%@", text];
 cgfloat width = [uilabel getwidthbytitle:string font:font];
 uilabel *label = [[uilabel alloc] initwithframe:cgrectmake(0, 0, width, 50)];
 label.font = font;
 label.text = string;
 label.textcolor = textcolor;
 return label;
}

- (uicolor *)randomcolor {
 return [uicolor colorwithred:[self randomvalue] green:[self randomvalue] blue:[self randomvalue] alpha:1];
}

- (cgfloat)randomvalue {
 return arc4random()%255 / 255.0f;
}

总结

这个例子挺小的,主要思路就是利用动画将其变活,可能不太好理解的地方就是在动画移动的path这个路径的距离上,我们想这个路径的时候肯定要这样想,我让动画从最初我看不见的地方出现,然后最后到我看不见的地方消失,这个中间的距离之差就是屏幕的宽度了,而这个屏幕的宽度正好我们可以用contentview.frame来表示。

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

  • ios uicollectionview实现横向滚动

    现在使用卡片效果的app很多,之前公司让实现一种卡片效果,就写了一篇关于实现卡片的文章。文章最后附有demo实现上我选择了使用uicollectionview ... [阅读全文]
  • iOS UICollectionView实现横向滑动

    本文实例为大家分享了ios uicollectionview实现横向滑动的具体代码,供大家参考,具体内容如下uicollectionview的横向滚动,目前我使... [阅读全文]
  • iOS13适配深色模式(Dark Mode)的实现

    iOS13适配深色模式(Dark Mode)的实现

    好像大概也许是一年前, mac os系统发布了深色模式外观, 看着挺刺激, 时至今日用着也还挺爽的终于, 随着iphone11等新手机的发售, ios 13系统... [阅读全文]
  • ios 使用xcode11 新建项目工程的步骤详解

    ios 使用xcode11 新建项目工程的步骤详解

    xcode11新建项目工程,新增了scenedelegate这个类,转而将原appdelegate负责的对ui生命周期的处理担子接了过来。故此可以理解为:ios... [阅读全文]
  • iOS实现转盘效果

    本文实例为大家分享了ios实现转盘效果的具体代码,供大家参考,具体内容如下demo下载地址: ios转盘效果功能:实现了常用的ios转盘效果,轮盘抽奖效果的实现... [阅读全文]
  • iOS开发实现转盘功能

    本文实例为大家分享了ios实现转盘功能的具体代码,供大家参考,具体内容如下今天给同学们讲解一下一个转盘选号的功能,直接上代码直接看viewcontroller#... [阅读全文]
  • iOS实现轮盘动态效果

    本文实例为大家分享了ios实现轮盘动态效果的具体代码,供大家参考,具体内容如下一个常用的绘图,主要用来打分之类的动画,效果如下。主要是ios的绘图和动画,本来想... [阅读全文]
  • iOS实现九宫格连线手势解锁

    本文实例为大家分享了ios实现九宫格连线手势解锁的具体代码,供大家参考,具体内容如下demo下载地址:效果图:核心代码://// clockview.m// 手... [阅读全文]
  • iOS实现卡片堆叠效果

    本文实例为大家分享了ios实现卡片堆叠效果的具体代码,供大家参考,具体内容如下如图,这就是最终效果。去年安卓5.0发布的时候,当我看到安卓全新的material... [阅读全文]
  • iOS利用余弦函数实现卡片浏览工具

    iOS利用余弦函数实现卡片浏览工具

    本文实例为大家分享了ios利用余弦函数实现卡片浏览工具的具体代码,供大家参考,具体内容如下一、实现效果通过拖拽屏幕实现卡片移动,左右两侧的卡片随着拖动变小,中间... [阅读全文]
验证码:
移动技术网