[MAC OS]第一次接觸MAC OS開發

 原文:http://www.raywenderlich.com/17811/how-to-make-a-simple-mac-app-on-os-x-10-7-tutorial-part-13

     原創譯文,轉載註明出處:http://blog.csdn.net/mamong/article/details/8458224



      本教程由iOS Tutorial Team成員Ernesto García發佈,他是一位Mac和iOS開發者,CocoaWithChurros.的創始人。


      現在是iOS開發者的好時候,你不僅可以在iPhone和iPad應用商店裏發佈你的應用,而且你還可以使用這些基本技能成爲一個Mac開發者,因爲它們兩者的開發是相當接近的。

      假若你是一個iOS開發者,對學習成爲一個Mac開發者的基礎充滿好奇,想了解如何從iOS應用遷移到桌面上來,那麼這個教程適合你。

      在本教程裏,你將建立你的第一個Mac應用,也就是先前我們在教程《How To Create A Simple iPhone App 》中建立的iOS應用的Mac版本。

      如果你已經跟着那個教程做過一遍,那麼你將對這個裏許多步驟相當熟悉,同時,你也會看到iOS和Mac編程之間的差異。

      假如你沒有看過那個教程,不要着急,這對於閱讀和理解本教程不是必要的,我們會指導你一步步走下去。

      創建這個應用時,你將會學到如下內容:

  • 如何在Xcode裏創建一個Mac應用
  • 學習Mac應用的基本結構
  • 學習OSX和iOS之間的差異
  • 如何使用Table Views,包括增刪行
  • 如何使用text field,button和image view
  • 如何從你的硬盤裏選擇一張圖片,或者用你的電腦攝像頭拍攝一張照片
  • 如何處理window resizing 
      

      本教程適合Mac初級開發者,假定你熟悉objective-c編程和Xcode。爲了跟隨本教程,建議有iOS編程的知識,但這不是硬性要求。

      在本系列分爲三部分。在第一部分,我們將涉及到如何下載一張昆蟲名錄model,並且將它們顯示在Table view裏。(跳到第二部分或者第三部分


開始

         創建一個Mac項目和創建一個iOS項目是非常相似的,仍然使用Xcode,但是使用不同的模版。前往Xcode菜單“File->New Project",在跳出的窗口裏選擇“Mac OS X”區域裏的“Application”,然後點擊“Next”。

       在下一頁,你將輸入這個應用的信息。在“Product Name”裏輸入“ScaryBugsMac”,選擇一個獨一無二的“Company Identifier”,蘋果建議使用域名的倒序形式。將剩餘的文本框留空。

       最後,確保只有“Use Automatic Reference Counting”被選中,而其他的選擇框沒有被選中。當你完成這一切之後,選擇“Next”。


         現在Xcode會詢問你保存項目的路徑。選擇你電腦裏的一個文件夾,然後點擊“Create”.

         項目已經建立,現在有了一個單個窗口的簡單Mac應用。我們來看看它是啥樣子的。找到“Run”按鈕,它應該在Xcode頂部工具欄中的左邊。點擊它,xcode就會編譯這個應用。當Xcode編譯完後,你將會看到應用的主窗口。

           這表明了三點:首先,說明你選擇了正確的模版,它工作了!其次,說明這是一個不錯的起點。第三,說明這和iOS編程有些非常大,而且顯而易見的差別:

  • 窗口不必像iPhone或者iOS那樣擁有一個鋪滿屏幕的固定尺寸,它是完全可以改變尺寸的
  • Mac應用可以擁有不止一個窗口,而且你還可以最小化他們等等  

           現在我們來對這個窗口進行點改變,讓它顯示一些蟲子的信息。正如在iOS裏一樣,第一件要做的事情就是建一個View Controller。在這個view裏,你將定義主程序的用戶界面。

           建立一個View Controller,前往菜單欄“File\New\File…”,在彈出的窗口裏,選擇“OS X\Cocoa\Objective-C class”,點擊“Next”。

        將這個類命名爲“MasterViewController”,在“Subclass of”中輸入“NSViewController”。確保“With XIB for user Interface”被選中,點擊“Next”.

      在彈出的最後一個窗口再次裏選擇“Create”。現在一個新的view Controller已經建立。在你的項目導航器應該顯示類似如下:

        建好view controller後,該是放些UI控件在view上面。在項目導航器裏點擊“MasterViewController.xib”,它會將你剛纔建立的View controller的可視化表現形式呈現給你。

        Interface Builder讓你以可視化的方式去創建用戶界面。你僅僅需要拖曳一個組建到你的View,根據應用的需要,將其放在合適的位置,調整它的大小。

        第一個想法,你的應用需要做的事情是顯示一個蟲子的列表。爲此,你需要一個Table View。在OSX裏,這個控件叫NSTableView(和iOS裏的UITableView類似)。

        如果你熟悉iOS編程,你也許能夠發現這裏的一個模式。許多在UIKit中的用戶界面相關的類都是從OSX AppKit中遷移過去的。因此,它們中的一些僅僅是從Mac中的前綴NS變成了iOS中的UI。

       因此,根據經驗,如果你好奇Mac中是否存在一些你知道的,喜歡的iOS控件,你可以試着找找這些以NS爲前綴的類。你會驚訝你找到了這麼多---NSScrollView, NSLabel, NSButton,還有更多。注意在某些情況下,這些控件也許和iOS裏的變體有些不同。

      用戶界面控件位於屏幕右邊的底部,確保選中第三個標籤(UI控件的標籤),找到NSTableView(你可以拖動控件列表裏的滾動條來找到它,也可以在控件盤的搜索欄裏輸入NSTableView)。

           從控件盤裏拖曳一個table view到view上,將它放在左上角附近。不要擔心table的尺寸,等下處理這個問題。

       你現在有了一個table在上面的view,但是你還沒將這個view的控制器添加到主窗口,因此它不會顯示出來。你需要在Application Delegate完成這個。在項目導航器裏選擇“AppDelegate.m”。

       爲了使用一個新的view controller,必須告訴Application Delegate它的存在,因此你需要做的第一件事情是導入view controller的頭文件。添加如下內容到“AppDelegate.m”:在“#import “AppDelegate.h””下一行,”@implementation AppDelegate”之前,添加

  1. #include "MasterViewController.h"  

      現在你要爲這個view controller創建一個property/instance。

      添加如下代碼到剛纔那行代碼的下面,“@implementation AppDelegate”之前。注意根據新的auto-synthesize特性,properties不再需要被synthesize,所以你就這樣設置:

  1. @interface  AppDelegate()  
  2. @property (nonatomic,strong) IBOutlet MasterViewController *masterViewController;  
  3. @end  

     現在Application Delegate有了一個MasterViewController property,但是view仍然不會被顯示在應用的屏幕上。爲了創建一個新的view,你需要實例化這個變量。然後,你需要將這個新創建的view添加到應用程序的主窗口。

    這些要在應用程序啓動的時候完成。Application delegate有一個applicationDidFinishLaunching方法,在應用程序啓動的時候會被操作系統調用。那就是你添加所有初始化代碼的地方,這也意味着這只是在程序啓動的時候被執行一次。

    假如你熟悉iOS編程,這個方法和iOS裏的方法– (BOOL)application:didFinishLaunchingWithOptions:launchOptions是等效的。

    讓我們來創建view controller,並且將它添加到主窗口。在applicationDidFinishLaunching:中插入如下代碼:

  1. // 1. Create the master View Controller  
  2. self.masterViewController = [[MasterViewController alloc] initWithNibName:@"MasterViewController" bundle:nil];  
  3.    
  4. // 2. Add the view controller to the Window's content view  
  5. [self.window.contentView addSubview:self.masterViewController.view];  
  6. self.masterViewController.view.frame = ((NSView*)self.window.contentView).bounds;  

    以上代碼有兩個作用。首先,使initWithNibName:方法從nib文件裏創建一個新MasterViewController。一旦它建立了,就被添加到主窗口。OSX中的窗口(NSWindow類)被創建的時候總是包含一個默認的view,叫做contentView,它自動根據窗口的尺寸調整自身大小。假如你要將自己的view添加到窗口上,你總是需要使用sddSubview方法將它添加到contentView上面。

     最後一行設置你的view的大小以匹配窗口的初始尺寸。再次對比iOS編程,這有些不同。在iOS裏,你會設置窗口的根視圖控制器(rootViewController),但是根視圖控制器在OSX裏不存在,因此你需要將你的view添加到窗口的內容視圖(content View)裏。

     假如現在你點擊“Run”,你將看到主窗口顯示了你那個帶有table view的視圖。非常好---我們來乾點別的。

發怵小蟲數據模型:組織

      到目前爲止,你已經有了一個包含一個漂亮的table view的窗口。但是事實上它也沒做什麼。你想讓它顯示些令人驚慌的蟲子的信息----但是等一下,你還沒有任何要展示的數據!

     沒有數據,這真的讓我很難過。因此,在接下來的步驟中,你將爲應用建立一個數據模型,但是在這之前,教你一個組織項目導航器裏文件的方法。

注意:這是一個可選的部分,展示如何組織文件到組裏。假如你看過《How To Create A Simple iPhone App on iOS 5 Tutorial》或者已經知道怎麼做了,可以跳過這部分。

      這是你當前在Xcode項目導航器裏文件結構:

       默認模板以應用的名字創建了一個組,還有一個存放支持文件(plist, resources等)。當你的項目變得越來越大,你將和很多文件打交道,查找你要的文件變得越來越困難。

      在這部分,我們將教你一個組織你的文件的方法。這個組織方式因人而異,因此你可以根據自己的喜好來改變它。

      首先,你需要創建一個組來存放用戶界面文件,我們將命名它爲“GUI”。創建這樣一個組,你可以Ctrl+Click或者右鍵“ScaryBugsMac”組。在彈出的菜單中選擇“New Group”。這個被創建的組自動被選中,你可以輸入一個新的名字“GUI”。

     現在,拖曳用戶界面文件到那個組(AppDelegate.h/.m MasterViewController.h/.m/.xib andMainMenu.xib)。在拖曳後,你的項目導航器看起來應該類似這樣:

        現在創建“Scary”的第二個組,命名爲“Model”。在接下去裏,我們將爲你的應用創建一些數據模型文件,你需要將這些文件添加到這個組。到此,你的導航器應該類似這樣:


         在我們開始之前,讓我們談論下如何組織這些東西:

  • ScaryBugData:包含蟲子的名字和排名
  • ScaryBugDoc:包含原尺寸的圖片,縮略圖,ScaryBugData

        我們這樣設置的理由是爲了這個教程的接下去部分更容易些,在那兒我們將開始保存我們的數據到硬盤。


發怵小蟲數據模型:實現

Note: If you’ve followed the How To Create A Simple iPhone App on iOS 5 Tutorial, you will find that this section is (almost) identical to that. One of the good things about Mac/iOS programming is that they share most of the SDK, obviously, except the UI classes and some OS specific parts.

So, when you’re creating the model and classes that don’t need user interface, you will find that most of your code will likely just work on Mac, or it will work with some minor changes.

For instance, in this case, changing the ScaryBug model classes from iOS to Mac only required one change. UIImage does not exist in OSX, so you just needed to change it to OSX’s image class, NSImage. And that was it!

       讓我們來創建這個模型。我們開始創建這個ScaryBugData文件。

       在項目導航器裏,Control-Click你剛纔創建的模型組,在菜單裏點擊“New File...”,選擇“OS X\Cocoa\Objective-C class”模版,然後點擊“Next”。

       命名這個類爲“ScaryBugData”,將它的父類設置爲“NSObject”,點擊“Next”。

        在最後彈出來的窗口裏再次點擊“Create”。假如一切順利的話,你的項目導航器應該類似這樣子:

      接下去我們爲“ScaryBugData”添加些源代碼。

      首先,選中“ScaryBugData.h”文件,用下面的代碼替換它裏面所有的內容:

  1. #import <Foundation/Foundation.h>  
  2.    
  3. @interface ScaryBugData : NSObject  
  4.    
  5. @property (strong) NSString *title;  
  6. @property (assign) float rating;  
  7.    
  8. - (id)initWithTitle:(NSString*)title rating:(float)rating;  
  9.    
  10. @end  

      這是非常簡單的東西----我們僅僅聲明瞭一個擁有兩個property的對象,兩個property分別是:一個表示蟲子名字的字符串,一個表示你對它令人發怵程度評價的浮點數。這時你要用到下面兩個property屬性:

  • strong:表示指定運行時應該自動保持對一個對象的強引用。這只是一個花哨的說法,大意就是隻要存在一個指向對象的引用,ARC運行時會將這個對象駐留在內存裏,當沒有引用剩下的時候,就銷燬它。更多內容見教程《Beginning ARC in iOS 5
  • assign:表示直接設置property,沒有涉及內存管理。你經常用它來設置float之類的基本類型(非對象)。

       你還爲這個類定義了一個初始化方法,因此你可以在創建一個蟲子的時候設置它的名字和發怵等級。轉到“ScaryBugData.m”,用下面的代碼替換:

  1. #import "ScaryBugData.h"  
  2.    
  3. @implementation ScaryBugData  
  4.    
  5. - (id)initWithTitle:(NSString*)title rating:(float)rating {  
  6.     if ((self = [super init])) {  
  7.         self.title = title;  
  8.         self.rating = rating;  
  9.     }  
  10.     return self;  
  11. }  
  12.    
  13. @end  

       這也相當簡單。你創建了一個初始化方法,使用傳入的參數給你的實例變量賦值。注意到這裏沒必要使用dealloc,因爲你用了ARC;也沒必要synthesize你的property,因爲auto-synthesize特性。

        好了,“ScaryBugData”就那麼多。現在根據前面的步驟創建另外一個NSObject的子類,這次命名爲“ScaryBugDoc”。使用下面的代碼替換”ScaryBugDoc.h”的內容:

  1. #import <Foundation/Foundation.h>  
  2.    
  3. @class ScaryBugData;  
  4.    
  5. @interface ScaryBugDoc : NSObject  
  6.    
  7. @property (strong) ScaryBugData *data;  
  8. @property (strong) NSImage *thumbImage;  
  9. @property (strong) NSImage *fullImage;  
  10.    
  11. - (id)initWithTitle:(NSString*)title rating:(float)rating thumbImage:(NSImage *)thumbImage fullImage:(NSImage *)fullImage;  
  12.    
  13. @end  

        這裏沒有什麼需要特別注意到地方------僅僅創建了一些實例變量/property和一個初始化方法。用下面的代碼替換“ScaryBugDoc.m”:

  1. #import "ScaryBugDoc.h"  
  2. #import "ScaryBugData.h"  
  3.    
  4. @implementation ScaryBugDoc  
  5.    
  6. - (id)initWithTitle:(NSString*)title rating:(float)rating thumbImage:(NSImage *)thumbImage fullImage:(NSImage *)fullImage {  
  7.     if ((self = [super init])) {  
  8.         self.data = [[ScaryBugData alloc] initWithTitle:title rating:rating];  
  9.         self.thumbImage = thumbImage;  
  10.         self.fullImage = fullImage;  
  11.     }  
  12.     return self;  
  13. }  
  14.    
  15. @end  

        就這樣,你的數據模型就完成了!

        現在你編譯並且運行你的應用來檢查是否一切運行正常。按照預期你應當看到一個空的列表,因爲你還沒有將數據模型和UI相鏈接。

        現在你有了數據模型,但是你還沒有任何數據。你需要創建一個“ ScaryBugDocs”列表,並且你將它存在一個NSMutableArray裏。我們將在MasterViewController裏添加一個property來跟蹤你的蟲子列表。

       選擇“MasterViewController.h”,將下面這行代碼放在@interface和 @end lines之間:

  1. @property (strong) NSMutableArray *bugs;  

     這將是我們用來跟蹤蟲子列表的實例變量/property。接下去讓我們來將它勾起來。


發怵小蟲圖片和樣品數據


         現在,MasterViewController類已經做好準備來接受一個蟲子列表。但是話說回來,你還是沒有任何數據。

         在添加數據之前,我們需要一些令人發怵的從子的圖片!你可以從教程《How To Create A Simple iPhone App on iOS 5 Tutorial》中下載這些圖片或者去網上找些你喜歡的令人發怵的蟲子的圖片:]。

         下載好這些文件或者得到了你自己喜歡的文件,將它們拖到你的項目導航器的文件結構樹的根位置。當彈窗出現時,確保選中了“Copy items into destination group’s folder (if needed)”,然後點擊“Add”。

          假如你想把這些東西保存得更加合理,你可以爲這些蟲子圖片創建一個子組,然後拖曳這些文件到裏面。

        現在,讓我們來創建樣品數據。選中“AppDelegate.m”,將下面一行添加到文件頂部,#include “MasterViewController.h”的下面:

  1. #import "ScaryBugDoc.h"  

        爲了創建傳給MainViewController的樣本數據,在applicationDidFinishLaunching方法裏做些變動,修改在“[self.window.contentView addSubview:self.masterViewController.view];”這一行上面進行:

  1. // Setup sample data  
  2. ScaryBugDoc *bug1 = [[ScaryBugDoc alloc] initWithTitle:@"Potato Bug" rating:4 thumbImage:[NSImage imageNamed:@"potatoBugThumb.jpg"] fullImage:[NSImage imageNamed:@"potatoBug.jpg"]];  
  3. ScaryBugDoc *bug2 = [[ScaryBugDoc alloc] initWithTitle:@"House Centipede" rating:3 thumbImage:[NSImage imageNamed:@"centipedeThumb.jpg"] fullImage:[NSImage imageNamed:@"centipede.jpg"]];  
  4. ScaryBugDoc *bug3 = [[ScaryBugDoc alloc] initWithTitle:@"Wolf Spider" rating:5 thumbImage:[NSImage imageNamed:@"wolfSpiderThumb.jpg"] fullImage:[NSImage imageNamed:@"wolfSpider.jpg"]];  
  5. ScaryBugDoc *bug4 = [[ScaryBugDoc alloc] initWithTitle:@"Lady Bug" rating:1 thumbImage:[NSImage imageNamed:@"ladybugThumb.jpg"] fullImage:[NSImage imageNamed:@"ladybug.jpg"]];  
  6. NSMutableArray *bugs = [NSMutableArray arrayWithObjects:bug1, bug2, bug3, bug4, nil];  
  7.    
  8. self.masterViewController.bugs = bugs;  


      這裏你使用了the ScaryBugDoc的初始化方法來創建四個蟲子樣本,給每一個傳入名字,評級和圖片信息。將這四個樣本放入NSMutableArray,然後通過bugs property傳給masterViewController。

      你終於有了些數據!編譯運行你的程序,確保所有都正常工作,沒有發生任何錯誤。但是我們仍然在用戶界面看不到任何東西,但是這次view controller已經有它需要的數據了,我們可以着手用戶界面上的工作,最終顯示出你的發怵小蟲子列表。


