ios - 波浪動畫

來源:http://summertreee.github.io/blog/2016/08/07/dong-hua-huang-jin-da-dang-cadisplaylink-and-cashapelayer/

使用
#import "ViewController.h"
#import "YDWaveLoadingView.h"

@interface ViewController ()
@property (nonatomic, strong) YDWaveLoadingView *loadingView;

@end

@implementation ViewController

- (void)viewDidLoad {
   [super viewDidLoad];
   self.view.backgroundColor = [UIColor whiteColor];
   _loadingView = [YDWaveLoadingView loadingView];
   [self.view addSubview:_loadingView];
   _loadingView.center = self.view.center;
   
   dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
       [_loadingView startLoading];
   });
}




@end

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN
@interface YDWaveLoadingView : UIView

+ (instancetype)loadingView;

- (void)startLoading;

- (void)stopLoading;

@end
NS_ASSUME_NONNULL_END
.m
#import "YDWaveLoadingView.h"

typedef NS_ENUM(NSInteger, YDWavePathType) {
    YDWavePathType_Sin,
    YDWavePathType_Cos
};

@interface YDWaveLoadingView ()

@property (nonatomic, assign) CGFloat frequency;
@property (nonatomic, strong) UIImageView *grayImageView;
@property (nonatomic, strong) UIImageView *sineImageView;
@property (nonatomic, strong) UIImageView *cosineImageView;
@property (nonatomic, strong) CAShapeLayer *waveSinLayer;
@property (nonatomic, strong) CAShapeLayer *waveCosLayer;
@property (nonatomic, strong) CADisplayLink *displayLink;
//波浪相關(guān)的參數(shù)
@property (nonatomic, assign) CGFloat waveWidth;
@property (nonatomic, assign) CGFloat waveHeight;
@property (nonatomic, assign) CGFloat waveMid;
@property (nonatomic, assign) CGFloat maxAmplitude;

@property (nonatomic, assign) CGFloat phaseShift;
@property (nonatomic, assign) CGFloat phase;

@end

static CGFloat kWavePositionDuration = 5;

@implementation YDWaveLoadingView

+ (instancetype)loadingView
{
    return [[YDWaveLoadingView alloc] initWithFrame:CGRectMake(0, 0, 40, 31)];
}

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

- (CGSize)intrinsicContentSize
{
    return CGSizeMake(40, 31);
}

#pragma mark - Public Methods
- (void)startLoading
{
    [_displayLink invalidate];
    self.displayLink = [CADisplayLink displayLinkWithTarget:self
                                                   selector:@selector(updateWave:)];
    [_displayLink addToRunLoop:[NSRunLoop currentRunLoop]
                       forMode:NSRunLoopCommonModes];
    CGPoint position = self.waveSinLayer.position;
    position.y = position.y - self.bounds.size.height - 10;
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
    animation.fromValue = [NSValue valueWithCGPoint:self.waveSinLayer.position];
    animation.toValue = [NSValue valueWithCGPoint:position];
    animation.duration = kWavePositionDuration;
    animation.repeatCount = HUGE_VALF;
    animation.removedOnCompletion = NO;
    [self.waveSinLayer addAnimation:animation forKey:@"positionWave"];
    [self.waveCosLayer addAnimation:animation forKey:@"positionWave"];
}

- (void)stopLoading
{
    [self.displayLink invalidate];
    [self.waveSinLayer removeAllAnimations];
    [self.waveCosLayer removeAllAnimations];
    self.waveSinLayer.path = nil;
    self.waveCosLayer.path = nil;
}

#pragma mark - Private Methods
- (void)setupSubViews
{
    self.waveSinLayer = [CAShapeLayer layer];
    _waveSinLayer.backgroundColor = [UIColor clearColor].CGColor;
    self.waveSinLayer.fillColor = [[UIColor greenColor] CGColor];
    self.waveSinLayer.frame = CGRectMake(0, self.bounds.size.height, self.bounds.size.width, self.bounds.size.height);
    
    self.waveCosLayer = [CAShapeLayer layer];
    _waveCosLayer.backgroundColor = [UIColor clearColor].CGColor;
    self.waveCosLayer.fillColor = [[UIColor blueColor] CGColor];
    self.waveCosLayer.frame = CGRectMake(0, self.bounds.size.height, self.bounds.size.width, self.bounds.size.height);
    
    self.waveHeight = CGRectGetHeight(self.bounds) * 0.5;
    self.waveWidth  = CGRectGetWidth(self.bounds);
    self.frequency = .3;
    self.phaseShift = 8;
    self.waveMid = self.waveWidth / 2.0f;
    self.maxAmplitude = self.waveHeight * .3;
    
    _grayImageView = [[UIImageView alloc] initWithFrame:self.bounds];
    _grayImageView.image = [UIImage imageNamed:@"du.png"];
    [self addSubview:_grayImageView];
    
    _cosineImageView = [[UIImageView alloc] initWithFrame:self.bounds];
    _cosineImageView.image = [UIImage imageNamed:@"gray.png"];
    [self addSubview:_cosineImageView];
    
    _sineImageView = [[UIImageView alloc] initWithFrame:self.bounds];
    _sineImageView.image = [UIImage imageNamed:@"blue.png"];
    [self addSubview:_sineImageView];
    
    _sineImageView.layer.mask = _waveSinLayer;
    _cosineImageView.layer.mask = _waveCosLayer;
}

