iOS --- 如何暫停和繼續(xù)CALayer上的動(dòng)畫(huà)

本文主要介紹了如何暫停和繼續(xù)CALayer的動(dòng)畫(huà). 首先來(lái)看CALayer.

/** The base layer class. **/

@interface CALayer : NSObject <NSCoding, CAMediaTiming>

NSCoding比較常用, 就不多說(shuō)了. 那這個(gè)CAMediaTiming是個(gè)什么東西!

CAMediaTiming

/* The CAMediaTiming protocol is implemented by layers and animations, it
 * models a hierarchical timing system, with each object describing the
 * mapping from time values in the object's parent to local time.
 *
 * Absolute time is defined as mach time converted to seconds. The
 * CACurrentMediaTime function is provided as a convenience for querying the
 * current absolute time.
 *
 * The conversion from parent time to local time has two stages:
 *
 * 1. conversion to "active local time". This includes the point at
 * which the object appears in the parent's timeline, and how fast it
 * plays relative to the parent.
 *
 * 2. conversion from active to "basic local time". The timing model
 * allows for objects to repeat their basic duration multiple times,
 * and optionally to play backwards before repeating. */

從以上介紹我們大概了解到CALayer繼承了CAMediaTiming協(xié)議, 則可以在layer與其父對(duì)象之間進(jìn)行時(shí)間轉(zhuǎn)換.
即, layer上的動(dòng)畫(huà)時(shí)間可以與實(shí)際的時(shí)間進(jìn)行一定的轉(zhuǎn)換. 轉(zhuǎn)換的步驟也描述地比較清楚.
那么這個(gè)轉(zhuǎn)換有什么意義呢?

再看CAMediaTiming, 包含了很多屬性. iOS中給protocol定義屬性, 實(shí)際上是沒(méi)有對(duì)應(yīng)的實(shí)例變量的, 只有g(shù)etter/setter方法.
這一點(diǎn)與category類似: 給category添加屬性柱搜,實(shí)際上只會(huì)添加getter/setter方法,不會(huì)添加真正的實(shí)例變量剥险。
因?yàn)閏ategory是在runtime決定的. 當(dāng)添加實(shí)例變量的話, 類對(duì)象的內(nèi)存空間就要發(fā)生變化了. 而類對(duì)象的內(nèi)存空間是在編譯時(shí)期就確定了的.
因此不能給category添加實(shí)例變量, 但屬性對(duì)應(yīng)的getter/setter依然有效.
protocol也是同樣的道理.
關(guān)于這一點(diǎn)的理解, 不知是否有不準(zhǔn)確的地方, 歡迎一起討論.

@protocol CAMediaTiming

/* The begin time of the object, in relation to its parent object, if
 * applicable. Defaults to 0. */

@property CFTimeInterval beginTime;

/* The basic duration of the object. Defaults to 0. */

@property CFTimeInterval duration;

/* The rate of the layer. Used to scale parent time to local time, e.g.
 * if rate is 2, local time progresses twice as fast as parent time.
 * Defaults to 1. */

@property float speed;

/* Additional offset in active local time. i.e. to convert from parent
 * time tp to active local time t: t = (tp - begin) * speed + offset.
 * One use of this is to "pause" a layer by setting `speed' to zero and
 * `offset' to a suitable value. Defaults to 0. */

@property CFTimeInterval timeOffset;

/* The repeat count of the object. May be fractional. Defaults to 0. */

@property float repeatCount;

/* The repeat duration of the object. Defaults to 0. */

@property CFTimeInterval repeatDuration;

/* When true, the object plays backwards after playing forwards. Defaults
 * to NO. */

@property BOOL autoreverses;

/* Defines how the timed object behaves outside its active duration.
 * Local time may be clamped to either end of the active duration, or
 * the element may be removed from the presentation. The legal values
 * are `backwards', `forwards', `both' and `removed'. Defaults to
 * `removed'. */

@property(copy) NSString *fillMode;

@end

看到了我們非常熟悉的duration和autoreverses, 原來(lái)是CAMediaTiming中才有的. 最初還以為是CALayer自身的屬性...
另外幾個(gè)關(guān)鍵的屬性, beginTime, speed, timeOffset分別是什么東西呢?

  • beginTime: 繼承CAMediaTiming協(xié)議的對(duì)象的起始時(shí)間, 與父對(duì)象有關(guān)系. 什么鬼, 不是非常明了...
  • speed: 表示local time與parent time的比例關(guān)系, 默認(rèn)為1, 即二者時(shí)間保持一致. 舉了個(gè)例子, 當(dāng)speed為2的時(shí)候, local time會(huì)比parent time快一倍.
  • timeOffset: 時(shí)間偏移量, 這個(gè)就更難理解了. 總之, 就是用于在local time與parent time之間進(jìn)行轉(zhuǎn)換的一個(gè)什么偏移量.

