用子類搞定不同的設備
因為要判斷我們的程序正運行在哪個設備上,所以,我們的代碼有些混亂了,IF來ELSE去的,記住,將來你花在維護代碼上的時間要比花在寫代碼上的時間多,如果你的項目比較大,且IF語句分布得到處都是,那么可以悲催地告訴你,你將在跟蹤iPad或iPhone的功能上面花更多的時間,更大的精力。
????在下面的建議中,我們不是針對iPad,而是要建立一種用傳統的包裝技巧來提取類、封裝方法的思路和習慣,這樣不但會減少那些個啰哩啰嗦的條件判斷,還能使代碼結構更加清晰。
????例如,一個更加明智的方法就是把你的類分成三個不同的類別,把那些兩個設備共用的代碼放在共享類別中,把iPhone相關的代碼放在iPhone類別中,把iPad相關的代碼放在iPad類別中,在本節結束的時候,我們的源代碼結構將變成下圖這樣:
????首先考慮RootViewController,這其中,我們只修改了表視圖代理的tableView:didSelectRowAtIndexPath:方法的實現,以讓它是適應于不同的設備,現在,我們就從RootViewController類中干掉它,然后創建兩個子類實現它。
????創建一個RootViewController的子類,起名為RootViewController_Pad,頭文件里面幾乎沒啥東西:
????實現起來也很簡單,在這里面我們將針對iPad實現代理方法,如果喜歡偷懶,就從RootViewController.m中把iPad對應的代碼復制、粘貼過來:
????接著,我們用類似的方法針對iPhone創建RootViewController_Phone子類,不用說,該子類的爸爸也是RootViewController類。
????自然,其中代理方法實現的是iPhone功能,我們繼續發揚復制、粘貼的精神,從RootViewContoller.m的tableView:didSelectRowAtIndexPath:方法中摘出iPhone對應的代碼:
????通過子類化RootViewController,我們沒費多大勁就把iPad、iPhone的功能分離開來,從RootViewController.m中刪除tableView:didSelectRowAtIndexPath:方法。如此,超類中包含了所有表視圖的數據源方法,而針對具體設備的功能方法,都被放在了子類中,從而實現了數據與功能的分離。
????不過,事兒還沒有干完,程序還不知道這些子類的存在,我們還要把應用代理切成iPad份和iPhone份,并讓他們分別調用相應的子類。
2.5?????把應用代理分開
?????為了調用上面的子類,我們還要做一些改動,那就是針對不同的平臺創建不同的應用代理,在超類DailyShootAppDegelate中保留這些設備共用的代碼,其頭文件如下:
????在實現文件中,干掉那些判斷目標設備的代碼,稍后,我們將添加子類的初始視圖,DailyShootAppDegelate.m的內容如下:
????創建一個DailyShootDegelate_Phone類,其頭文件內容如下:
????對于iPhone,我們要添加導航控制器的視圖,一添加進來它就會在最上面顯示,然后,還要調用超類的application:didFinishLaunchingWithOptions方法:
????類似的,再創建DailyShootAppDegelate_Pad類,其頭文件內容如下:
????在這個子類中,需要添加一個分割視圖控制器(UISplitViewController)屬性,在實現中,我們將把分割視圖控制器的視圖作為頂部視圖添加進來,并在dealloc方法中釋放資源:
????到現在,工作基本完成,不過先別著急,我們還需要對nib文件做少許修改。在IB中打開MainWindow.nib,用實體查看器把DailyShootAppDegelate對象的類型改為DailyShootAppDegelate_Phone,把RootViewController對象的類型改為RootViewController_Phone。
????類似的,在IB中打開MainWindow_iPad.nib,用實體查看器把DailyShootAppDegelate對象的類型改為DailyShootAppDegelage_Pad,把RootViewController對象的類型改為RootViewController_Pad。
????保存所有成果,生成并運行,所有的東西將如以往那般運行。
????為了替換兩個簡單的if語句我們就做了這么多事情,是不是感覺很磨嘰?但是,凡事要朝好的方向想,你的代碼是不是變得清晰靈活了?其實,你也許感覺做這些修改也沒有費多少時間,但是,這么做確實很重要。
2.6?????在詳細視圖中添加一個工具條
下一步,讓我們在iPad中被AssignmentViewController管理的詳細視圖的頂部添加一個工具條,豎著使用iPad時,為了隱藏和顯示導航視圖,我們的確需要一個工具欄放置“導航”按鈕;即使在橫屏下,留著它也挺好,因為,有時候隱藏掉導航視圖會使界面更清晰。iPhone版本的界面已經有個導航條,所以不用理會它。
我們要創建一個iPad版的AssignmentViewController,選擇“iPad組”,創建新文件,該文件是UIViewController的子類,記著選中“針對iPad”、“創建XIB”兩個復選框,且將新類命名為AssignmentViewController_Pad。
????給AssignmentViewController_Pad類添加名為toolbar的公共屬性,其類型為UIToolbar,把超類從通用的UIViewController改為AssignmentViewController。
????打開AssignmentViewController_Pad nib,在視圖的頂部放一個UIToolbar,剩下的部分用UIWebView填充,把工具條上的默認按鈕干掉,待會我們創建自己的按鈕。在UIWebView對象的屬性查看器中,把“Scales Pages”的值設置為“Fit”,從“Files’Owner”中把兩個外部接口與這些元素相連,保存。
????現在,在AssignmentViewController_Pad類的實現文件中就沒有多少事情要做了:
????下面,我們要對MainWindow_iPad.nib做一些調整,用實體查看器把AssignmentViewController對象的類型改為AssignmentViewController_Pad,接著,還要用屬性查看器把NIB名稱改為AssignmentViewController_Pad,別忘了保存。
????好了,運行運行,看看工具條是不是出來了,下面我們將在分割視圖(橫屏)和懸浮窗體(豎屏)中使用工具條。