關(guān)于Custom Segues的初探筆記

開發(fā)過(guò)程中漫雕,我們往往會(huì)需要滿足各種各樣的跳轉(zhuǎn)Segues的需求秉颗,光靠自帶的那幾個(gè)默認(rèn)的轉(zhuǎn)場(chǎng)似乎無(wú)法滿足成天充滿奇思妙想的產(chǎn)品定位人員(哥稽穆,我完全沒有惡意。哥你說(shuō)啥效果我就給你啥效果米丘,你是我親哥)
AppCoda上有一篇文章其實(shí)有專門非常詳細(xì)的講述了有關(guān)于Custom自定義轉(zhuǎn)場(chǎng)Segues的一個(gè)小例子剑令,國(guó)內(nèi)也有譯文版本,大概預(yù)覽了下拄查,自己也照著做了個(gè)小的Demo吁津。我調(diào)重要的部分做為學(xué)習(xí)的筆記,也希望能給到看到本篇文章的您一點(diǎn)啟發(fā)
Demo的主要功能其實(shí)很簡(jiǎn)單堕扶,建立三個(gè)View Controller碍脏,以不同的方式(向上滑動(dòng)屏幕,向下滑動(dòng)屏幕稍算,點(diǎn)擊按鈕)進(jìn)行自定義轉(zhuǎn)場(chǎng)典尾,當(dāng)中會(huì)用到一些動(dòng)畫去呈現(xiàn),三個(gè)View視圖控制器都會(huì)根據(jù)跳轉(zhuǎn)和返回視圖(Segue <-> Unwind)呈現(xiàn)相應(yīng)的數(shù)據(jù)糊探。讓我們了解轉(zhuǎn)場(chǎng)和解除轉(zhuǎn)場(chǎng)并在這之間進(jìn)行數(shù)據(jù)呈現(xiàn)的所有過(guò)程钾埂。Demo的效果如圖

1421999721366749.gif

首先在Main.storyboard里面創(chuàng)建好這三個(gè)ViewController河闰,并添加三個(gè)類對(duì)這三個(gè)View視圖進(jìn)行綁定。再建立兩個(gè)完整轉(zhuǎn)場(chǎng)動(dòng)作的四個(gè)自定義類(主視圖跳轉(zhuǎn)到第二視圖褥紫,第二視圖回到主視圖的segue和unwind處理類姜性。主視圖點(diǎn)擊按鈕跳轉(zhuǎn)到第三視圖,第三視圖回到主視圖的segue和unwind處理類髓考,他們都繼承自UIStoryboardSegue)部念,當(dāng)然也要?jiǎng)?chuàng)建主視圖segue連線創(chuàng)建custom轉(zhuǎn)場(chǎng)方式并在轉(zhuǎn)場(chǎng)中寫好Identifier、綁定剛剛創(chuàng)建的segue處理類氨菇,在主視圖的ViewController上創(chuàng)建一個(gè)@IBAction方法(解除轉(zhuǎn)場(chǎng)依賴且必須要定義一個(gè)這樣的方法)儡炼,同樣的segue連線把第二視圖對(duì)象與Exit連線綁定剛剛創(chuàng)建在主視圖里的@IBAction,并設(shè)置好Identifier查蓉。準(zhǔn)備好了這一切射赛,此時(shí)你已經(jīng)設(shè)置好了第一視圖和第二視圖所需要的準(zhǔn)備工作,讓我們用代碼的角度看下奶是,ViewController#1 和 ViewController#2之間互相切換的時(shí)候過(guò)程是怎么樣產(chǎn)生的
1.當(dāng)app啟動(dòng)的時(shí)候,第一個(gè)視圖viewDidLoad()被執(zhí)行竣灌,向上滑動(dòng)聂沙,創(chuàng)建好的識(shí)別器被啟動(dòng):
var swipeGestureRecognizer:UISwipeGestureRecognizer=UISwipeGestureRecognizer(target:self, action:"showSecondViewController") swipeGestureRecognizer.direction=UISwipeGestureRecognizerDirection.Up self.view.addGestureRecognizer(swipeGestureRecognizer)
2.識(shí)別器啟動(dòng)了綁定的方法:
func showSecondViewController() { self.performSegueWithIdentifier("idFirstSegue", sender:self) }
上面的方法體里啟動(dòng)Identifier值為“idFirstSegue”的類(就是我們之前綁定的主視圖向第二視圖的segue處理類)
segue處理類做的事情就是重載父類UIStoryboardSegue的perform方法,此時(shí)此方法被啟動(dòng):
override func perform() { var firstVCView =self.sourceViewController.view as UIView! var secondVCView =self.destinationViewController.view as UIView! let screenWidth =UIScreen.mainScreen().bounds.size.width let screenHeight =UIScreen.mainScreen().bounds.size.height secondVCView.frame=CGRectMake(0.0, screenHeight, screenWidth, screenHeight) let window =UIApplication.sharedApplication().keyWindow window?.insertSubview(secondVCView, aboveSubview: firstVCView) UIView.animateWithDuration(0.4, animations: { () ->Voidin firstVCView.frame=CGRectOffset(firstVCView.frame,0.0, -screenHeight) secondVCView.frame=CGRectOffset(secondVCView.frame,0.0, -screenHeight) }) { (Finished) ->Voidin self.sourceViewController.presentViewController(self.destinationViewController as! UIViewController, animated:false,completion:nil) } }
上面做的事情其實(shí)很簡(jiǎn)單初嘹,我們一行行解讀
首先得到源視圖窗口對(duì)象
得到目標(biāo)視圖窗口對(duì)象
得到屏幕的寬和高
指定應(yīng)該出現(xiàn)視圖的初始位置及汉。把視圖放在當(dāng)前視圖的正下方,設(shè)置frame讓他在視圖外
得到窗口的子視圖對(duì)象
把窗口子視圖對(duì)象放到目標(biāo)視圖
UIView啟用animateWithDuration動(dòng)畫運(yùn)動(dòng)屯烦,修改兩個(gè)視圖的frame坷随,把視圖1移除到屏幕上方邊緣,同時(shí)把視圖2放到視圖1原來(lái)的位置,在后面設(shè)置一個(gè)掛尾閉包執(zhí)行顯示目標(biāo)控制器
以上就是一個(gè)完整的主圖切換到第二視圖的過(guò)程

