微博紅包加載動(dòng)畫

新浪微博的紅包加載動(dòng)畫澳骤,過年在家里搶紅包看到這個(gè)效果,就順手仿照著寫了一下为肮。主要還是利用余弦函數(shù)曲線的特性實(shí)現(xiàn)的。

具體原理是圓球在從左向右移動(dòng)時(shí)時(shí)先縮小再放大颊艳,圓球從右向左移動(dòng)時(shí)先放大在縮小棋枕;然后再加上另一個(gè)圓球就實(shí)現(xiàn)了這樣遠(yuǎn)近交換的效果。
GitHub地址:https://github.com/mengxianliang/XLDotLoading
XLDot.h

#import <UIKit/UIKit.h>

typedef NS_ENUM(NSInteger,DotDitection)
{
    DotDitectionLeft = -1,
    DotDitectionRight = 1,
};


@interface XLDot : UIView

//移動(dòng)方向 就兩種 左重斑、右
@property (nonatomic,assign) DotDitection direction;
//字體顏色
@property (nonatomic,strong) UIColor *textColor;

@end

XLDot.m

#import "XLDot.h"

@interface XLDot ()
{
    UILabel *_label;
}
@end

@implementation XLDot

-(instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self buildUI];
    }
    return self;
}

-(void)buildUI
{
    self.layer.cornerRadius = self.bounds.size.width/2.0f;
    self.layer.masksToBounds = true;
    
    _label = [[UILabel alloc] initWithFrame:self.bounds];
    _label.textAlignment = NSTextAlignmentCenter;
    _label.font = [UIFont boldSystemFontOfSize:20];
    _label.text = @"¥";
    _label.adjustsFontSizeToFitWidth = true;
    [self addSubview:_label];
}

-(void)setTextColor:(UIColor *)textColor
{
    _textColor = textColor;
    _label.textColor = textColor;
}

@end

XLDotLoading.h

#import <UIKit/UIKit.h>

@interface XLDotLoading : UIView

//顯示方法
+(void)showInView:(UIView*)view;
//隱藏方法
+(void)hideInView:(UIView*)view;

-(void)start;

-(void)stop;

@end

XLDotLoading.m

#import "XLDotLoading.h"
#import "XLDot.h"

@interface XLDotLoading ()
{
    NSMutableArray *_dots;
    
    CADisplayLink *_link;
    
    UIView *_dotContainer;
}
@end

@implementation XLDotLoading

//初始化方法
-(instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self buildUI];
        [self buildData];
    }
    return self;
}

//豆的寬度
-(CGFloat)dotWidth
{
    CGFloat margin = _dotContainer.bounds.size.width/5.0f;
    CGFloat dotWidth = (_dotContainer.bounds.size.width - margin)/2.0f;
    return  dotWidth;
}

-(CGFloat)speed
{
    return  2.0f;
}

//初始化兩個(gè)豆
-(void)buildUI
{
    //初始化存放豆豆的的容器
    _dotContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 80, 50)];
    _dotContainer.center = self.center;
    [self addSubview:_dotContainer];
    
    //一個(gè)豆放左 一個(gè)豆放右
    _dots = [NSMutableArray new];
    NSArray *dotBackGroundColors = @[[self R:255 G:218 B:134 A:1],[self R:245 G:229 B:216 A:1]];
    NSArray *textColors = @[[self R:255 G:197 B:44 A:1],[self R:237 G:215 B:199 A:1]];
    
    for (NSInteger i = 0; i<textColors.count; i++) {
        CGFloat dotX = i==0 ? 0 : _dotContainer.bounds.size.width - [self dotWidth];
        //初始化開始運(yùn)動(dòng)的方向 左邊的方向是向右 右邊的方向是向左
        DotDitection direction = i==0 ? DotDitectionRight : DotDitectionLeft;
        XLDot *dot = [[XLDot alloc] initWithFrame:CGRectMake(dotX, 0, [self dotWidth],[self dotWidth])];
        dot.center = CGPointMake(dot.center.x, _dotContainer.bounds.size.height/2.0f);
        dot.layer.cornerRadius = dot.bounds.size.width/2.0f;
        dot.backgroundColor = dotBackGroundColors[i];
        dot.direction = direction;
        dot.textColor = textColors[i];
        [_dotContainer addSubview:dot];
        [_dots addObject:dot];
    }
}

//初始化定時(shí)刷新
-(void)buildData
{
    _link = [CADisplayLink displayLinkWithTarget:self selector:@selector(reloadView)];
}

