add flying commit
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// LXDanMuManager.h
|
||||
// LXAnimationTest
|
||||
//
|
||||
// Created by lianxiang on 2018/8/14.
|
||||
// Copyright © 2018年 com.giga.ios. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
@interface LXDanMuManager : NSObject
|
||||
@property (nonatomic,strong) NSArray *trackSpeedArray;
|
||||
@property (nonatomic,assign) float centerY;//所有轨道中心点
|
||||
@property (nonatomic,assign) float trackWidth;
|
||||
@property (nonatomic,strong) NSTimer *timer;
|
||||
@property (nonatomic,strong) UIView *superView;
|
||||
@property (nonatomic,strong) NSMutableArray *trackArray;
|
||||
@property (nonatomic,strong) UIView *baseView;
|
||||
|
||||
+(LXDanMuManager *)shareInstance;
|
||||
-(void)createDanmuWithTrackSpeedArray:(NSArray *)trackSpeedArray centerY:(float)centerY trackWidth:(float)trackWidth showInView:(UIView *)inView;
|
||||
/**
|
||||
插入一条弹幕,可以插入任意继承UIView的对象
|
||||
|
||||
@param customView 自定义的view(注意,最高不能超过轨道的高,否则会出问题)
|
||||
@param trackIndex 插入弹幕的轨道(为-1则代表自动寻找最不拥挤的轨道插入)
|
||||
*/
|
||||
-(void)appendDanMuWithCustomView:(UIView *)customView toTrackIndex:(NSInteger)trackIndex;
|
||||
-(void)start;
|
||||
-(void)pause;
|
||||
-(void)stop;
|
||||
-(void)destory;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,145 @@
|
||||
//
|
||||
// LXDanMuManager.m
|
||||
// LXAnimationTest
|
||||
//
|
||||
// Created by lianxiang on 2018/8/14.
|
||||
// Copyright © 2018年 com.giga.ios. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LXDanMuManager.h"
|
||||
#import "LXDanMuTrackView.h"
|
||||
|
||||
@implementation LXDanMuManager
|
||||
|
||||
+ (LXDanMuManager *)shareInstance{
|
||||
static LXDanMuManager *managerInstance = nil;
|
||||
static dispatch_once_t once;
|
||||
dispatch_once(&once, ^{
|
||||
managerInstance = [[self alloc] init];
|
||||
});
|
||||
return managerInstance;
|
||||
}
|
||||
|
||||
- (void)createDanmuWithTrackSpeedArray:(NSArray *)trackSpeedArray centerY:(float)centerY trackWidth:(float)trackWidth showInView:(UIView *)inView{
|
||||
_superView = inView;
|
||||
_trackSpeedArray = trackSpeedArray;
|
||||
_centerY = centerY;
|
||||
_trackWidth = trackWidth;
|
||||
_trackArray = [[NSMutableArray alloc] init];
|
||||
[self initUI];
|
||||
}
|
||||
|
||||
-(void)initUI{
|
||||
_baseView = [[UIView alloc] initWithFrame:CGRectMake(0, 0,_trackWidth, 0)];
|
||||
_baseView.userInteractionEnabled = NO;
|
||||
[_superView addSubview:_baseView];
|
||||
|
||||
for (int i = 0; i<_trackSpeedArray.count; i++) {
|
||||
|
||||
LXDanMuTrackView *trackView = [[LXDanMuTrackView alloc] initWithFrame:CGRectMake(0, (TRACK_HEIGHT + TRACK_VERTICAL_PADDING) * i, _baseView.frame.size.width, TRACK_HEIGHT)];
|
||||
[_baseView addSubview:trackView];
|
||||
[_trackArray addObject:trackView];
|
||||
if (_trackSpeedArray.count - 1 == i) {
|
||||
_baseView.frame = CGRectMake(_baseView.frame.origin.x, _baseView.frame.origin.y, _baseView.frame.size.width,CGRectGetMaxY(trackView.frame));
|
||||
_baseView.center = CGPointMake(_baseView.center.x, _centerY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void)start{
|
||||
|
||||
if (_timer) {
|
||||
return;
|
||||
}
|
||||
_timer = [NSTimer timerWithTimeInterval:0.01 target:self selector:@selector(startAction) userInfo:nil repeats:YES];
|
||||
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
|
||||
|
||||
}
|
||||
|
||||
- (void)pause{
|
||||
[_timer invalidate];
|
||||
_timer = nil;
|
||||
}
|
||||
|
||||
- (void)stop{
|
||||
|
||||
[_timer invalidate];
|
||||
_timer = nil;
|
||||
for (LXDanMuTrackView *trackView in _trackArray) {
|
||||
[trackView cleanTrack];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)destory{
|
||||
|
||||
[_timer invalidate];
|
||||
_timer = nil;
|
||||
for (LXDanMuTrackView * trackView in _trackArray) {
|
||||
[trackView cleanTrack];
|
||||
[trackView removeFromSuperview];
|
||||
}
|
||||
[_trackArray removeAllObjects];
|
||||
[_baseView removeFromSuperview];
|
||||
_trackSpeedArray = nil;
|
||||
_superView = nil;
|
||||
_baseView = nil;
|
||||
_trackArray = nil;
|
||||
|
||||
}
|
||||
|
||||
-(void)startAction{
|
||||
|
||||
for (int i = 0; i < _trackArray.count; i++) {
|
||||
//执行轨道定时器方法
|
||||
LXDanMuTrackView *trackView = _trackArray[i];
|
||||
[trackView moveViewWithSpeed:[_trackSpeedArray[i] floatValue]];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
-(UIView *)baseView{
|
||||
if (!_baseView) {
|
||||
_baseView = [[UIView alloc] initWithFrame:CGRectMake(0, 0,_trackWidth, 0)];
|
||||
|
||||
}
|
||||
return _baseView;
|
||||
}
|
||||
|
||||
//自定义的view(注意,最高不能超过轨道的高,会出问题)
|
||||
- (void)appendDanMuWithCustomView:(UIView *)customView toTrackIndex:(NSInteger)trackIndex
|
||||
{
|
||||
//trackIndex 插入弹幕的轨道(为-1则代表自动寻找最不拥挤的轨道插入)
|
||||
NSInteger realTrackIndex = trackIndex;
|
||||
if (realTrackIndex == -1) {
|
||||
realTrackIndex = [self findTheMinTotalWidthTrack];
|
||||
}
|
||||
LXDanMuTrackView *trackView = _trackArray[realTrackIndex];
|
||||
[trackView appendWithCustomView:customView];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
找到最短右侧出屏幕和等待数组总长度最短的轨道序号
|
||||
|
||||
@return 轨道的序号
|
||||
*/
|
||||
|
||||
- (int)findTheMinTotalWidthTrack
|
||||
{
|
||||
LXDanMuTrackView *firstTrackView = _trackArray[0];
|
||||
int minWidthIndex = 0;
|
||||
float minWidth = [firstTrackView rightOutScreenWidth];
|
||||
for (int i = 0; i<_trackArray.count; i++)
|
||||
{
|
||||
LXDanMuTrackView *trackView = _trackArray[i];
|
||||
float trackRightOutScreenWidth = [trackView rightOutScreenWidth];
|
||||
if (trackRightOutScreenWidth < minWidth)
|
||||
{
|
||||
minWidth = trackRightOutScreenWidth;
|
||||
minWidthIndex = i;
|
||||
}
|
||||
}
|
||||
return minWidthIndex;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// LXDanMuManagerConfig.h
|
||||
// LXAnimationTest
|
||||
//
|
||||
// Created by lianxiang on 2018/8/14.
|
||||
// Copyright © 2018年 com.giga.ios. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef LXDanMuManagerConfig_h
|
||||
#define LXDanMuManagerConfig_h
|
||||
|
||||
//轨道中弹幕的最小间距
|
||||
#define TRACK_HORIZONTAL_PADDING 10
|
||||
//轨道与轨道的纵向间距
|
||||
#define TRACK_VERTICAL_PADDING 10
|
||||
//轨道的高度(轨道上的View不能超过此高度)
|
||||
#define TRACK_HEIGHT 60
|
||||
|
||||
#endif /* LXDanMuManagerConfig_h */
|
||||
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// LXDanMuTrackView.h
|
||||
// LXAnimationTest
|
||||
//
|
||||
// Created by lianxiang on 2018/8/14.
|
||||
// Copyright © 2018年 com.giga.ios. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "LXDanMuManagerConfig.h"
|
||||
|
||||
@interface LXDanMuTrackView : UIView
|
||||
|
||||
/**
|
||||
等待出现到屏幕中的弹幕view数组
|
||||
*/
|
||||
@property (nonatomic,strong) NSMutableArray *waitShowArray;
|
||||
|
||||
/**
|
||||
正在展示的弹幕view数组
|
||||
*/
|
||||
@property (nonatomic,strong) NSMutableArray *showingArray;
|
||||
/**
|
||||
向轨道中插入一条自定义的view
|
||||
|
||||
@param view 自定义的view,高度不可超过轨道的高,否则出问题
|
||||
*/
|
||||
- (void)appendWithCustomView:(UIView *)view;
|
||||
|
||||
/**
|
||||
当前轨道右侧出屏幕的距离+等待出现到屏幕中的弹幕view的总长度和
|
||||
@return 等待弹幕+右侧出屏幕弹幕的和
|
||||
*/
|
||||
- (float)rightOutScreenWidth;
|
||||
/**
|
||||
清理轨道,移除所有弹幕
|
||||
*/
|
||||
- (void)cleanTrack;
|
||||
/**
|
||||
根据速度移动轨道中所有弹幕的位置
|
||||
|
||||
@param speed 每0.01秒弹幕向左移动的距离
|
||||
*/
|
||||
- (void)moveViewWithSpeed:(float)speed;
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,123 @@
|
||||
//
|
||||
// LXDanMuTrackView.m
|
||||
// LXAnimationTest
|
||||
//
|
||||
// Created by lianxiang on 2018/8/14.
|
||||
// Copyright © 2018年 com.giga.ios. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LXDanMuTrackView.h"
|
||||
|
||||
@implementation LXDanMuTrackView
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame{
|
||||
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
[self dataConfig];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)dataConfig{
|
||||
|
||||
_showingArray = [[NSMutableArray alloc] init];
|
||||
_waitShowArray = [[NSMutableArray alloc] init];
|
||||
|
||||
}
|
||||
|
||||
- (void)appendWithCustomView:(UIView *)view{
|
||||
|
||||
view.frame = CGRectMake(self.frame.size.width,view.frame.origin.y, view.frame.size.width,view.frame.size.height);
|
||||
view.center = CGPointMake(view.center.x, TRACK_HEIGHT/2);
|
||||
if (_showingArray.count) {
|
||||
UIView *lastView = [_showingArray lastObject];
|
||||
//最右侧的那条弹幕还没有完全出现在屏幕中
|
||||
if (CGRectGetMaxX(lastView.frame) + TRACK_HORIZONTAL_PADDING > self.frame.size.width || _waitShowArray.count) {
|
||||
//把这条弹幕加到等待数组中
|
||||
[_waitShowArray addObject:view];
|
||||
}else{
|
||||
//加入轨道
|
||||
[self addSubview:view];
|
||||
//加入展示数组
|
||||
[_showingArray addObject:view];
|
||||
|
||||
}
|
||||
}else{
|
||||
|
||||
[self addSubview:view];
|
||||
[_showingArray addObject:view];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)moveViewWithSpeed:(float)speed{
|
||||
//正在展示的弹幕自减一次
|
||||
for (UIView *view in _showingArray) {
|
||||
view.frame = CGRectMake(view.frame.origin.x - speed, view.frame.origin.y, view.frame.size.width, view.frame.size.height);
|
||||
|
||||
}
|
||||
//正在展示的弹幕
|
||||
if (_showingArray.count){
|
||||
UIView *firstView = [_showingArray firstObject];
|
||||
UIView *lastView = [_showingArray lastObject];
|
||||
|
||||
if (CGRectGetMaxX(firstView.frame) < 0) {
|
||||
//已移除屏幕 remove
|
||||
[firstView removeFromSuperview];
|
||||
[_showingArray removeObjectAtIndex:0];
|
||||
|
||||
}
|
||||
if (_waitShowArray.count) {
|
||||
//最右侧的view 已经完全出现
|
||||
if (CGRectGetMaxX(lastView.frame) + TRACK_HORIZONTAL_PADDING <= self.frame.size.width) {
|
||||
//转移数组
|
||||
[_showingArray addObject:[_waitShowArray firstObject]];
|
||||
[_waitShowArray removeObjectAtIndex:0];
|
||||
[self addSubview:[_showingArray lastObject]];
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
- (float)rightOutScreenWidth
|
||||
{
|
||||
float outScreenWidth = 0.0;
|
||||
//如果等待数组中有值
|
||||
if (_waitShowArray.count)
|
||||
{
|
||||
//先遍历所有等待数组中的view,累加长度和间距
|
||||
for (UIView *view in _waitShowArray)
|
||||
{
|
||||
outScreenWidth += view.frame.size.width + TRACK_HORIZONTAL_PADDING;
|
||||
}
|
||||
}
|
||||
|
||||
//如果展示数组中有值
|
||||
if (_showingArray.count)
|
||||
{
|
||||
//拿出最右侧的view
|
||||
UIView *lastView = [_showingArray lastObject];
|
||||
//算出出屏宽
|
||||
float rightOutWidth = CGRectGetMaxX(lastView.frame) - self.frame.size.width;
|
||||
if (rightOutWidth < 0)
|
||||
{
|
||||
rightOutWidth = 0;
|
||||
}
|
||||
outScreenWidth += rightOutWidth;
|
||||
}
|
||||
|
||||
return outScreenWidth;
|
||||
}
|
||||
|
||||
//清理轨道
|
||||
- (void)cleanTrack
|
||||
{
|
||||
for (UIView *view in _showingArray)
|
||||
{
|
||||
[view removeFromSuperview];
|
||||
}
|
||||
[_showingArray removeAllObjects];
|
||||
[_waitShowArray removeAllObjects];
|
||||
|
||||
}
|
||||
@end
|
||||
Reference in New Issue
Block a user