天天看點

【我們都愛Paul Hegarty】斯坦福IOS8公開課個人筆記24 popovers彈窗

上幾話中我們詳細了解了幾種segue,我們也了解到了多MVC模式的幾種控制器,比如導航、頁籤和分欄,除了這三種多MVC的模式之外,還有一種popover,它跟其他三種不太一樣。首先先來認識一下popover(彈窗)

【我們都愛Paul Hegarty】斯坦福IOS8公開課個人筆記24 popovers彈窗

你可以看到彈窗會有一個小箭頭指向觸發彈窗的地方:

【我們都愛Paul Hegarty】斯坦福IOS8公開課個人筆記24 popovers彈窗

它像一個白色的三角形。出了彈窗的區域是白色,其他區域都是灰色的,單擊其他區域的唯一功能就是讓彈窗消失。

說popover不同的原因是,它不是一個UIViewController。它通常是presentation controller來出現在螢幕上的。是以popover并不真的需要一個viewcontroller,它的view是這個MVC,它可以純粹依靠presentation controller機制來做到這一點。

雖然它不是自己的viewcontroller,但是它依舊有所有的segue,用法并沒有差別。我們剛才在示例中看到的彈窗是ipad上的效果,在iphone它被modal替代了,IOS自動為你配适的。但是如果你使用代理或者presentation controller,你可以影響這個配适。我們來看幻燈片:

【我們都愛Paul Hegarty】斯坦福IOS8公開課個人筆記24 popovers彈窗

綠色部分和其他segue沒有什麼差別,但是黃色這行我從viewcontroller 過渡到popover得presentationcontroller。當你設定自身為代理時,你能做些什麼呢?

我們看到代理中有兩個代理方法。第一個方法用來配适裝置,預設iphone上全屏展示,如果你把它的傳回值的風格設為none,表示不配适,那麼它的彈窗會和iphone上一樣。

彈窗的另外一個重點是尺寸,你可能需要用一種面向對象的方式,也就是系統調用的方式來詢問MVC合适的尺寸是多少,這隻是控制器的一個屬性,你可以重寫它:

【我們都愛Paul Hegarty】斯坦福IOS8公開課個人筆記24 popovers彈窗

下面來展示一個Demo,讓我們的彈窗顯示浏覽曆史,并且适應内容的尺寸。

我們回到Psychologist這個Demo中,在storyboard中給HappinessVeiwController右上角添加一個按鈕History用來顯示我們點選的按鈕的值,這些值組成整數數組用來表達小人臉的開心程度。注意這個按鈕不要用UIButton,用BarButtonItem,這是個輕量級的按鈕,專門放置在導航欄或者工具欄上。

【我們都愛Paul Hegarty】斯坦福IOS8公開課個人筆記24 popovers彈窗

我們需要讓這個按鈕展示一個新的控制器,是以我們向storyboard中拖一個新的控制器,然後把History按鈕和這個控制器連線,注意segue方式要選擇popover present。

【我們都愛Paul Hegarty】斯坦福IOS8公開課個人筆記24 popovers彈窗

和其他segue一樣,給Identifier命名,我們取名為Show Diagnostic History。

雖然現在控制器是空白的,但是我們已經可以運作了。我們建立一個UIViewController和這個控制器對應起來,取名為TextViewController。

在storyboard中拖一個text view到新控制器中,這個textview可以顯示多行文本,設定它為不可編輯,但是可以選中,修改文本文字為24号。你會在storyboard中看到textview中有很多文字,這些是占位文字,沒有關系我們會在運作的時候重新寫值,這些占位文字是不會顯示的。

【我們都愛Paul Hegarty】斯坦福IOS8公開課個人筆記24 popovers彈窗

我們在代碼中建立多行文本的outlet。

現在該為我們的segue做些準備了。那麼這些準備工作應該在哪裡做呢?顯然我們不應該在HappinessViewController中做,因為這個控制器你可能是從别處拷貝來的,它的設計者希望它是專門用來管理笑臉的,它應該對浏覽曆史一無所知。那麼我們該如何做呢?答案是建立一個新的控制器,然後繼承HappinessViewController,再在其中增加浏覽曆史的功能。

那麼現在回到storyboard中,笑臉的類應該不再是HappinessViewController了,而是我們剛剛修改的新的類。

【我們都愛Paul Hegarty】斯坦福IOS8公開課個人筆記24 popovers彈窗

我們之前設定的各種outlet不會有問題,因為它是子類,繼承了父類的所有東西,包括outlet。這就是控制器的多态性,通常你會有一個可重用的控制器,也許你想給某個特定的控制器中增加功能,這樣你就可以建立它的子類。

我們重寫了屬性happiness,這裡的屬性觀察器和父類中的觀察器不會沖突,程式會先執行父類中happiness的觀察器運作你會發現這個記錄隻能記錄上一次的點選記錄,這是因為我們之前講過的使用segue每次打開的MVC都是新建立的,是以這個浏覽記錄需要存在我們之前講過的NSUserDefaults中。我們把diagnosticHistory改成計算屬性,靠它讀取或者寫入NSDuserDefaults。

新的代碼:

來運作一下看看,我們看到在iphone6上雖然出現了浏覽記錄,但是popover依舊會布滿螢幕,下一個任務是修改它的尺寸了。

【我們都愛Paul Hegarty】斯坦福IOS8公開課個人筆記24 popovers彈窗

首先我們需要讓我們的控制器可以作為自己的彈窗代理,是以:

然後如我們之前講的,在segue中做處理,把原來的語句修改如下:

可以看到popoverPresentationController是在UIViewController中的,隻當這個MVC真的在一個彈窗中的時候它才會傳回,否則傳回nil,然後我們把代理設為自己,這是我們第一次控制系統的代理。之後我們實作控制尺寸的代理方法;

這個代理的傳回表示我們不做任何配适,運作看看:

【我們都愛Paul Hegarty】斯坦福IOS8公開課個人筆記24 popovers彈窗

完整代碼如下:

現在還有最後一個步驟,彈窗的視窗有點大,我們需要它的尺寸适應彈窗中的内容的大小。這次我們需要到TextViewController中去做修改:

我們重寫父類中的這個屬性

然後再次運作:

【我們都愛Paul Hegarty】斯坦福IOS8公開課個人筆記24 popovers彈窗

成功了!