//開始動(dòng)畫
-(void)start
{
    [_link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}

//停止動(dòng)畫
-(void)stop
{
    [_link removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}

//刷新UI
-(void)reloadView
{
    XLDot *dot1 = _dots.firstObject;
    
    XLDot *dot2 = _dots.lastObject;
    
    //改變移動(dòng)方向祖很、約束移動(dòng)范圍
    //移動(dòng)到右邊距時(shí)
    if (dot1.center.x >= _dotContainer.bounds.size.width - [self dotWidth]/2.0f) {
        CGPoint center = dot1.center;
        center.x = _dotContainer.bounds.size.width - [self dotWidth]/2.0f;
        dot1.center = center;
        dot1.direction = DotDitectionLeft;
        dot2.direction = DotDitectionRight;
        [_dotContainer bringSubviewToFront:dot1];
    }
    //移動(dòng)到左邊距時(shí)
    if (dot1.center.x <= [self dotWidth]/2.0f) {
        dot1.center = CGPointMake([self dotWidth]/2.0f, dot2.center.y);
        dot1.direction = DotDitectionRight;
        dot2.direction = DotDitectionLeft;
        [_dotContainer sendSubviewToBack:dot1];
    }
    
    //更新第一個(gè)豆的位置
    CGPoint center1 = dot1.center;
    center1.x += dot1.direction * [self speed];
    dot1.center = center1;
    //顯示放大效果
    [self showAnimationsOfDot:dot1];
    
    //根據(jù)第一個(gè)豆的位置確定第二個(gè)豆的位置
    CGFloat apart = dot1.center.x - _dotContainer.bounds.size.width/2.0f;
    CGPoint center2 = dot2.center;
    center2.x = _dotContainer.bounds.size.width/2.0f - apart;
    dot2.center = center2;
    [self showAnimationsOfDot:dot2];
}

//顯示放大漾脂、縮小動(dòng)畫
-(void)showAnimationsOfDot:(XLDot*)dot
{
    CGFloat apart = dot.center.x - _dotContainer.bounds.size.width/2.0f;
    //最大距離
    CGFloat maxAppart = (_dotContainer.bounds.size.width - [self dotWidth])/2.0f;
    //移動(dòng)距離和最大距離的比例
    CGFloat appartScale = apart/maxAppart;
    //獲取比例對(duì)應(yīng)余弦曲線的Y值
    CGFloat transfomscale = cos(appartScale * M_PI/2.0);
    
    
    //向右移動(dòng)則 中間變大 兩邊變小
    if (dot.direction == DotDitectionLeft) {
        dot.transform = CGAffineTransformMakeScale(1 + transfomscale/4.0f, 1 + transfomscale/4.0f);
        //向左移動(dòng)則 中間變小 兩邊變大
    }else if (dot.direction == DotDitectionRight){
        dot.transform = CGAffineTransformMakeScale(1 - transfomscale/4.0f,1 - transfomscale/4.0f);
    }
}

-(UIColor*)R:(CGFloat)r G:(CGFloat)g B:(CGFloat)b A:(CGFloat)a
{
    return [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a];
}

#pragma mark -
#pragma mark 功能方法

+(XLDotLoading *)getLoadingInView:(UIView *)view {
    
    XLDotLoading *loading = nil;
    for (XLDotLoading *subview in view.subviews) {
        if ([subview isKindOfClass:[XLDotLoading class]]) {
            loading = subview;
        }
    }
    return loading;
}

+(void)showInView:(UIView*)view
{
    XLDotLoading *loading = [[XLDotLoading alloc] initWithFrame:view.bounds];
    [view addSubview:loading];
    [loading start];
}

+(void)hideInView:(UIView *)view
{
    XLDotLoading *loading = [XLDotLoading getLoadingInView:view];
    if (loading) {
        [loading removeFromSuperview];
        [loading stop];
    }
}


@end

Simulator Screen Shot 2017年5月8日 下午7.55.45.png
Simulator Screen Shot 2017年5月8日 下午7.55.49.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末骨稿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子啊终,更是在濱河造成了極大的恐慌,老刑警劉巖蓝牲,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異例衍,居然都是意外死亡昔期,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門硼一,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人般贼,你說我怎么就攤上這事『咔” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵腮介,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我叠洗,道長(zhǎng)甘改,這世上最難降的妖魔是什么灭抑? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮腾节,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘禀倔。我一直安慰自己参淫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布涎才。 她就那樣靜靜地躺著,像睡著了一般耍铜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上棕兼,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音伴挚,去河邊找鬼靶衍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛颅眶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涛酗,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼商叹!你這毒婦竟也來了燕刻?” 一聲冷哼從身側(cè)響起沈自,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎枯途,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酪夷,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年晚岭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坦报。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖片择,靈堂內(nèi)的尸體忽然破棺而出潜的,到底是詐尸還是另有隱情字管,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布嘲叔,位于F島的核電站,受9級(jí)特大地震影響硫戈,放射性物質(zhì)發(fā)生泄漏锰什。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一卵牍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧糊昙,春花似錦、人聲如沸谢谦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至千劈,卻和暖如春祭刚,著一層夾襖步出監(jiān)牢的瞬間墙牌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來泰國(guó)打工喜滨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人虽风。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像辜膝,于是被迫代替她去往敵國(guó)和親无牵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子厂抖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容