我們來(lái)看看解除轉(zhuǎn)場(chǎng)又是怎么樣的:
我們現(xiàn)在要做的就是解除轉(zhuǎn)場(chǎng)的準(zhǔn)備工作:
當(dāng)解除轉(zhuǎn)場(chǎng)發(fā)生的時(shí)候驻龟,會(huì)自動(dòng)調(diào)用我們?cè)赩iewController處理類中寫好的重載segueForUnwindingToViewController方法温眉,需要注意的是,他有三個(gè)參數(shù)分別是:fromViewController翁狐,toViewController還有identifier类溢,字面意識(shí)上就可以解釋:當(dāng)前顯示的視圖控制器(消失的)、目標(biāo)視圖控制器(要它顯示的)露懒、第三個(gè)大家都懂(轉(zhuǎn)場(chǎng)行為標(biāo)示符)闯冷,代碼如下:
override func segueForUnwindingToViewController(toViewController: UIViewController, fromViewController: UIViewController, identifier: String?) -> UIStoryboardSegue { if let id = identifier{ if id == "idFirstSegueUnwind"{ //初始化解除轉(zhuǎn)場(chǎng)自定義類的對(duì)象 let unwindSegue = FirstCustomSegueUnwind(identifier: id, source: fromViewController, destination: toViewController , performHandler: { () -> Void in }) return unwindSegue //返回這個(gè)解除專場(chǎng)自定義類對(duì)象 } }//同樣返回此行為對(duì)象給父類的super方法 return super.segueForUnwindingToViewController(toViewController, fromViewController: fromViewController, identifier: identifier) }
上面代碼上也很好理解,例子是主視圖綁定的兩個(gè)視圖之間的跳轉(zhuǎn)懈词,所以需要通過(guò)判斷identifier來(lái)判斷返回到哪個(gè)解除轉(zhuǎn)場(chǎng)中
完成了解除轉(zhuǎn)場(chǎng)的準(zhǔn)備工作蛇耀,接著就是觸發(fā)他了:

這個(gè)時(shí)候我們?cè)诘诙晥D的ViewController中所以,當(dāng)用戶向下滑動(dòng)屏幕:

var swipeGestureRecognizer:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "showFirstViewController")//定義一個(gè)滑動(dòng)手勢(shì)坎弯,并綁定滑動(dòng)的action方法是: showFirstViewController()方法 swipeGestureRecognizer.direction = UISwipeGestureRecognizerDirection.Down//滑動(dòng)的方向纺涤,向下 self.view.addGestureRecognizer(swipeGestureRecognizer)//讓視圖添加識(shí)別動(dòng)作為 (向下滑動(dòng)) 的識(shí)別器
//當(dāng)向下滑動(dòng)译暂,執(zhí)行方法 func showFirstViewController(){ self.performSegueWithIdentifier("idFirstSegueUnwind", sender: self)//執(zhí)行轉(zhuǎn)場(chǎng)行為,轉(zhuǎn)場(chǎng)行為是identifier里面的id }
(⊙o⊙)… 是不是這個(gè)時(shí)候覺得洒琢,怎么那么眼熟秧秉,是的,歷史又開始重演
這個(gè)時(shí)候監(jiān)聽到用戶滑動(dòng)的識(shí)別器開始執(zhí)行第二視圖倒回第一視圖:Unweid的解除轉(zhuǎn)場(chǎng)處理類
同樣跟上面的segue處理類相同衰抑,也是重寫父類的perform方法

override func perform() { var secondVCView = self.sourceViewController.view as UIView! var firstVCView = self.destinationViewController.view as UIView! let screenHeight = UIScreen.mainScreen().bounds.size.height let window = UIApplication.sharedApplication().keyWindow window?.insertSubview(firstVCView, aboveSubview: secondVCView) UIView.animateWithDuration(0.4, animations: { () -> Void in firstVCView.frame = CGRectOffset(firstVCView.frame, 0.0, screenHeight) secondVCView.frame = CGRectOffset(secondVCView.frame, 0.0, screenHeight) }) { (Finished) -> Void in self.sourceViewController.dismissViewControllerAnimated(false, completion: nil) } }
相信大家也都能看出來(lái)Unwind唯一和Segue區(qū)別的就是:源視圖和目標(biāo)視圖相反了(很好理解象迎,就是現(xiàn)在需要第二視圖轉(zhuǎn)向第一視圖)
animateWithDuration運(yùn)動(dòng)現(xiàn)在是把兩個(gè)視圖都同時(shí)做底部移動(dòng)的動(dòng)作

** 以上就是解除轉(zhuǎn)場(chǎng)Unwind處理類的寫法 **

轉(zhuǎn)場(chǎng)運(yùn)動(dòng)的時(shí)候數(shù)據(jù)的傳輸也很簡(jiǎn)單,其實(shí)就是通過(guò)重載prepareForSegue這個(gè)方法進(jìn)行的呛踊,這個(gè)方法會(huì)得到一個(gè)segue對(duì)象砾淌,所以我們可以以此segue對(duì)象判斷是哪個(gè)identifier的ID的轉(zhuǎn)場(chǎng)來(lái)進(jìn)行l(wèi)abel的顯示值操作,代碼如下:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if segue.identifier == "idFirstSegue" { let secondViewController = segue.destinationViewController as! SecondViewController secondViewController.message = "Hello from the 1st View Controller" } }
同樣的解除轉(zhuǎn)場(chǎng)時(shí)候谭网,也可以在第二視圖的處理類中寫相同的代碼汪厨,包括第三個(gè)視圖的segue和Unwind這里就不再重復(fù)了
還有就是第三個(gè)視圖轉(zhuǎn)換到主視圖時(shí)候的縮小動(dòng)畫,其實(shí)也不是什么很難的東西:
主視圖跳轉(zhuǎn)到第三個(gè)視圖的動(dòng)畫實(shí)現(xiàn):
thirdVCView.transform = CGAffineTransformScale(thirdVCView.transform, 0.001, 0.001) UIView.animateWithDuration(0.5, animations: { () -> Void in firstVCView.transform = CGAffineTransformScale(thirdVCView.transform, 0.001, 0.001) }) { (Finished) -> Void in UIView.animateWithDuration(0.5, animations: { () -> Void in thirdVCView.transform = CGAffineTransformIdentity }, completion: { (Finished) -> Void in firstVCView.transform = CGAffineTransformIdentity self.sourceViewController.presentViewController(self.destinationViewController as! UIViewController, animated: false, completion: nil) }) }
第三個(gè)視圖解除轉(zhuǎn)場(chǎng)動(dòng)畫實(shí)現(xiàn):
firstVCView.frame = CGRectOffset(firstVCView.frame, 0.0, screenHeight) firstVCView.transform = CGAffineTransformScale(firstVCView.transform, 0.001, 0.001) let window = UIApplication.sharedApplication().keyWindow window?.insertSubview(firstVCView, aboveSubview: thirdVCView) UIView.animateWithDuration(0.5, animations: { () -> Void in thirdVCView.transform = CGAffineTransformScale(thirdVCView.transform, 0.001, 0.001) thirdVCView.frame = CGRectOffset(thirdVCView.frame, 0.0, -screenHeight) firstVCView.transform = CGAffineTransformIdentity firstVCView.frame = CGRectOffset(firstVCView.frame, 0.0, -screenHeight) }) { (Finished) -> Void in self.sourceViewController.dismissViewControllerAnimated(false, completion: nil) }
值得一提的是愉择,當(dāng)初我們創(chuàng)建的解除轉(zhuǎn)場(chǎng)綁定@IBAction方法劫乱,其實(shí)她就是實(shí)現(xiàn)第二視圖解除轉(zhuǎn)場(chǎng)回到第一視圖閃了一下紅色背景,并實(shí)現(xiàn)第三視圖回到第一視圖 welcome back那句label的方法:
@IBAction func returnFromSegueActions(sender: UIStoryboardSegue){ if sender.identifier == "idFirstSegueUnwind" { let originalColor = self.view.backgroundColor self.view.backgroundColor = UIColor.redColor() UIView.animateWithDuration(1.0, animations: { () -> Void in self.view.backgroundColor = originalColor }) } else{ self.lblMessage.text = "Welcome back!" } }
在這個(gè)IBAction中我們可以窺探并預(yù)想到轉(zhuǎn)場(chǎng)之間我們需要和能做到的事情
文章已經(jīng)看到這里的同學(xué),應(yīng)該可以完全理解上面的句子的含義

