您好,登錄后才能下訂單哦!
Tutorial: Add Data
教程:添加數據
本教程基于你在第二個教程(Tutorial: Storyboards)中建立的工程。你將使用你已經學到的關于使用設計模式、在Foundation中操作、和編寫自定義類來為你的ToDoList app添加動態數據提供支持。
本教程會教你如何完成:
使用常用的Foundation類
創建自定義數據類
實現代理和元數據協議
在視圖控制器之間傳遞數據
在你完成本教程的所有步驟后,你將得到一個看上去如下的app:
Create a Data Class
創建一個數據類
首先,在Xcode中打開已經存在的工程。
現在,你有一個使用故事板得到的接口和導航方案給你的ToDoList app。現在,是時候添加數據存儲和模型對象的行為。
你的app的目的是常見一個待辦事宜項目的列表,所以首先你將創建一個自定義類,XYZToDoItem,來代表個人的待辦事宜項。回憶一下,XYZToDoItem類在Writing a Custom Class中已經討論過了。
創建XYZToDoItem類
1.選擇 File > New > File (或者Command+N).
出現一個對話框提示你為你的新文件選擇模板。
2.在左側,在iOS下選擇Cocoa Touch 。
3.選擇Objective-C類,點擊Next。
4.在Class字段,在XYZ前綴后面鍵入ToDoItem。
5.Choose NSObject from the “Subclass of” pop-up menu. 在 “Subclass of”彈出菜單中選擇NSObject。
如果你完全跟隨教程,在本步驟中Class標題顯示XYZToDoItemViewController。但你在“Subclass of”中選擇NSObject,Xcode知道你制作一個一般的類,并且移除之前被添加的 ViewController文本。
6.點擊 Next.
7.默認保存位置為你的工程目錄。
8.Group選項默認為你的app名,ToDoList。
9.Targets選項默認為你的app被選擇而測試沒有被選擇。
10.點擊 Create.
XYZToDoItem類是簡單的實現。它有名字、創建日期、和項目是否完成等屬性。繼續添加屬性到XYZToDoItem類接口文件。
配置XYZToDoItem類
1.在工程導航器中選擇 XYZToDoItem.h.
2.向接口文件添加如下屬性:
.@interfaceXYZToDoItem : NSObject
.
.
.
.@propertyNSString*itemName;
.
.@propertyBOOLcompleted;
.
.@property(readonly)NSDate*creationDate;
.
.
.
.@end
3.
4.
Checkpoint: 通過選擇 Product > Build (或者Command+B). 構建你的工程。你的使用新類做任何事情,但你構建它可一個給編譯器一個選擇來核實你沒有做任何錯誤的輸入。如果你有,通過閱讀編譯器提供的警告或者錯誤來修改它們,并且回顧所有本教程的指令來確保每件事都如所描述的樣子。
Load the Data
加載數據
現在你有了一個類來讓你創建和存儲個人的列表項的數據。你還需要保持這些項的清單。跟蹤這件事情的最自然的地方是在XYZToDoListViewController類——視圖控制器是負責協調模型和視圖之間的關系,所以他們需要參考模型。
Foundation框架包括一個類,NSMutableArray,它能很好的跟蹤項目的列表。使用可變數組對于用戶添加項目到數組非常重要。在不可變數組中,不允許你在初始化后添加項目。
使用一個數組要同時聲明和創建它。你通過分配和初始化數組來做到這一點:
分配和初始化數組
1.在工程導航器中選擇XYZToDoListViewController.m.
因為項目的數組是你的表視圖控制器的具體實現,你要在.m文件中聲明而不是.h文件中。只是你的私有自定義類。
2.添加如下的屬性到接口類別,Xcode在你自定義的視圖控制器創建。聲明如下所示:
.@interfaceXYZToDoListViewController()
.
.
.
.@propertyNSMutableArray*toDoItems;
.
.
.
.@end
3.
4.
5.在viewDidLoad方法中分配和初始化toDoItems數組:
.-(void)viewDidLoad
.
.{
.
.[superviewDidLoad];
.
.self.toDoItems=[[NSMutableArrayalloc]init];
.
.}
6.
7.
viewDidLoad的實際代碼包括一些額外的行——在XYZListViewController創建的時候被Xcode插入——被添加了注釋。不用管它們。
現在,你有了一個數組,你能往里面添加項。你會在一個單獨的方法,loadInitialData,中做這一點。你將從viewDidLoad中調用。這段代碼運行在自己的方法中是因為它是一個模塊化的任務,你通過方法單獨實現來能提高代碼的可讀性。在真實的app中,這個方法將從某些持久化存儲中加載數據,就像文件一樣。現在,我們的目標是看表視圖控制器如何操作自定義數據項目,所以你將創建一些測試數據來試驗。
創建一個項目到到你創建的數組中:分配和初始化。然后給這個項目起名。這個名字將被顯示在表視圖中。多做幾個這樣的項目。
加載初始化數據
1.添加一個方法,loadInitialData,在 @implementation行的下面。
.-(void)loadInitialData{
.
.}
2.
3.
4.在這個方法中,創建幾個清單項目,然后添加它們到數組中。
.-(void)loadInitialData{
.
.XYZToDoItem*item1=[[XYZToDoItemalloc]init];
.
.item1.itemName=@"Buy milk";
.
.[self.toDoItemsaddObject:item1];
.
.XYZToDoItem*item2=[[XYZToDoItemalloc]init];
.
.item2.itemName=@"Buy eggs";
.
.[self.toDoItemsaddObject:item2];
.
.XYZToDoItem*item3=[[XYZToDoItemalloc]init];
.
.item3.itemName=@"Read a book";
.
.[self.toDoItemsaddObject:item3];
.
.}
5.
6.
7.在viewDidLoad方法中調用loadInitialData。
.-(void)viewDidLoad
.
.{
.
.[superviewDidLoad];
.
.self.toDoItems=[[NSMutableArrayalloc]init];
.
.[selfloadInitialData];
.
.}
8.
9.
Checkpoint: 通過選擇Product > Build來構建你的工程。你會看在loadInitialData方法中看到很多錯誤。關鍵是第一行的錯誤,它應該是說 “Use of undeclared identifier XYZToDoItem.”它的意思是說編譯器在編譯XYZToDoListViewController的時候不知道關于你的XYZToDoItem。編譯器是非常特殊的,它需要被確切的告知要去注意什么。
告訴編譯器注意你自定義的清單項目類
1.在XYZToDoListViewController.m文件的頂部附近找到#import "XYZToDoListViewController.h" 。
2.在他下面添加如下行:
.#import "XYZToDoItem.h"
3.
4.
Checkpoint: 構建你的工程,你將發現沒有錯誤了。
Display the Data
顯示數據
現在,你的視圖有了一個可變數組,它被一些簡單的待辦事宜項目填充。現在你需要在表視圖上顯示這些數據。
你將通過制作表視圖XYZToDoListViewController數據源來做到這一點。為了使用表視圖數據源,需要實現UITableViewDataSource委托。這些你需要實現的方法原來在第二個教程中是被注釋掉得。要有一個功能表需要三個方法。第一個方法numberOfSectionsInTableView:,它告訴表視圖有多少區域需要被顯示。在這個app中,你只需要顯示一個區域在表視圖中,所以這個實現非常簡單。
在你的表中顯示區域
1.在工程導航器中選擇 XYZToDoListViewController.m.
2.如果你注釋了這些方法,現在移除掉注釋。
3.找到區域的實現模板,如下所示:
.-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView
.
.{
.
.#warning Potentially incomplete method implementation.
.
.// Return the number of sections.
.
.return0;
.
.}
4.
5.
你要的是一個區域,所以你移除警告行并且改變返回值從0到1.
6.改變numberOfSectionsInTableView:數據源方法的返回值為單一區域,如下所示:
.-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView
.
.{
.
.// Return the number of sections.
.
.return1;
.
.}
7.
8.
下一個方法,tableView:numberOfRowsInSection:,告訴表視圖在給定的區域中顯示多少行。在你的表中有一個區域,并且每個to-do 項應該在表視圖中有自己的行。這意味著行數應該是在toDoItems數組中的XYZToDoItem對象數。
在你的表中返回行數
1.在工程導航器中選擇 XYZToDoListViewController.m.
2.找到模板實現的部分如下所示:
.-(NSInteger)tableView:(UITableView*)tableViewnumberOfRowsInSection:(NSInteger)section
.
.{
.
.#warning Incomplete method implementation.
.
.// Return the number of rows in the section.
.
.return0;
.
.}
3.
4.
你需要返回你有的清單項目的數目。幸運的是,NSArray有一個方便的方法叫做count,它能返回在數組中醒目的數目,所以行數就是[self.toDoItems count]。
5.改變tableView:numberOfRowsInSection數據源方法來返回適當的行數。
.-(NSInteger)tableView:(UITableView*)tableViewnumberOfRowsInSection:(NSInteger)section
.
.{
.
.// Return the number of rows in the section.
.
.return[self.toDoItemscount];
.
.}
6.
7.
最后一個方法,tableView:cellForRowAtIndexPath:,請求一個表視圖單元來顯示給定的行。到現在為止,你只是用代碼進行工作,但是表單元顯示是你接口文件的一部分。幸運的是,Xcode可以在IB中非常容易的設計自定義表單元。第一個任務是設計你的表單元并且告訴表視圖而并非使用靜態內容,它將動態的使用表單元的屬性。
配置表視圖
1.打開故事板。
2.在大綱視圖中選擇表視圖。
3.在表視圖選中的情況下,在工具區打開屬性檢查器
4.在屬性檢查器中,改變表視圖的Content 屬性,從靜態表單元(Static Cells)到動態原型(Dynamic Prototypes)。
IB讓你的靜態表單元全部配置為原形。原形表單元,顧名思義,是表單元被配置文本樣式、顏色、圖片、或者其他你想要的屬性用來顯示,但它們的數據是在運行的時候由數據源提供。數據源加載每個行的原形表單元并且配置他們在行中的顯示。
加載當前的表單元,數據源需要知道它被叫什么,并且它的名字必須在故事板中配置。
當你設置原形表單元的名稱時,你也配置另外的表單元的選擇樣式屬性,它決定表單元在被用戶選中的時候如何顯示。設置表單元選擇樣式為None,所以表單元的項目將不會在用戶選中的時候高亮顯示。這是你想要的行為,想要你的表單元在用戶在to-do list中點擊項目來標記是否完成——在本教程下面的內容中實現——所呈現的樣子。
配置原形表單元(prototype cell)
1.在表中選擇第一個表視圖單元。
2.在屬性檢查其中,定位標識字段和類型ListPrototypeCell。
3.在屬性檢查其中,定位Selection字段并選擇None。
你也能改變更改原形表單元的字體或者其他屬性。最基本的配置很容易,所以你將保存它。
下一步是告訴你的數據源通過tableView:cellForRowAtIndexPath:如何在給定的行上配置表單元。這個數據源方法通過表視圖調用當它項要顯示給定的行時。如果表視圖只有少數幾個行,那么所有行立即都顯示在屏幕上。但是如果表視圖有很多行但是在同一事件只能顯示其中的某些部分。對于表視圖要求哪些行需要被顯示是非常有效的,這就是tableView:cellForRowAtIndexPath允許表視圖做什么。
對于任何給定的表中的行,在待辦事宜項數組中獲取相應的條目,然后把項的名字設置到表單元的文本標簽上。
在你的表中顯示表單元
1.在工程導航其中選擇XYZToDoListViewController.m.
2.找到tableView:cellForRowAtIndexPath:數據源方法。想如下顯示那樣實現:
.-(UITableViewCell*)tableView:(UITableView*)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPath
.
.{
.
.staticNSString*CellIdentifier=@"Cell";
.
.UITableViewCell*cell=[tableViewdequeueReusableCellWithIdentifier:CellIdentifierforIndexPath:indexPath];
.
.
.
.// Configure the cell...
.
.
.
.returncell;
.
.}
3.
4.
模板執行多個任務。它創建變量來保存表單元的標識,詢問表視圖帶有標識的表單元,在關于設置表單元的地方添加注釋,然后返回表單元。
想要使用這段代碼,你需要在故事板中設置標識符,然后添加代碼來配置表單元。
5.表單元標識符改變為故事板中你的設置。為了避免打字,從故事板中復制并粘貼到實現文件中。表單元標識符線現在看起來如下所示:
.staticNSString*CellIdentifier=@"ListPrototypeCell";
6.
7.
8.在返回語句之前,添加如下代碼:
.XYZToDoItem*toDoItem=[self.toDoItemsobjectAtIndex:indexPath.row];
.
.cell.textLabel.text=toDoItem.itemName;
9.
10.
你的tableView:cellForRowAtIndexPath方法應該如下所示:
.-(UITableViewCell*)tableView:(UITableView*)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPath
.
.{
.
.staticNSString*CellIdentifier=@"ListPrototypeCell";
.
.UITableViewCell*cell=[tableViewdequeueReusableCellWithIdentifier:CellIdentifierforIndexPath:indexPath];
.
.XYZToDoItem*toDoItem=[self.toDoItemsobjectAtIndex:indexPath.row];
.
.cell.textLabel.text=toDoItem.itemName;
.
.returncell;
.
.}
.
Checkpoint:運行你的app。你添加在loadInitialData中的事項列表應該被顯示在表視圖的表單元上。
continue...
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。