一個不同的蟲子列表

      爲了顯示蟲子列表,你需要設置table view從你的模型中得到蟲子列表。

      在OSX中,table view控件叫做NSTableView,它和UITableView類似之處是它也能顯示成列的數據,但是不同之處是NSTableView每一行可以顯示多列。

      和UITableView一樣,NSTableView每一行都有些cell。然而它們的功能最近有了些改變:

  • OSX10.7Lion之前:table view的cells是一個繼承自NSCell類的特別的類。它們不是基於view的,處理draw和鼠標事件是程序員的職責。
  • OSX10.7以後:有了一類新的table view---基於view的table view。這個table view工作的方式非常類似UITableView。它的cells是一類特別的view(NSTableViewCell),使用這樣的view就非常類似在iOS的用法,這樣就簡單多了。

      在本教程裏,你將使用這樣新的基於view的Table view。我們將涉及到基礎部分,但是假如你想學習更多關於NSTableView的,你可以閱讀《Table View Programming Guide》,在這裏面非常好的解釋了table view如何工作的。

      在設置用戶界面之前,你需要在nib文件裏做一個小小的改變,關閉“Auto Layout”。Auto Layout是OSX10.7中新介紹的特性,意在根據程序員訂下的一些規則,自動處理用戶界面上的控件尺寸改變。Auto Layout超出了本教程的範圍,使解釋一些東西變得比較困難,因此你要先關掉它。在Auto Layout關掉之後,autoresizing就可以配置,並且和在iOS 5項目裏具有相同的運行結果。

      選擇MasterViewController.xib。Interface Builder界面打開,在窗口右側的實用工具盤(Utilities panel)裏,確保選中“File Inspector”(它位於左側標籤欄第一個)。在“File Inspector”標籤中取消選中“Use Auto Layout”。

       做完這些,你需要對main window做同樣的操作。選中“MainMenu.xib”裏的window,同樣取消auto layout。

       現在我們已經準備好了。讓我們開始設置你的table view,這樣它就可以顯示一個ScaryBugDocs列表了。在項目導航器裏選擇“MasterViewController.xib”,在Interface Builder的view裏選中你的table view。注意table view是內嵌在一個scroll view裏的。因此你第一次點擊它,你會選中scroll view。

       爲了選中table view,再次點擊它(不是雙擊,第二次點擊在前一次後面一小會兒)。另外一個選中它的辦法是直接點擊右側對象盤(objects panel)裏的table view。

       選中之後緊接着要做的事情是改變table view爲“view based”,因爲Interface builder默認創建的是“cells based”。

       爲了改變它,確保你選中了屏幕右側的特性盤(properties panel)的“Attributes Inspector Tab”。然後在“Content Mode” 中選擇 “View Based”。你的列表不需要很多列,因此改變“Columns property”爲1。

       爲了定製這個列表,選中特性“Alternating Rows”,這樣就會以藍白交替的方式繪製行。不要選中“Headers”特性,這樣就移除了表頭,因爲在本教程裏我們不需要。

       在移除多餘的列之後,剩下的列比table view窄,爲了調整它的大小,點擊“table column”(點擊三次table view或者使用右側的對象盤),調整這一列的大小以鋪滿整個table的寬度。

       接下來的步驟是配置table view使用的cell view。你的列表需要顯示蟲子的圖片和名字。你需要包含一個image和一個text  field的cell來顯示信息。Interface Builder有一個預配置的包含一個image和text field的NSTablecellView,因此你要用那個。在窗口底部左側的“Object library panel”裏有一個“Image & Text Table Cell View”,將它拖到你的table view裏。

         做完這些之後,你的table裏現在有兩種不同的cell。選中原來的cell(沒有齒輪圖標的cell),按下delete鍵來刪除。

         最後一步是改變cell的高度,因爲它對於顯示蟲子的圖片來說是在太小了。你應當將其的高度設置爲32.選中cell,然後在Xcode窗口的右側特性盤(Utilities panel)裏打開大小檢查器“Size Inspector”標籤。你可以在高度配置盤(Height panel)裏設置cell的高度爲32.

         另外一種辦法是拖動cell底部的邊框直到你得到了想要的高度。這之後,image和text field有了些偏移,爲了修復這個,選中它們,然後拖到cell的中間。你可以改變image view的大小,改變text field的字體來滿足你的需要。現在設計的table view應該像這樣:


       現在你要設置列標識(column identifier),這是一個你給table view的每一列取的名字,因此當你想要執行一些操作或者你收到了一些來自某列的通知,你就可以識別出是哪一列。

       這並非本教程嚴格需要的,因爲你只有一列,但是這樣做是一個不錯的練習,當在其他項目裏需要建立一個多列的table view的時候,你就不會有什麼問題了。選中table column(記住你要在table view中點擊三次或者使用左邊的Objects panel)。在這之後,打開Utilities panel裏的“Identity Inspector”標籤。在那裏Identifier由“Automatic”變爲 “BugColumn”。

         這就是table UI的配置。現在你需要連接table view和MasterViewController,這樣它們就能知道彼此的存在了。

         和iOS一樣,table view使用兩個property來讓table和它的controller來通信:數據源(datasource)和委託(delegate)。

         基本上,數據源是一種告訴table view它要顯示什麼數據的類。委託也是一個類,它控制數據如何顯示,並且從table view接收通知,例如當一個cell被選中。

         委託和數據源通常是(但是現在是總是)同一個controller。這本例子中,數據源和委託都是你的MasterViewController類。這可以通過編程來實現,但是在本教程中,你將要在Interface Builder來實現這種關聯。

         選中你的table view,在“Utilities Panel”裏選擇連接檢查器(Connections Inspector,有個指向右側箭頭圖標的那個)。在Outlets區域,你會看到delegate和datasource。(原文此處有錯誤“you will see the delegate in the datasource”,翻譯版本已修復)先來連接delegate。點擊delegate右側的小圓圈,然後拖到左側PlaceHolders panel的File’s Owner上(也就是MasterViewController)。

         正如你被告知的那樣,table view的delegate是MasterViewController。當你實例化你應用裏的視圖控制器,將爲我們自動創建這種連接。現在對datasource outlet重複這個過程。做完這些後,你一定可以看到兩條指向File’s Owner的連接,像這樣:

        就這樣,現在我們要往你的view controller裏添些必要的代碼來顯示你的蟲子列表。選擇MasterViewController.m,將下面的添加到文件的頂部,#import “MasterViewController.h”這一行下邊:

  1. #import "ScaryBugDoc.h"  
  2. #import "ScaryBugData.h"  

           然後複製下面的代碼到文件的底部,@end之前:

  1. - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {  
  2.    
  3.     // Get a new ViewCell   
  4.     NSTableCellView *cellView = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];  
  5.    
  6.     // Since this is a single-column table view, this would not be necessary.  
  7.     // But it's a good practice to do it in order by remember it when a table is multicolumn.  
  8.     if( [tableColumn.identifier isEqualToString:@"BugColumn"] )  
  9.     {  
  10.         ScaryBugDoc *bugDoc = [self.bugs objectAtIndex:row];  
  11.         cellView.imageView.image = bugDoc.thumbImage;  
  12.         cellView.textField.stringValue = bugDoc.data.title;  
  13.         return cellView;  
  14.     }  
  15.     return cellView;  
  16. }  
  17.    
  18.    
  19. - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {  
  20.     return [self.bugs count];  
  21. }  

         好了,來看看我們在這兒做了些什麼。爲了在table view裏顯示數據,你需要實現至少兩個方法。一個是數據源的numberOfRowsInTableView:方法,這個方法由操作系統調用來詢問數據源(在本例中是MasterViewController)“我該要顯示多少行?”你只需要用數組裏的蟲子列表迴應。

         使用這個方法,table view就知道了要顯示多少行,但是仍然不知道顯示在每列裏的哪個cell,也不知道那些cell應該有什麼信息。

         這些由tableView:viewForTableColumn:row方法來完成。這個方法由操作系統爲table view裏的每行和每列調用。在方法裏,你需要創建合適的cell,並且用你需要的信息填充它。假如你有iOS編程經驗,你會發現這和UITableView的工作方式非常類似。numberOfRowsInTableView:非常類似iOS中的numberOfRowsInSection:,同樣地,viewForTableColumn:row也和iOS中的cellForRowAtIndexPath:類似。不同之處在於在iOS裏你需要根據它的section 和row來設置cell,而在OSX裏,你根據row和column來設置cell。cellForRowAtIndexPath:是一個非常重要的方法,因此讓我們來仔細地看一下這個方法:

  1. - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {  
  2.    
  3.     // Get a new ViewCell   
  4.     NSTableCellView *cellView = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];  
  5.    
  6.     // Since this is a single-column table view, this would not be necessary.  
  7.     // But it's a good practice to do it in order by remember it when a table is multicolumn.  
  8.     if( [tableColumn.identifier isEqualToString:@"BugColumn"] )  
  9.     {  
  10.         ScaryBugDoc *bugDoc = [self.bugs objectAtIndex:row];  
  11.         cellView.imageView.image = bugDoc.thumbImage;  
  12.         cellView.textField.stringValue = bugDoc.data.title;  
  13.         return cellView;  
  14.     }  
  15.     return cellView;  
  16. }  

        首先你通過調用makeViewWithIdentifier:來得到一個cellView。這個方法將會創建(或者再利用)一個合適的基於identifier的單列的cell(就是你在Interface Builder裏設置的)。當你擁有這樣一個cell之後,就該用信息來填充它。我們依靠列來差異地進行這一步。這就是爲什麼我們要檢查identifier是否爲“BugColumn”。假如列的identifier是“BugColumn”,就根據ScaryBugDoc裏的信息設置image和text field。在本例子裏只有一種列,因此這個檢查不是必須的。然而知道如何處理多列的情況將對你非常有幫助,因爲在你自己的應用裏,你可能需要那些。

         這就是所有你需要顯示在table view裏的信息。這僅僅是一個在Interface Builder中定義properties和connections,在你的view controller裏實現兩個方法的問題。

          是時候編譯運行這個程序了。假如一切正常的話,你應該可以看到一個顯示Scary Bugs列表的table view!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章