最近项目中要使用直播功能,自然就涉及礼物效果展示。示例效果如下图
主要是解决2个问题:
1.动画效果。
2.送到多次礼物后礼物按收到顺序播放动画。
思路:
1.针对第一个问题,使用UIView的动画即可做出。
2.第二个问题要实时监听新加入的动画并且按顺序执行,自然就想到用队列NSOperationQueue
处理。第一步,创建一个最大并发数为1的队列(满足FIFO),这样可以使动画按顺序执行。但是出现了新的问题:每个Operation中的代码也是异步的!这样导致动画并不是一个执行完了再接着一个执行。于是想到一个投机的办法,让线程sleep
......
核心代码很简单,主要是用的UIView的动画效果,直接看代码
@interface ViewController ()
@property (strong, nonatomic) NSOperationQueue *queue;
@end
@implementation ViewController
- (NSOperationQueue *)queue
{
if (!_queue)
{
self.queue = [[NSOperationQueue alloc] init];
//最大并发数量为1,实现FIFO
self.queue.maxConcurrentOperationCount = 1;
}
return _queue;
}
//点击一次模拟收到一次礼物
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^
{
//根据具体的逻辑展示不同的动画
[self receiveGift:@"mogu"];
}];
[self.queue addOperation:op];
}
//执行动画
- (void)receiveGift:(NSString *)giftName
{
CGFloat duringTime = 4;
CGFloat WH = 100;
CGFloat leftOffSet = 50;
//动画效果需要在主线程中进行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
{
UIImageView *aImageView = [[UIImageView alloc] initWithFrame:CGRectMake(-WH, 0, WH, WH)];
aImageView.image = [UIImage imageNamed:giftName];
[self.view addSubview:aImageView];
CGAffineTransform zoomInScaleTransform = CGAffineTransformMakeScale(0.5, 0.5);
aImageView.transform = zoomInScaleTransform;
[UIView animateKeyframesWithDuration:duringTime delay:0 options:0 animations:^
{
[UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0.1 animations:^
{
aImageView.transform = CGAffineTransformIdentity;
aImageView.center = CGPointMake(self.view.frame.size.width * 0.5 - leftOffSet, self.view.frame.size.height * 0.5 - 100);
}];
[UIView addKeyframeWithRelativeStartTime:0.1 relativeDuration:0.8 animations:^
{
aImageView.center = CGPointMake(self.view.frame.size.width * 0.5 + leftOffSet, self.view.frame.size.height * 0.5 - 100);
}];
[UIView addKeyframeWithRelativeStartTime:0.9 relativeDuration:0.1 animations:^
{
aImageView.center = CGPointMake(self.view.frame.size.width + WH,0);
aImageView.transform = CGAffineTransformMakeScale(0.5, 0.5);
}];
}
completion:^(BOOL finished)
{
[aImageView removeFromSuperview];
}];
});
//线程休眠
sleep(duringTime);
}
通过sleep
让线程休眠起到线程执行时间为完整的一个动画时间达到预期的效果。
大神若有更好的思路请告诉我😂.....