- (void)updateWave:(CADisplayLink *)displayLink
{
    self.phase += self.phaseShift;
    self.waveSinLayer.path = [self createWavePathWithType:YDWavePathType_Sin].CGPath;
    self.waveCosLayer.path = [self createWavePathWithType:YDWavePathType_Cos].CGPath;
}

- (UIBezierPath *)createWavePathWithType:(YDWavePathType)pathType
{
    UIBezierPath *wavePath = [UIBezierPath bezierPath];
    CGFloat endX = 0;
    for (CGFloat x = 0; x < self.waveWidth + 1; x += 1) {
        endX=x;
        CGFloat y = 0;
        if (pathType == YDWavePathType_Sin) {
            y = self.maxAmplitude * sinf(360.0 / _waveWidth * (x  * M_PI / 180) * self.frequency + self.phase * M_PI/ 180) + self.maxAmplitude;
        } else {
            y = self.maxAmplitude * cosf(360.0 / _waveWidth *(x  * M_PI / 180) * self.frequency + self.phase * M_PI/ 180) + self.maxAmplitude;
        }
        
        if (x == 0) {
            [wavePath moveToPoint:CGPointMake(x, y)];
        } else {
            [wavePath addLineToPoint:CGPointMake(x, y)];
        }
    }
    
    CGFloat endY = CGRectGetHeight(self.bounds) + 10;
    [wavePath addLineToPoint:CGPointMake(endX, endY)];
    [wavePath addLineToPoint:CGPointMake(0, endY)];
    
    return wavePath;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末节榜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蠢涝,老刑警劉巖侠草,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肚菠,死亡現(xiàn)場離奇詭異属桦,居然都是意外死亡沦补,警方通過查閱死者的電腦和手機乳蓄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來夕膀,“玉大人虚倒,你說我怎么就攤上這事〔瑁” “怎么了魂奥?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長易猫。 經(jīng)常有香客問我耻煤,道長,這世上最難降的妖魔是什么准颓? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任哈蝇,我火速辦了婚禮,結(jié)果婚禮上攘已,老公的妹妹穿的比我還像新娘炮赦。我一直安慰自己,他們只是感情好样勃,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布吠勘。 她就那樣靜靜地躺著性芬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪剧防。 梳的紋絲不亂的頭發(fā)上批旺,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機與錄音诵姜,去河邊找鬼汽煮。 笑死,一個胖子當(dāng)著我的面吹牛棚唆,可吹牛的內(nèi)容都是我干的暇赤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼宵凌,長吁一口氣:“原來是場噩夢啊……” “哼鞋囊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瞎惫,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤溜腐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后瓜喇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挺益,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年乘寒,在試婚紗的時候發(fā)現(xiàn)自己被綠了望众。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡伞辛,死狀恐怖烂翰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蚤氏,我是刑警寧澤甘耿,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站竿滨,受9級特大地震影響佳恬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜姐呐,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一殿怜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧曙砂,春花似錦头谜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽截驮。三九已至,卻和暖如春际度,著一層夾襖步出監(jiān)牢的瞬間葵袭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工乖菱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留坡锡,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓窒所,卻偏偏與公主長得像鹉勒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子吵取,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

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

  • 在此特此聲明:一下所有鏈接均來自互聯(lián)網(wǎng)禽额,在此記錄下我的查閱學(xué)習(xí)歷程,感謝各位原創(chuàng)作者的無私奉獻(xiàn) 皮官! 技術(shù)一點一點積...
    遠(yuǎn)航的移動開發(fā)歷程閱讀 11,110評論 12 197
  • 10點半睡脯倒,6點半起,2+6.5=8.5小時有核心技術(shù)的人捺氢,才能活到最后藻丢。 iOS 閱讀整理在sourcetree...
    士夢閱讀 3,042評論 0 18
  • 127 薇薇安趴在斐濟島金色的沙灘上,陽光在背上涂上性感的小麥色讯沈。黃一凡在遠(yuǎn)處接打著電話郁岩,盡管本人不在基督城,但找...
    鎮(zhèn)魂歌閱讀 383評論 0 1
  • 我們?yōu)榱擞洗蟊娙焙荩[瞞自己的欲望,把自己變得和別人一樣萍摊。然后又覺得不適挤茄,加了一些小個性。 ...
    sango珊閱讀 515評論 0 0
  • 一首曲冰木,一支狂舞穷劈!就是這么個小瘋女子!
    davidpp閱讀 216評論 0 0