額锥涕,結(jié)尾了衷戈,好長(zhǎng)好長(zhǎng),原文其實(shí)更長(zhǎng),很多都是重復(fù)的层坠,所以我以自己的理解殖妇,把運(yùn)行過(guò)程以分段式的方式去解釋當(dāng)中的代碼(其實(shí)就是偷懶~ ??哈哈)
相信也希望以上我的學(xué)習(xí)總結(jié),能夠幫助到你理解自定義轉(zhuǎn)場(chǎng)的所有過(guò)程破花,同時(shí)在這個(gè)基礎(chǔ)上創(chuàng)建更多的可能性

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谦趣,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子座每,更是在濱河造成了極大的恐慌前鹅,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件峭梳,死亡現(xiàn)場(chǎng)離奇詭異嫡纠,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)延赌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門除盏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人挫以,你說(shuō)我怎么就攤上這事者蠕。” “怎么了掐松?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵踱侣,是天一觀的道長(zhǎng)粪小。 經(jīng)常有香客問我,道長(zhǎng)抡句,這世上最難降的妖魔是什么探膊? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮待榔,結(jié)果婚禮上逞壁,老公的妹妹穿的比我還像新娘。我一直安慰自己锐锣,他們只是感情好腌闯,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著雕憔,像睡著了一般姿骏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上斤彼,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天分瘦,我揣著相機(jī)與錄音,去河邊找鬼琉苇。 笑死擅腰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的翁潘。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼歼争,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼拜马!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起沐绒,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤俩莽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后乔遮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扮超,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年蹋肮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了出刷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡坯辩,死狀恐怖馁龟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情漆魔,我是刑警寧澤坷檩,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布却音,位于F島的核電站,受9級(jí)特大地震影響矢炼,放射性物質(zhì)發(fā)生泄漏系瓢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一句灌、第九天 我趴在偏房一處隱蔽的房頂上張望夷陋。 院中可真熱鬧,春花似錦涯塔、人聲如沸肌稻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)爹谭。三九已至,卻和暖如春榛搔,著一層夾襖步出監(jiān)牢的瞬間诺凡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工践惑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留腹泌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓尔觉,卻偏偏與公主長(zhǎng)得像凉袱,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子侦铜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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