看了這些注釋, 依然不曉得具體怎么使用CAMediaTiming及其屬性, 那么請(qǐng)看下邊的實(shí)例.
通過(guò)暫停動(dòng)畫(huà)和繼續(xù)動(dòng)畫(huà)的兩個(gè)方法, 非常簡(jiǎn)明地介紹了這些相關(guān)的屬性.

開(kāi)始動(dòng)畫(huà)

[UIView animateWithDuration:2.0 animations:^{
    view1.frame = CGRectMake(self.view.frame.size.width - 100, 100, 100, 100);
} completion:^(BOOL finished) {
}];

暫停動(dòng)畫(huà)

- (void)demosAnimationPause:(UIButton *)sender {
    // 將當(dāng)前時(shí)間CACurrentMediaTime轉(zhuǎn)換為layer上的時(shí)間, 即將parent time轉(zhuǎn)換為local time
    CFTimeInterval pauseTime = [view1.layer convertTime:CACurrentMediaTime() fromLayer:nil];

    // 設(shè)置layer的timeOffset, 在繼續(xù)操作也會(huì)使用到
    view1.layer.timeOffset = pauseTime;

    // local time與parent time的比例為0, 意味著local time暫停了
    view1.layer.speed = 0;
}

One use of this is to "pause" a layer by setting speed to zero and offset to a suitable value.

暫停動(dòng)畫(huà)的操作實(shí)際上非常簡(jiǎn)單.

繼續(xù)動(dòng)畫(huà)

- (void)demosAnimationContinue:(UIButton *)sender {
    // 時(shí)間轉(zhuǎn)換
    CFTimeInterval pauseTime = view1.layer.timeOffset;
    // 計(jì)算暫停時(shí)間
    CFTimeInterval timeSincePause = CACurrentMediaTime() - pauseTime;
    // 取消
    view1.layer.timeOffset = 0;
    // local time相對(duì)于parent time世界的beginTime
    view1.layer.beginTime = timeSincePause;
    // 繼續(xù)
    view1.layer.speed = 1;
}

那么如何繼續(xù)執(zhí)行動(dòng)畫(huà)呢? 重新正確設(shè)置local time的beginTime與speed即可.
其實(shí), 最難理解的就是local time與parent time, 及其之間的轉(zhuǎn)換關(guān)系.

Demo

Demo請(qǐng)參考:
iOS-Animation

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末聪蘸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子表制,更是在濱河造成了極大的恐慌健爬,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夫凸,死亡現(xiàn)場(chǎng)離奇詭異浑劳,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)夭拌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)魔熏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)衷咽,“玉大人,你說(shuō)我怎么就攤上這事蒜绽∠馄” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵躲雅,是天一觀的道長(zhǎng)鼎姊。 經(jīng)常有香客問(wèn)我,道長(zhǎng)相赁,這世上最難降的妖魔是什么相寇? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮钮科,結(jié)果婚禮上唤衫,老公的妹妹穿的比我還像新娘。我一直安慰自己绵脯,他們只是感情好佳励,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著蛆挫,像睡著了一般赃承。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上悴侵,一...
    開(kāi)封第一講書(shū)人閱讀 50,084評(píng)論 1 291
  • 那天瞧剖,我揣著相機(jī)與錄音,去河邊找鬼畜挨。 笑死筒繁,一個(gè)胖子當(dāng)著我的面吹牛噩凹,可吹牛的內(nèi)容都是我干的巴元。 我是一名探鬼主播,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼驮宴,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼逮刨!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起堵泽,我...
    開(kāi)封第一講書(shū)人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤修己,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后迎罗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體睬愤,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年纹安,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了尤辱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片砂豌。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖光督,靈堂內(nèi)的尸體忽然破棺而出阳距,到底是詐尸還是另有隱情,我是刑警寧澤结借,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布筐摘,位于F島的核電站,受9級(jí)特大地震影響船老,放射性物質(zhì)發(fā)生泄漏咖熟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一柳畔、第九天 我趴在偏房一處隱蔽的房頂上張望球恤。 院中可真熱鬧,春花似錦荸镊、人聲如沸咽斧。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)张惹。三九已至,卻和暖如春岭洲,著一層夾襖步出監(jiān)牢的瞬間宛逗,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工盾剩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留雷激,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓告私,卻偏偏與公主長(zhǎng)得像屎暇,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子驻粟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

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