Album Animation Part III: Interactive UICollectionViewLayout Transition

系列重寫了戈抄,這篇文章留在這里記錄下錯(cuò)誤思路苏章。

系列前兩篇文章在此:Part I, Part II皇帮。三天前還信心滿滿地要把 Interactive Push Transition 弄出來(lái)刽严,到此刻不得不聲明寸潦,用盡了我能嘗試的辦法,沒(méi)能解決琉历。囧rz坠七。暫時(shí)找不到解決辦法水醋,先記錄下思路,以便日后復(fù)盤彪置。

在使用 pinch 手勢(shì) push toViewController 的 transition 中發(fā)生的事件順序如下:
1.fromVC.pinch and initial.toVC
2.toVC.viewDidLoad()
3.navigationController.push(toVC)
4.ask navigation transition delegate for: animation controller, interactive controller
5.toVC.viewWillAppear()
6.AnimationController.animateTransition(contextTransition) //Transition 動(dòng)畫開(kāi)始
7.toVC.collectionView:cellForItemAtIndexPath: //cell 開(kāi)始在屏幕上
8.toVC.pinch.End and contextTransition.completeTransition() //push transitin 結(jié)束
9.toVC.viewDidAppear()

WWDC13 Session 218: Custom Transitions Using View Controllers 中工程師一再?gòu)?qiáng)調(diào)不保證 transition 中 viewDidAppear() 發(fā)生在 viewWillAppear() 之后拄踪,之前墨客的開(kāi)發(fā)者也發(fā)過(guò)一篇文章講過(guò)這個(gè)問(wèn)題,不過(guò)目前來(lái)看這個(gè)順序還算穩(wěn)定悉稠。

Part II 中可知宫蛆,若是 push transition 中有動(dòng)畫沒(méi)有發(fā)生在 AnimationController 的- animateTransition:中,那么終止交互后無(wú)法維持這個(gè)動(dòng)畫的繼續(xù)或是返回的猛。將一個(gè) UICollectionviewController push transition 變成可交互的困難在于在無(wú)法在 AnimationController 的- animateTransition:發(fā)生前獲取目標(biāo)視圖中的 Cells,也就無(wú)法將 Cell 上的動(dòng)畫放入- animateTransition:以進(jìn)行交互控制(在 pop 時(shí)就不存在這個(gè)問(wèn)題想虎,因此此時(shí) Cells 可以使用 collectionView.visibleCells() 來(lái)獲取卦尊,所以 pop 的交互化就很簡(jiǎn)單了)。于是思路轉(zhuǎn)換為在手勢(shì)控制過(guò)程中讓其布局跟隨手勢(shì)更新舌厨,在手勢(shì)結(jié)束后更新布局為需要的布局并將這個(gè)過(guò)程動(dòng)畫化岂却。這個(gè)思路將 cell 的動(dòng)畫的控制權(quán)從由交互控制器 InteractiveController 轉(zhuǎn)移到了手勢(shì)中。此時(shí)有兩種方案:

  1. UICollectionViewTransitionLayout: iOS 7 推出的新類裙椭,用于對(duì)布局更新進(jìn)行動(dòng)畫躏哩,在 WWDC13 Session 218: Custom Transitions Using View Controllers 中跟著其他三種視圖轉(zhuǎn)換機(jī)制一起隆重推出,看起來(lái)是個(gè)合適的選擇揉燃。
    UICollectionView layout transition

    在手勢(shì)更新過(guò)程中只要更新第一個(gè)方法返回的UICollectionViewTransitionLayouttransitionProgress屬性值就可以對(duì)整個(gè)過(guò)程進(jìn)行控制扫尺。在一個(gè) viewDidAppear 后的 collectionView 使用該類進(jìn)行布局轉(zhuǎn)換是非常方便以及簡(jiǎn)單的,一切如你想象的那樣炊汤。然而正驻,在 push transition 中,這個(gè)類無(wú)法正常工作抢腐。
  2. 手動(dòng)對(duì)布局進(jìn)行更新:這個(gè)聽(tīng)起來(lái)更靠譜一點(diǎn)姑曙,除了有點(diǎn)惱人的布局動(dòng)畫的性能除外,在結(jié)束手勢(shì)時(shí)布局動(dòng)畫會(huì)播放兩次迈倍,就壞在這里了伤靠,百思不得其解。手動(dòng)更新布局有個(gè)很容易掉進(jìn)去的坑:更新布局后啼染,使用 toVC.collectionViewLayout 得到的僅僅是 toVC 初始化時(shí)的布局宴合,而不是更新后的布局,必須通過(guò) toVC.collectionView.collectionViewLayout 來(lái)獲取提完。這個(gè)坑可坑死我了形纺。一直納悶為啥有時(shí)候能手勢(shì)驅(qū)動(dòng)布局更新,有時(shí)候又不能徒欣,因?yàn)槲覜](méi)注意到這兩個(gè)方法的區(qū)別逐样。

這里有個(gè)環(huán)節(jié)我的代碼里可能會(huì)存在問(wèn)題,就是手勢(shì)的建立。下面代碼做的事就是在 pinch 手勢(shì)的 Begin 狀態(tài)下脂新,實(shí)例化目標(biāo)控制器 toVC 并 push挪捕。

