JHChainableAnimations源碼學(xué)習(xí)

JHChainableAnimations源碼學(xué)習(xí)

JHChainableAnimations是什么

JHChainableAnimations 是一個(gè)多系統(tǒng)動(dòng)畫封裝的鏈?zhǔn)秸Z(yǔ)法庫(kù)。

原有的OC代碼如果我們想寫一個(gè)動(dòng)畫,需要這樣寫。

    [UIView animateWithDuration:1.0
                          delay:0.0
         usingSpringWithDamping:0.8
          initialSpringVelocity:1.0
                        options:0 animations:^{
                            CGPoint newPosition = self.myView.frame.origin;
                            newPosition.x += 50;
                            self.myView.frame.origin = newPosition;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.5
                              delay:0.0
                            options:UIViewAnimationOptionCurveEaseIn
                         animations:^{
            self.myView.backgroundColor = [UIColor purpleColor];
        } completion:nil];
    }];

使用 JHChainableAnimations 可以這樣寫:

JHChainableAnimator *animator = [[JHChainableAnimator alloc] initWithView:self.myView];
animator.moveX(50).spring.thenAfter(1.0).makeBackground([UIColor purpleColor]).easeIn.animate(0.5);

代碼一下就顯得特別清晰明了,JHChainableAnimations 采用了現(xiàn)在流行的鏈?zhǔn)秸Z(yǔ)法,跟 Masonry 一樣的語(yǔ)法。

鏈?zhǔn)秸Z(yǔ)法的特點(diǎn)是什么

鏈?zhǔn)骄幊烫攸c(diǎn):方法的返回值是block,block必須有返回值(本身對(duì)象),block參數(shù)(需要操作的值)

JHChainableAnimations代碼具體分析

首先看一段代碼

JHChainableAnimator *animator = [[JHChainableAnimator alloc] initWithView:self.myView];
animator.moveX(100).animate(2);

首先是將 self.myViewJHChainableAnimator *animator 關(guān)聯(lián)起來,然后通過 JHChainableAnimator *animator 進(jìn)行動(dòng)畫設(shè)置。

第二行代碼
animator.moveX(100).animate(2);

首先是 animator 調(diào)用 moveX 方法生成動(dòng)畫樣式,這個(gè)方法從字面上面看 就是 移動(dòng)視圖的X軸,然后調(diào)用 animate 執(zhí)行動(dòng)畫,設(shè)置動(dòng)畫時(shí)間。具體看先 它是如何實(shí)現(xiàn)的。

- (JHChainableFloat)moveX
{
    JHChainableFloat chainable = JHChainableFloat(f) {
        
        [self addAnimationCalculationAction:^(__weak UIView *view, __weak JHChainableAnimator *weakSelf) {
            JHKeyframeAnimation *positionAnimation = [weakSelf basicAnimationForKeyPath:@"position.x"];
            positionAnimation.fromValue = @(view.layer.position.x);
            positionAnimation.toValue = @(view.layer.position.x+f);
            [weakSelf addAnimationFromCalculationBlock:positionAnimation];
        }];
        [self addAnimationCompletionAction:^(__weak UIView *view, __weak JHChainableAnimator *weakSelf) {
            CGPoint position = view.layer.position;
            position.x += f;
            view.layer.position = position;
        }];
        
        return self;
    };
    return chainable;
}

再來回顧下鏈?zhǔn)秸Z(yǔ)法的特點(diǎn):

方法的返回值是block,block必須有返回值(本身對(duì)象),block參數(shù)(需要操作的值)

再來看上面這段代碼:

  1. moveX 方法返回的是一個(gè) block chainable
  2. block 的參數(shù)是一個(gè) float,
  3. block chainable 的返回值是當(dāng)前類 JHChainableAnimator 實(shí)例。

完全符合鏈?zhǔn)秸Z(yǔ)法的特點(diǎn)。

moveX 具體實(shí)現(xiàn)

然后再來看具體實(shí)現(xiàn),moveX 干了什么。

首先是返回了一個(gè) block,然后這個(gè) block 返回了這個(gè)類本身的實(shí)例。

