【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记23 多MVC模式Demo的实现
上一話我們對Demo的選擇界面做了自動布局的相關處理,現在開始連接多個MVC的操作。首先我們需要其他工程中的文件,那么讓我們打開另一個app。點擊下面這個文件
然后拖動我們需要的文件到新的工程目錄下:
注意勾選第一行,不然只是做了引用,如果你不小心刪除了目標目錄的話,你就找不到這些文件了,所以還是推薦做復制,這樣會把文件復制到我們自己的工程目錄下。
那么storyboard中的內容怎么辦呢,我們只需要在原工程的storyboard中選中控制器然后復制,粘貼到新工程的storyboard中即可。
我注意到一個問題,當我復制粘貼過來的時候控制器中的臉沒有了。看起來需要一些觸發的小動作。我們來到FaceView中做一些小修改然后回退再保存就好了。
看,現在出來了。現在把這兩個MVC添加到分欄控制器中,別忘了把左側的小箭頭移到分欄控制器中,具體做法我們之前已經介紹過了,這里就不啰嗦了,直接看結果:
我們在ip6 plus上運行一下,如果是豎屏你會看到:
跟其他尺寸的iphone一樣,即便你左右滑動也不會出現笑臉,但是如果你橫屏的話會看到:
這和ipad上的效果是相同的,我們之前講過ip6 plus比較特殊,雖然屏幕小但是清晰度很高,在橫屏模式下和ipad是一樣的,關于自動布局的東西以后會細講。
在我們繼續下面的工作前需要修改storyboard以適應iphone,之前講過我們在master上Embed in一個導航控制器,現在在iphone6上運行你會看到初始界面變成:
點擊返回就可以回到選擇界面,如果你在導航欄上加了一個標題,storyboard中會出現警告,原因是我們新加的導航欄會擋住之前的label,依舊update frame就好了。現在我們把master和detail關聯起來。我們使用segue,之前講過了拖拽按鈕到小人臉的控制器上然后選擇show detail,三個按鈕都做重復的動作,三個segue分別命名為sad 、happy、meh(即不開心也不難過)。
現在你在iphone上運行可以看到點擊按鈕頁面發生跳轉了,說明segue生效了,但是小人臉的表情并沒有發生變化,因為我們還沒有準備segue,回憶一下之前講的。
回到PsychologistViewController的代碼中,我們在這個代碼中所需要做的就是為segue做準備。
import UIKitclass PsychologistViewController: UIViewController {override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {if let hvc = segue.destinationViewController as? HappinessViewController,let identifier = segue.identifier{switch identifier{case "sad":hvc.happiness = 0case "happy":hvc.happiness = 100default:hvc.happiness = 50}}}}請注意我這里if let(可選綁定)的寫法,這是Swift 1.2版本的新寫法,避免了有很多if let{}嵌套的情況。看起來一切都很美好?那么運行一下點擊一個按鈕,你會發現程序崩潰了。中控臺提示在解包一個可選型的時候發現了空值。錯誤定位到了updateUI這里:
你會看到faceView是空值。回顧一下之前的代碼,我們剛才修改了happiness的值,來看看happiness的屬性觀察器:
var happiness:Int = 75 {//0代表傷心,100代表開心didSet{happiness = max(min(happiness, 100), 0)println("happiness = \(happiness)")updateUI()}}你會發現這里調用了updateUI方法,而這個方法中的faceView是用IBOutlet定義的!
這就是我們之前講過的,outlet在segue的時候還沒有初始化。
那么如何解決這個問題呢?幸運的是當我們想要修改模型的值時會更新頁面的內容,如果這個時候頁面的outlet沒有值的話,只要忽略就好了。很簡單的做法,我們把可能為空的值放入可選鏈中:
func updateUI(){faceView?.setNeedsDisplay()}意思是如果faceView為空,那么后面的都不會被執行。只需要這么一個簡單的問號,再次運行你會發現得到了我們想要的效果。現在我們給detail部分也增加一個導航控制器,并且標題根據點擊按鈕的值得不同來設定。依舊Embed In一個。
然后在updateUI這個方法中增加一行:
func updateUI(){faceView?.setNeedsDisplay()title = "\(happiness)"}我們之前講的控制器中有屬性傳達給它的導航控制器,然后控制器負責繪制,運行看看,你會發現標題是不會出現的:
這也是我們之前講的,當你增加了一個導航控制器后,所有的segue都指向了導航控制器,而不再是detail本身了:
那么如何修改呢?
import UIKitclass PsychologistViewController: UIViewController {override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {var destination = segue.destinationViewController as? UIViewControllerif let navCon = destination as? UINavigationController{destination = navCon.visibleViewController}if let hvc = destination as? HappinessViewController,let identifier = segue.identifier{switch identifier{case "sad":hvc.happiness = 0case "happy":hvc.happiness = 100default:hvc.happiness = 50}}}}這里我們做了一個判斷,當我們不確定某個控制器是否在導航控制器中的時候,我們可以應用這種寫法。如果有導航控制器那么取出控制器中的最上面的控制器也就是Demo中的HappinessViewController,把它賦給destination,如果沒有就把segue中保存的目標控制器賦給destination。現在可以運行了:
之前的segue都是我們通過storyboard中實現的,現在讓我們來試試如何通過代碼來實現,我們新加一個按鈕取名Noting!然后通過頁面間的拖動來產生segue。我們選中master控制器上方的黃色按鈕
拖拽到detail的導航控制器中松手選擇show detail。取名為nothing,然后我們打開聯合視圖拖動nothing按鈕到控制器代碼中生成一個action,action代碼如下:
@IBAction func nothing(sender: UIButton) {performSegueWithIdentifier("nothing", sender: nil)}可以看到我們讓sender為nil代表點擊這個按鈕什么都沒做,但是它依舊會執行到prepareForSegue方法,此時我們在prepareForSegue方法中增加一個case: case "nothing":hvc.happiness = 25
運行你會發現nothing按鈕依舊起作用了。
那么我們為什么要在代碼中使用segue呢,你可能在按鈕被點擊之后需要根據一些狀態來判斷使用哪個segue,這是在代碼中使用segue的經典理由。
總結
以上是生活随笔為你收集整理的【我们都爱Paul Hegarty】斯坦福IOS8公开课个人笔记23 多MVC模式Demo的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CANoe-第2个仿真工程-XVehic
- 下一篇: 悦读FM客户端应用源码