func handlePinchGestureAction(gesture:UIPinchGestureRecognizer){
    let scale = gesture.scale
    if scale >= 1.0{
        if let indexPath = collectionView?.indexPathForItemAtPoint(gesture.locationInView(collectionView)){
            switch gesture.state{
            case .Began:
                interactive = true
                let cell = collectionView?.cellForItemAtIndexPath(indexPath)
                let cellReferencePoint = cell?.convertPoint(CGPointMake(10, 10), toView: self.collectionView!)
                
                let layoutAttributes = self.collectionView!.layoutAttributesForItemAtIndexPath(indexPath)
                let imageOriginInSuperView = self.collectionView!.convertPoint((layoutAttributes?.frame.origin)!, toView: self.collectionView!.superview)
                
                if let toVC = self.storyboard?.instantiateViewControllerWithIdentifier("AlbumVC") as? SDEAlbumViewController{
                    
                    let initialLayout = PushTransitionInitialStateFlowLayout(cell!.convertPoint(CGPointMake(85, 85), toView: self.collectionView!))
                    toVC.collectionView?.setCollectionViewLayout(initialLayout, animated: true)
                    /***進(jìn)行一些配置***/    
                    //必須將當(dāng)前的手勢(shì)添加到toView,在 toVC 自行添加的手勢(shì)在 push transition 中無(wú)法被識(shí)別                    
                    gesture.addTarget(toVC, action: "handlePushTransitionActionWithPinchGesture:")
                    toVC.view.addGestureRecognizer(gesture)
                    toVC.interactivePushTransitionDelegate = interactivePushTransitionDelegate
                    
                    self.navigationController?.delegate = self
                    self.navigationController?.pushViewController(toVC, animated: true)
                }
            case .Changed:
                interactive = false
            default:
                interactive = false
            }
        }     
    }
}

上述過(guò)程中將 fromView 中的 pinch 手勢(shì)復(fù)制到了 toView 中争便,因?yàn)樵?toView 的初始化過(guò)程中自行添加的手勢(shì)在 push transition 中無(wú)法被識(shí)別级零。另外當(dāng)前的 pinch 手勢(shì)在 fromView 中很難檢測(cè)到 Ended 或是 Cancelled狀態(tài),大概是隔了一層 toView 的緣故滞乙,而在 toView 中卻檢測(cè)不到 Begin 狀態(tài)奏纪,Begin 狀態(tài)的缺失讓UICollectionViewTransitionLayout的初始化工作也就是調(diào)用- startInteractiveTransitionToCollectionViewLayout:completion:有點(diǎn)困難。不過(guò)這個(gè)好解決斩启,讓這個(gè)方法只運(yùn)行一次的方法很多序调,接下來(lái)只要在手勢(shì)的 Changed, Ended, Cancelled 的狀態(tài)中走一下 UICollectionViewTransitionLayout 的標(biāo)準(zhǔn)流程就可以了。但問(wèn)題來(lái)了兔簇,這個(gè)類似乎很脆弱发绢,得小心翼翼地使用 pinch,你能看到預(yù)期的效果垄琐,一旦你快速地使用边酒,基本上就會(huì)出現(xiàn)以下錯(cuò)誤,google 無(wú)果狸窘。
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'the collection was not prepared for an interactive transition. see startInteractiveTransitionToCollectionViewLayout:completion:'

Photos 和 Paper 里的 pinch 手勢(shì)驅(qū)動(dòng) push transition 就是我想要的效果墩朦,前兩者基本從一個(gè) Stack 布局的 CollectionView 轉(zhuǎn)換到最常見(jiàn)的 FlowLayout 布局的 CollectionView,這個(gè)方案在WWDC13 Session 218中演示過(guò)朦前,demo 代碼在此: ViewTransition Demo Code in WWDC13 Session 218介杆。但我著手解決的這個(gè)問(wèn)題和它們有點(diǎn)不一樣,我想要的是從 toView 出現(xiàn)后進(jìn)行布局轉(zhuǎn)換韭寸,然而卻不遂我愿春哨,也許這條路走不通,等我有心情了再試試恩伺。

今天在微博上看到 CKWaveCollectionViewTransition 這個(gè)效果赴背,主要是 cell 之間的時(shí)間差調(diào)節(jié)得非常驚艷,之前我也有類似的調(diào)整晶渠,但基本上看不出效果來(lái)凰荚,看人家的代碼,用于調(diào)整時(shí)間差的算法還是很復(fù)雜的褒脯,反正掃一眼代碼就暈菜了便瑟。雖然動(dòng)畫時(shí)間有點(diǎn)長(zhǎng),但這個(gè)驚艷的畫面表現(xiàn)我忍了番川。動(dòng)畫在質(zhì)量而不在數(shù)量到涂,相比之下脊框,我嘗試做了好幾種效果,卻差了老遠(yuǎn)践啄。