block chainable 都做了什么
  1. 生成一個(gè)可執(zhí)行的動(dòng)畫
     [self addAnimationCalculationAction:^(__weak UIView *view, __weak JHChainableAnimator *weakSelf) {
            JHKeyframeAnimation *positionAnimation = [weakSelf basicAnimationForKeyPath:@"position.x"];
            positionAnimation.fromValue = @(view.layer.position.x);
            positionAnimation.toValue = @(view.layer.position.x+f);
            [weakSelf addAnimationFromCalculationBlock:positionAnimation];
        }];
  1. 生成有個(gè)動(dòng)畫執(zhí)行完畢的回調(diào),修改視圖屬性
    [self addAnimationCompletionAction:^(__weak UIView *view, __weak JHChainableAnimator *weakSelf) {
            CGPoint position = view.layer.position;
            position.x += f;
            view.layer.position = position;
        }];
  1. 返回 當(dāng)前類本身

animate 具體實(shí)現(xiàn)

- (JHChainableAnimation)animate
{
    JHChainableAnimation chainable = JHChainableAnimation(t) {
        
        return self.animateWithCompletion(t, self.completionBlock);
    };
    
    return chainable;
}

華麗的分割線

感覺自己的語(yǔ)言表示能力有問題,突然不知道該怎么往下說下去了。
這個(gè)地方。

重新描述下:

首先是像

- (JHChainableFloat)moveX;
- (JHChainableFloat)moveY;
- (JHChainablePoint)moveXY;
- (JHChainableFloat)moveHeight;
- (JHChainableFloat)moveWidth;

這類方法調(diào)用的時(shí)間,會(huì)生成一些類的動(dòng)畫對(duì)象 JHKeyframeAnimation 然后存儲(chǔ)到 JHAnimationChainLink 的動(dòng)畫數(shù)組里面。

最終 animate 方法是循環(huán)調(diào)用 類數(shù)組里面存儲(chǔ)的 JHAnimationChainLink 對(duì)象,執(zhí)行 JHAnimationChainLink 對(duì)象的 JHKeyframeAnimation動(dòng)畫數(shù)組。
大致就是這樣執(zhí)行的,但是具體的實(shí)現(xiàn)有好多細(xì)節(jié),動(dòng)畫的添加,動(dòng)畫執(zhí)行的回調(diào),取得當(dāng)前執(zhí)行的動(dòng)畫、如何暫停動(dòng)畫等。感覺自己目前的功力還很難描述清楚。就暫時(shí)先告一段落了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 那棵楓樹呢 我在這里等 等了一百年 終究沒有從前的顏色 . 這個(gè)季節(jié)除了枯枝 沒有什么可以編織花環(huán) 你用什么來暗示...
    周延龍閱讀 160評(píng)論 1 5
  • 怪鴨帆說:每個(gè)人都有一個(gè)餐廳的夢(mèng)。在這個(gè)連載里,將用我的親身經(jīng)歷告訴年輕人,如何開自己的第一家餐廳。這個(gè)連載將是一...
    怪鴨帆閱讀 772評(píng)論 4 7
  • 楊絳先生說我們總是想的太多,讀書太少 我在想一個(gè)問題的時(shí)候,總是時(shí)不時(shí)的走神。所以往往一天下來,做成的事情很少,但...
    木頭與琉璃閱讀 290評(píng)論 0 0
  • flask框架第一部,創(chuàng)建一個(gè)項(xiàng)目flask是python中一個(gè)微內(nèi)核的web框架 開發(fā)環(huán)境 python3.6f...
    那個(gè)唐僧閱讀 3,025評(píng)論 0 4
  • 會(huì)議紀(jì)要是在總結(jié)中夾雜著陳述,而且還能夠讓所有參會(huì)者看后感到自己價(jià)值體現(xiàn)的一種文體。不知我總結(jié)的對(duì)不對(duì),反正我是認(rèn)...
    剛剛的鋼閱讀 4,584評(píng)論 0 4

友情鏈接更多精彩內(nèi)容