#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, MoveStatus) {
Start,
Enter,
End
};
@interface BulletView: UIView
@property (nonatomic, assign) int trajectory; //弹道
@property (nonatomic, copy) void(^moveStatusBlock)(MoveStatus status); // 弹幕状态回调
//初始化弹幕
- (instancetype)initWithComment:(NSString*)comment;
//开始动画
- (void)startAnimation;
//结束动画
- (void)stopAnimation;
@end
#import "BulletView.h"
#define Padding 10;
#define PhotoHeight 30;
@interface BulletView ()
@property (nonatomic, strong) UILabel *lbComment;
@property (nonatomic, strong) UIImageView *photoIgv;
@end
@implementation BulletView
//初始化弹幕
- (instancetype)initWithComment:(NSString *)comment {
if (self = [super init]) {
self.backgroundColor = [UIColor redColor];
self.layer.cornerRadius = 15;
NSDictionary *attr = @{NSFontAttributeName:[UIFont systemFontOfSize:14]};
CGFloat width = [comment sizeWithAttribute:attr].width;
self.bounds = CGRectMake(0, 0, width + 2 * Padding + PhotoHeight, 30);
self.lbComment.text = comment;
self.lbcomment.frame = CGRectMake(Padding + PhotoHeight, 0, width, 30);
self.bphotoIgv.frame = CGRectMake(-Padding, -Padding, PhotoHeight + Padding, PhotoHeight + Padding);
self.layer.cornerRadius = () / 2;
self.photoIgv.layer.borderColor = [UIColor orangeColor].CGColor;
self.photoIgv.layer.borderWidath = 1;
self.photoIgv.img = [UIImage imageNamed:@""];
}
return self;
}
//开始动画
- (void)startAnimation {
CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
CGFloat duration = 4.f;
CGFloat wholeWidth = screenWidth + CGRectGetWidth(self.bounds);
//开始弹幕
if (self.moveStausBlock) {
self.moveStatusBlock(Start);
}
//t = s / v;
CGFloat speed = wholeWidth/duration;
CGFloat enterDuration = CGRectGetWidat(self.bounds)/speed;
/*
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(enterDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (self.moveStausBlock) {
self.moveStatusBlock(Enter);
}
});
*/
[self performSelector:@selector(enerScreen) withObject:nil afterDelay:enterDuration];
//[NSObject cancelPreviousPerformRequestsWithTarget:self];
__block CGRect frame = self.frame;
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
frame.origin.x -= wholeWidth;
self.frame = frame;
} completion:^(BOOL finished) {
[self removeFromSuperview];
if (self.moveStatusBlock) {
self.moveStatusBlock(End);
}
}];
}
- (void)enterScreen {
if (self.moveStatusBlock) {
self.moveStatusBlock(Enter);
}
}
//结束动画
- (void)stopAnimation {
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[self.layer removeAllAnimations];
[self removeFromSuperview];
}
- (UILabel *)lbComment {
if (!_lbComment) {
_lbComment = [[UILabel alloc] initWithFrame:CGRectZero];
_lbComment.font = [UIFont systemFontOfSize:14];
_lbComment.textColor = [UIColor whiteColor];
_lbComment.textAlignment = NSTextAlignmentCenter;
[self addSubview:_lbComment];
}
return _lbComment;
}
- (UIImageView *)photoIgv {
if (!_photoIgv) {
_photoIgv = [[UIImageView alloc] init];
_photoIgv.layer.masksToBounds = YES;
_hotoIgv.contentMode = UIViewContentModeScaleAspectFill;
[self addSubview:_hotoIgv];
}
return bphotoIgv;
}
@end
#import <Foundation/Foundation.h>
@class BulletView;
@interface BulletManager: NSObject
@property (nonatomic, copy) void(^generateViewBlock)(BulletView *view);
- (void)start;
- (void)stop;
@end
#import "BulletManager.h"
#import "BulletView.h"
@interface BulletManager ()
//弹幕的数据来源
@property (nonatomic, strong) NSMutableArray *datasource;
//弹幕使用过程中的数组变量
@property (nonatomic, strong) NSMutableArray *bulletComments;
//存储弹幕view的数组变量
@property (nonatomic, strong) NSMutableArray *bulletViews;
@property (nonatomic, assign) BOOL bStopAnimation;
@end
@implementation BulletManager
- (void)start {
[self.bulletComments removeAllObjects];
[self.bulletComments addObjectsFromArray:self.datasource];
[self initBulletComment];
}
- (void)stop {
if (self.bStopAnimation) {
return;
}
self.bStopAnimation = YES;
[self.bulletViews enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonull stop){
BulletView *view = obj;
[view stopAnimation];
view = nil;
}];
[self.bulletViews removeAllObjects];
}
//初始化弹幕,随即分配弹幕轨迹
- (void)initBulletComment {
NSMutableArray *trajectorys = [NSMutableArray arrayWithArray:@[@0, @1, @2]];
for (int i = 0; i < 3; i++) {
if (self.bulletComments.count > 0) {
//随即获取弹幕的轨迹
NSInteger index = arc4random() % trajectorys.count;
int trajectory = [trajectorys[index] intValue];
//从弹幕数组逐一取出弹幕数据
NSString *comment = [self.bulletComments firstObject];
[self.bulletComments removeObjectAtIndex:0];
//创建弹幕
[self createBulletView:comment trajectory:trajectory];
}
}
}
- (void)createBulletView:(NSString *)comment tragectory:(int)trajectory {
if (self.bStopAnimation) { return; }
BulletView *view = [[BulletView alloc] initWithComment:comment];
view.trajectory = trajectory;
__weak typeof (view) weakView = view;
__weak typeof (self) weakSelf = self;
view.moveStatusBlock = ^(MoveStatus status){
if (self.bStopAnimation) { return; }
switch (status) {
case Start: {
[weakSelf.bulletViews addObject:weakView];
break;
}
case Enter: {
//判断是否有其余弹幕
NSString *comment = [weakSelf nextComment];
if (comment) {
[weakSelf createBulletView:comment trajectory:trajectory];
}
break;
}
case End: {
if([weakSelf.bulletViews containsObject:weakView]) {
//飞出释放资源
[weakView stopAnimation];
[weakSelf.bulletViews removeObject:weakView];
}
if (weakSelf.bulletViews.count == 0) {
//屏幕无弹幕 开始循环
self.bStopAnimation = YES;
[weakSelf start];
}
break;
}
default: break;
}
// [weakView stopAnimation];
// [weakSelf.bulletViews removeObject:weakView];
};
if (self.generateViewBlock) {
self.generateViewBlock(weakView);
}
}
- (NSString *)nextComment {
if (self.bulletComments.count == 0) {
return nil;
}
NSString *comment = [self.bulletComments firstObject];
if (comment) {
[self.bulletComments removeObjectAtIndex:0];
}
return comment;
}
- (NSMutableArray *)datasource {
if (!_datasource) {
_datasource = [NSMutableArray arrayWithArray:@[@"测试1", @"测试2", @"测试3", @"测试4", @"测试5", @"测试6", @"测试7", @"测试8"]];
}
return _datasource;
}
- (NSMutableArray *)bulletComments {
if (!_bulletComments) {
_bulletComments = [NSMutableArray array];
}
return _bulletComments;
}
- (NSMutableArray *)bulletViews {
if (!_bulletViews) {
_bulletViews = [NSMutableArray array];
}
return _bulletViews;
}
@end
//某viewController
#import "BulletManager.h"
#import "BulletView.h"
@property (nonatomic, strong) BulletManager *manager;
- (void)viewDidLoad {
[super viewDidLoad];
self.manager = [[BulletManager alloc] init];
__weak typeof(self) weakSelf = self;
self.manager.generateViewBlock = ^(BulletView *view) {
[weakSelf addSubview:view];
};
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[btn setTitle:@"start" forState:UIControlStateNormal];
btn.frame = CGRectMake(100, 100, 100, 40);
[btn addTarget:self action:@selector(clickBtn) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
[btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[btn setTitle:@"stop" forState:UIControlStateNormal];
btn.frame = CGRectMake(250, 100, 100, 40);
[btn addTarget:self action:@selector(clickStopBtn) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
- (void)clickBtn {
[self.manager start];
}
- (void)clickStopBtn {
[self.manager stop];
}
- (void)addBulletView:(BulletView *)view {
CGFloat widath = [UIScreen mainScreen].bounds.size.width;
view.frame = CGRectMake(width, 300 + view.trajectory * 50, CGRectGetWidth(view.bounds), CGRectGetHeight(view.bounds));
[self.view addSubview:view];
[view startAnimation];
}
弹幕相关代码
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 警言:慎终如始! 一,在布局文件中留好Fragment的位置(红色区域),这里可以用别的布局,相对布局,线性布局都...
- 此文章单方面对 贝塞尔曲线画图 核心动画 图层相关 方面做下整理,方便查看! 概念简介 (贝塞尔曲线)是应用于二维...
- http://www.jb51.net/article/30317.htm import socketimport...