在摸索過(guò)程中浇雹,也許有很多地方我不了解而犯了錯(cuò),就比如動(dòng)畫放在哪兒執(zhí)行屿讽,就只能在- viewDidLoad, - viewWillAppear:, - viewWillDisappear:中挨個(gè)試昭灵;還有出現(xiàn)那個(gè)問(wèn)題 google 無(wú)果后,我也沒(méi)有手段去探知哪個(gè)環(huán)節(jié)出錯(cuò)伐谈,盡管從函數(shù)調(diào)用幀上看到出錯(cuò)的地方似乎是內(nèi)部的實(shí)現(xiàn)問(wèn)題烂完,但這種束手無(wú)策的境地讓我很不安,是時(shí)候好好學(xué)習(xí) debug 了衩婚。前年實(shí)習(xí)的時(shí)候窜护,我的上司面對(duì)一些問(wèn)題總是會(huì)"異想天開(kāi)"地在一些環(huán)節(jié)上下手,在我看來(lái)不了解系統(tǒng)的相關(guān)流程非春,這么瞎搞效率很低,但有不少時(shí)候我的上司這么瞎搞搞問(wèn)題還真解決了缓屠。唉奇昙,踢一腳有時(shí)候就能解決大部分的電器問(wèn)題。

另外敌完,看了人家的代碼储耐,能直接拿來(lái)用,而我的則不行滨溉,要好好設(shè)計(jì)下代碼才行什湘。

目前這個(gè)問(wèn)題我實(shí)在有點(diǎn)厭煩了,絞盡腦汁晦攒,就差那么一點(diǎn)點(diǎn)闽撤,然而路還是被堵死了,這種無(wú)望煩躁在長(zhǎng)時(shí)間盯著電腦精神迷糊或是 Xcode 對(duì) Swift 的糟糕支持下更加嚴(yán)重了脯颜,我要轉(zhuǎn)移下注意力哟旗。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市栋操,隨后出現(xiàn)的幾起案子闸餐,更是在濱河造成了極大的恐慌,老刑警劉巖矾芙,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舍沙,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡剔宪,警方通過(guò)查閱死者的電腦和手機(jī)拂铡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門壹无,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人和媳,你說(shuō)我怎么就攤上這事格遭。” “怎么了留瞳?”我有些...
    開(kāi)封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵拒迅,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我她倘,道長(zhǎng)璧微,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任硬梁,我火速辦了婚禮前硫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘荧止。我一直安慰自己屹电,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布跃巡。 她就那樣靜靜地躺著危号,像睡著了一般。 火紅的嫁衣襯著肌膚如雪素邪。 梳的紋絲不亂的頭發(fā)上外莲,一...
    開(kāi)封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音兔朦,去河邊找鬼偷线。 笑死,一個(gè)胖子當(dāng)著我的面吹牛沽甥,可吹牛的內(nèi)容都是我干的声邦。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼安接,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼翔忽!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起盏檐,我...
    開(kāi)封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤歇式,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后胡野,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體材失,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年硫豆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了龙巨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片笼呆。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖旨别,靈堂內(nèi)的尸體忽然破棺而出诗赌,到底是詐尸還是另有隱情,我是刑警寧澤秸弛,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布铭若,位于F島的核電站,受9級(jí)特大地震影響递览,放射性物質(zhì)發(fā)生泄漏叼屠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一绞铃、第九天 我趴在偏房一處隱蔽的房頂上張望镜雨。 院中可真熱鬧,春花似錦儿捧、人聲如沸荚坞。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)西剥。三九已至,卻和暖如春亿汞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背揪阿。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工疗我, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人南捂。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓吴裤,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親溺健。 傳聞我的和親對(duì)象是個(gè)殘疾皇子麦牺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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

  • 前言的前言 唐巧前輩在微信公眾號(hào)「iOSDevTips」以及其博客上推送了我的文章后,我的 Github 各項(xiàng)指標(biāo)...
    VincentHK閱讀 5,341評(píng)論 3 44
  • 效果預(yù)覽: 前言 蘋果自家應(yīng)用 Photos 里點(diǎn)擊相冊(cè)后的動(dòng)畫是非常精妙的鞭缭,而且是可交互的剖膳。我有類似的動(dòng)畫需求,...
    seedante閱讀 5,736評(píng)論 3 39
  • iOS視圖控制器詳解 視圖控制器中的視圖顯示在屏幕上有兩種方式:最主要的方式是內(nèi)嵌在容器控制器中岭辣,比如 UINav...
    coder_feng閱讀 11,199評(píng)論 2 12
  • 下午三點(diǎn)吱晒,一個(gè)又黑又壯、穿著綠色護(hù)士服的彪形大漢帶我去手術(shù)室沦童,他先帶我到護(hù)士站打了一針阿托品仑濒。這家伙塊頭雖大叹话,卻很...
    楊愛(ài)民閱讀 527評(píng)論 6 4
  • 若有明天 我想像掠過(guò)的流星般燦爛 若有明天 我想一直注視銀河、月亮和櫻花 若有明天 我想焚盡曾經(jīng)流淌筆下的癡情詩(shī)篇...
    芊里行云閱讀 176評(píng)論 1 2