Start Developing iOS Apps Today系列(十一)

Start Developing iOS Apps Today系列之應用程序

11、教程:添加數據

      本教程以第二個教程(「教程:串聯圖」)中建立的項目爲基礎。您將用到從使用設計模式、使用 Foundation 以及編寫自定類中學到的知識,在 ToDoList 應用程序中添加對動態數據的支持。 html

      本教程講述瞭如下操做: ios

  • 使用常見的 Foundation 類 設計模式

  • 建立自定數據類 api

  • 實現委託和數據源協議 數組

  • 在視圖控制器之間傳遞數據 app

      完成本教程中的全部步驟後,您的應用程序外觀大體是這樣的: 框架

image: ../Art/ios_simulator_add_new_item_2x.png
image: ../Art/ios_simulator_full_list_checked_2x.png

建立數據類

      如今就開始吧,請在 Xcode 中打開您的現有項目。 編輯器

      目前,使用串聯圖的 ToDoList 應用程序有一個界面和一個導航方案。如今,是時候使用模型對象來添加數據儲存和行爲了。 ide

      應用程序的目標在於建立一個待辦事項列表,所以首先您將建立一個自定類XYZToDoItem來表示單個待辦事項。您應該記得,XYZToDoItem類已經在編寫自定類中討論過。 模塊化

建立 XYZToDoItem 類

  1. 選取「File」>「New」>「File」(或按下 Command-N)。

    這時將會出現一個對話框,提示您爲新文件選取模板。

  2. 從左側的 iOS 下方選擇「Cocoa Touch」。

  3. 選擇「Objective-C Class」,並點按「Next」。

  4. 在「Class」欄中,在XYZ前綴後鍵入ToDoItem。

  5. 從「Subclass of」彈出式菜單中選取「NSObject」。

  6. 若是您徹底按照本教程操做,那麼在這個步驟以前,「Class」標題多是XYZToDoItemViewController。選取 NSObject 做爲「Subclass of」後,Xcode 會知道您建立了一個正常的自定類,並移除了它先前添加的ViewController文本。

  7. 點按「Next」。

  8. 存儲位置默認爲您的項目目錄。此處無需更改。

  9. 「Group」選項默認爲您的應用程序名稱「ToDoList」。此處無需更改。

  10. 「Targets」部分默認選定您的應用程序,未選定應用程序的測試。好極了,這些都無需更改。

  11. 點按「Create」。

      XYZToDoItem類很容易實現。它具備項目名稱、建立日期,以及該項目是否已完成等屬性。繼續將這些屬性添加到XYZToDoItem類接口。

配置 XYZToDoItem 類

  1. 在項目導航器中,選擇XYZToDoItem.h。

  2. 將如下屬性添加到該接口,使聲明以下所示:

    1. @interface XYZToDoItem : NSObject

    2. @property NSString *itemName;
    3. @property BOOL completed;
    4. @property (readonly) NSDate *creationDate;

    5. @end

      檢查點:經過選取「Product」>「Build」(或按下 Command-B)來生成項目。儘管該新類還沒有實現任何功能,可是生成它有助於編譯器驗證任何拼寫錯誤。若是發現錯誤,請及時修正:通讀編輯器提供的警 告或錯誤,而後回顧本教程中的說明,確保全部內容與此處的描述相符。

載入數據

      您如今有一個類,能夠用它做爲基礎來爲單個列表項目建立並儲存數據。您還須要保留一個項目列表。在XYZToDoListViewController類中跟蹤此內容較爲合適,視圖控制器負責協調模型和視圖,因此須要對模型進行引用。

      Foundation 框架有一個NSMutableArray類,很適合跟蹤項目列表。此處必須使用可變數組,這樣用戶就能夠將項目添加到數組。由於不可變數組NSArray在其初始化後將不容許添加項目。

      要使用數組,您須要聲明並建立它。能夠經過分配並初始化數組來完成。

要分配並初始化數組

  1. 在項目導航器中,選擇XYZToDoListViewController.m。

    因爲項目數組是表格視圖控制器的實現細節,因此應該在 .m 文件中進行聲明,而不是 .h 文件。此操做可以讓項目數組成爲您自定類的私有數組。

  2. 將如下屬性添加到接口類別中,它是由 Xcode 在您的自定表格視圖控制器類中建立的。聲明應該是這樣的:

    1. @interface XYZToDoListViewController ()

    2. @property NSMutableArray *toDoItems;

    3. @end
  3. 在viewDidLoad方法中分配並初始化toDoItems數組:

    1. - (void)viewDidLoad
    2. {
    3.     [super viewDidLoad];
    4.     self.toDoItems = [[NSMutableArray alloc] init];
    5. }

      viewDidLoad的實際代碼中有一些附加行被註釋掉了,那些行是 Xcode 建立XYZListViewController時插入的。保留與否都沒有影響。

      如今,您已經擁有了一個能夠添加項目的數組。添加項目將在單獨的方法loadInitialData中進行,並將經過viewDidLoad調用該方法。因爲此代碼是一個模塊化任務,因此會進入其自身的方法中。固然您也能夠將方法分離出來,從而提升代碼的可讀性。在真正的應用程序中,此方法可 能會從某種永久儲存形式載入數據,例如文件。如今,咱們的目標是瞭解表格視圖如何處理自定數據項目,那麼讓咱們建立一些測試數據來體驗一下吧。

      以建立數組的方式建立項目:分配並初始化。而後,給項目命名。該名稱將顯示在表格視圖中。按照此方法建立一組項目。

載入初始數據

  1. 在@implementation行下方,添加一個新方法loadInitialData。

    1. - (void)loadInitialData {
    2. }
  2. 在此方法中,建立幾個列表項目,並將它們添加到數組。

    1. - (void)loadInitialData {
    2.     XYZToDoItem *item1 = [[XYZToDoItem alloc] init];
    3.     item1.itemName = @"Buy milk";
    4.     [self.toDoItems addObject:item1];
    5.     XYZToDoItem *item2 = [[XYZToDoItem alloc] init];
    6.     item2.itemName = @"Buy eggs";
    7.     [self.toDoItems addObject:item2];
    8.     XYZToDoItem *item3 = [[XYZToDoItem alloc] init];
    9.     item3.itemName = @"Read a book";
    10.     [self.toDoItems addObject:item3];
    11. }
  3. 在viewDidLoad方法中調用loadInitialData。

    1. - (void)viewDidLoad
    2. {
    3.     [super viewDidLoad];
    4.     self.toDoItems = [[NSMutableArray alloc] init];
    5.     [self loadInitialData];
    6. }

      檢查點:經過選取「Product」>「Build」來生成項目。您應該會在loadInitialData方法的代碼行上看到大量錯誤。第一行是出錯的關鍵所在,錯誤提示應該是「Use of undeclared identifier XYZToDoItem」。這說明編譯器在編譯XYZToDoListViewController時不知道XYZToDoItem。編譯器比較特別,您須要明確告知它應當注意什麼。

讓編譯器注意您的自定列表項目類

  1. 在XYZToDoListViewController.m文件的頂部附近找到#import "XYZToDoListViewController.h"行。

  2. 緊接着在其下方添加如下行:

    1. #import "XYZToDoItem.h"

      檢查點:經過選取「Product」>「Build」來生成項目。項目生成時應該沒有錯誤。

顯示數據

      目前,表格視圖具備一個可變數組,預填充了幾個示例待辦事項。如今您須要在表格視圖中顯示數據。

      經過讓XYZToDoListViewController成爲表格視圖的數據源,能夠實現這一點。不管要讓什麼成爲表格視圖的數據源,都須要實施UITableViewDataSource協議。須要實施的方法正是您在第二個教程中註釋掉的那些。建立有效的表格視圖須要三個方法。第一個方法是numberOfSectionsInTableView:,它告訴表格視圖要顯示幾個部分。對於此應用程序,表格視圖只須要顯示一個部分,因此實現比較簡單。

在表格中顯示一個部分

  1. 在項目導航器中,選擇XYZToDoListViewController.m。

  2. 若是您在第二個教程中註釋掉了表格視圖數據源方法,如今請移除那些註釋標記。

  3. 模板實現的部分以下所示。

    1. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    2. {
    3. #warning Potentially incomplete method implementation.
    4. // Return the number of sections.
    5.     return 0;
    6. }

    您想要單個部分,因此須要移除警告行並將返回值由 0 更改成 1。

  4. 更改numberOfSectionsInTableView:數據源方法以便返回單個部分,像這樣:

    1. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    2. {
    3. // Return the number of sections.
    4.     return 1;
    5. }

    下一個方法tableView:numberOfRowsInSection:告訴表格視圖要在給定部分中顯示幾行。如今表格中有一個部分,而且每一個待辦事項在表格視圖中都應該有它本身的行。這意味着行數應該等於toDoItems數組中的XYZToDoItem對象數。

返回表格中的行數

  1. 在項目導航器中,選擇XYZToDoListViewController.m。

  2. 您可看到模板實現的部分是這樣的:

    1. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    2. {
    3. #warning Incomplete method implementation.
    4. // Return the number of rows in the section.
    5.     return 0;
    6. }

    您想要返回所擁有的列表項目的數量。幸運的是,NSArray有一個很方便的方法,稱爲count,它會返回數組中的項目數,所以行數是[self.toDoItems count]。

  3. 更改tableView:numberOfRowsInSection:數據源方法,使其返回正確的行數。

    1. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    2. {
    3. // Return the number of rows in the section.
    4.     return [self.toDoItems count];
    5. }

      最後一個方法,tableView:cellForRowAtIndexPath:請求一個單元格來顯示給定行。到如今爲止,您只是處理了代碼,可是界面的絕大部分是針對行顯示的單元格。幸運的是,Xcode 可以讓您輕鬆地在 Interface Builder 中設計自定單元格。首個任務是設計您的單元格,並告訴表格視圖不要使用靜態內容,而要使用具備動態內容的原型單元格。

配置表格視圖

  1. 打開串聯圖。

  2. 在大綱中選擇表格視圖。

  3. 選定表格視圖後,在實用工具區域中打開「Attributes」檢查器 image: ../Art/inspector_attributes_2x.png

  4. 在「Attributes」檢查器中,將表格視圖的「Content」屬性從「Static Cells」更改成「Dynamic Prototypes」。

      Interface Builder 會採用您配置的靜態單元格,並將它們所有轉換爲原型。原型單元格,顧名思義,是使用您要顯示的文本樣式、顏色、圖像或其餘屬性進行配置,並在運行時從數據 源獲取其數據的單元格。數據源會爲每一行載入一個原型單元格,而後配置該單元格來顯示該行的數據。

      要載入正確的單元格,數據源須要知道單元格的名稱,而且該名稱也必須在串聯圖中進行配置。

      設定原型單元格名稱時,也將配置另外一個屬性—單元格選擇樣式,該樣式用於肯定用戶輕按單元格時單元格的外觀。將單元格選擇樣式設定爲「None」,使用戶 輕按單元格時單元格不會高亮顯示。這是當用戶輕按待辦事項列表中的項目,將其標記爲已完成或未完成時,您想要單元格呈現的行爲。稍後會在本教程中實現該功 能。

配置原型單元格

  1. 在表格中選擇第一個表格視圖單元格。

  2. 在「Attributes」檢查器中,找到「Identifier」欄並鍵入ListPrototypeCell。

  3. 在「Attributes」檢查器中,找到「Selection」欄並選取「None」。

      您也能夠更改原型單元格的字體或其餘屬性。基本配置很容易完成,您能夠輕鬆記下。

      下一步是實現tableView:cellForRowAtIndexPath:方法,讓數據源爲給定行配置單元格。表格視圖在想要顯示給定行時會調用此數據源方法。對於行數較少的表格視圖,全部行可能會同時出如今屏幕上,因此表格中 的每一行都會調用此方法。可是,行數不少的表格視圖在給定時間內只會顯示所有項目中的一小部分。最有效的方式是讓表格視圖僅請求要顯示行的單元格,而這一 點可經過tableView:cellForRowAtIndexPath:讓表格視圖實現。

      對於表格中的任何給定行,取回toDoItems數組中的相應條目,而後將單元格的文本標籤設定爲項目的名稱。

在表格中顯示單元格

  1. 在項目導航器中,選擇XYZToDoListViewController.m。

  2. 找到tableView:cellForRowAtIndexPath:數據源方法。模板實現是這樣的:

    1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    2. {
    3.     static NSString *CellIdentifier = @"Cell";
    4.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier     forIndexPath:indexPath];

    5. // Configure the cell...

    6. return cell;
    7. }

    該模板執行多個任務。它會建立一個變量來保存單元格的標識符,向表格視圖請求具備該標識符的單元格,添加一個註釋註明配置該單元格的代碼應該寫在哪裏,而後返回該單元格。

    要讓此代碼爲您的應用程序所用,須要將標識符更改成您在串聯圖中設定的標識符,而後添加代碼來配置該單元格。

  3. 將單元格標識符更改成您在串聯圖中設定的標識符。爲了不拼寫錯誤,請將串聯圖中的標識符拷貝並粘貼到實現文件中。該單元格標識符行如今應該是這樣的:

    1. static NSString *CellIdentifier = @"ListPrototypeCell";
  4. 在 return 語句前,添加如下代碼行:

    1. XYZToDoItem *toDoItem = [self.toDoItems objectAtIndex:indexPath.row];
    2. cell.textLabel.text = toDoItem.itemName;

      您的tableView:cellForRowAtIndexPath:方法應以下圖所示:

  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  2. {
  3.     static NSString *CellIdentifier = @"ListPrototypeCell";
  4.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
  5.     XYZToDoItem *toDoItem = [self.toDoItems objectAtIndex:indexPath.row];
  6.     cell.textLabel.text = toDoItem.itemName;
  7.     return cell;
  8. }

      檢查點:運行您的應用程序。您在loadInitialData中添加的項目列表應該在表格視圖中顯示爲單元格。

將項目標記爲已完成

      若是沒法將待辦事項列表中的項目標記爲已完成,那麼這個待辦事項列表還不夠好。如今,讓咱們來添加這樣的支持。一個簡單的界面應該能夠在用戶輕按單元格時 切換完成狀態,並在已完成的項目旁邊顯示勾號。幸運的是,表格視圖附帶了一些內建行爲,您能夠利用這些行爲來實現這樣的簡單界面。須要注意的是,在用戶輕 按單元格時,表格視圖要通知它們的委託。因此咱們的任務是寫一段代碼,對用戶輕按表格中的待辦事項這個操做做出響應。

      您在串聯圖中配置XYZToDoListViewController時,Xcode 就已經讓它成爲表格視圖的委託了。您要作的只是實現tableView:didSelectRowAtIndexPath:委託方法,使其響應用戶輕按,並在適當時候更新您的待辦事項列表。

      選定單元格後,表格視圖會調用tableView:didSelectRowAtIndexPath:委託方法,來查看它應如何處理選擇操做。在此方法中,您須要編寫代碼來更新待辦項目的完成狀態。

將項目標記爲已完成或未完成

  1. 在項目導航器中,選擇XYZToDoListViewController.m。

  2. 將如下代碼行添加到文件末尾,在@end行正上方:

    1. #pragma mark - Table view delegate

    2. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    3. {

    4. }

    請試着鍵入第二行,而不是拷貝和粘貼。您將發現代碼補全是 Xcode 最節省時間的功能之一。當 Xcode 顯示出可能的補全建議列表時,請滾動瀏覽列表,找到想要的建議,而後按下 Return 鍵。Xcode 會爲您插入整行。

  3. 您想要響應輕按,但並不想讓單元格保持選定狀態。添加如下代碼,讓單元格在選定後當即取消選定:

    1. [tableView deselectRowAtIndexPath:indexPath animated:NO];
  4. 在toDoItems數組中搜索相應的XYZToDoItem。

    1. XYZToDoItem *tappedItem = [self.toDoItems objectAtIndex:indexPath.row];
  5. 切換被輕按項目的完成狀態。

    1. tappedItem.completed = !tappedItem.completed;
  6. 告訴表格視圖從新載入您剛更新過數據的行。

    1. [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];

      您的tableView:didSelectRowAtIndexPath:方法應以下圖所示:

  1. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  2. {
  3.     [tableView deselectRowAtIndexPath:indexPath animated:NO];
  4.     XYZToDoItem *tappedItem = [self.toDoItems objectAtIndex:indexPath.row];
  5.     tappedItem.completed = !tappedItem.completed;
  6.     [tableView reloadRowsAtIndexPaths:@[indexPath]     withRowAnimation:UITableViewRowAnimationNone];
  7. }

      檢查點:運行您的應用程序。您在loadInitialData中添加的項目列表在表格視圖中顯示爲單元格。但當您輕按項目時,並無任何反應。爲何呢?

      緣由是您還沒有配置顯示項目完成狀態的表格視圖單元格。要實現此功能,您須要回到tableView:cellForRowAtIndexPath:方法,並配置單元格以在項目完成時顯示指示。

      指示項目已完成的一種方式是在其旁邊放置一個勾號。幸運的是,表格視圖右邊能夠有一個單元格附屬物。默認狀況下,單元格中沒有任何附屬物;不過您能夠進行更改,使其顯示不一樣的附屬物。其中的一個附屬物就是勾號。您要作的是根據待辦事項的完成狀態,設定單元格的附屬物。

顯示項目的完成狀態

  1. 前往tableView:cellForRowAtIndexPath:方法。

  2. 在設定單元格的文本標籤的代碼行下方添加如下代碼:

    1. if (toDoItem.completed) {
    2. cell.accessoryType = UITableViewCellAccessoryCheckmark;
    3. } else {
    4. cell.accessoryType = UITableViewCellAccessoryNone;
    5. }

      您的tableView:cellForRowAtIndexPath:方法如今應以下圖所示:

  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  2. {
  3.     static NSString *CellIdentifier = @"ListPrototypeCell";
  4.     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
  5.     XYZToDoItem *toDoItem = [self.toDoItems objectAtIndex:indexPath.row];
  6.     cell.textLabel.text = toDoItem.itemName;
  7.     if (toDoItem.completed) {
  8.         cell.accessoryType = UITableViewCellAccessoryCheckmark;
  9.     } else {
  10.         cell.accessoryType = UITableViewCellAccessoryNone;
  11.     }
  12.     return cell;
  13. }

      檢查點:運行應用程序。您在loadInitialData中添加的項目列表在表格視圖中顯示爲單元格。輕按項目時,其旁邊應該出現一個勾號。若是您再次輕按同一項目,勾號會消失。

添加新項目

      構建待辦事項列表應用程序功能的最後一步是實現添加項目的能力。當用戶在XYZAddToDoItemViewController場景的文本欄中輸入項目名稱,並輕按「Done」按鈕時,您想要視圖控制器建立一個新的列表項目並將其傳遞迴XYZToDoListViewController,以顯示在待辦事項列表中。

      首先,您須要擁有一個列表項目來進行配置。就像表格視圖那樣,視圖控制器是將界面鏈接到模型的邏輯位置。爲XYZAddToDoItemViewController添加一個屬性來保存新的待辦事項。

將 XYZToDoItem 添加到 XYZAddToDoItemViewController 類

  1. 在項目導航器中,選擇XYZAddToDoItemViewController.h。

    因爲稍後須要從表格視圖控制器訪問列表項目,因此務必將其設爲公共屬性。這就是爲何要在接口文件XYZAddToDoItemViewController.h中聲明它,而不在實現文件XYZAddToDoItemViewController.m中聲明的緣由所在。

  2. 將 import 聲明添加到@interface行上方的XYZToDoItem類中。

    1. #import "XYZToDoItem.h"
  3. 將toDoItem屬性添加到該接口。

    1. @interface XYZAddToDoItemViewController : UIViewController

    2. @property XYZToDoItem *toDoItem;

    3. @end

      要得到新項目的名稱,視圖控制器須要訪問用戶輸入名稱的文本欄。要實現此功能,請建立從XYZAddToDoItemViewController類到串聯圖中的文本欄的鏈接。

將文本欄鏈接到視圖控制器

  1. 在大綱視圖中,選擇XYZAddToDoItemViewController對象。

  2. 點按窗口工具欄右上角的「Assistant」按鈕,打開輔助編輯器。

    image: ../Art/assistant_editor_2x.png

    右邊的編輯器出現時,應該顯示有XYZAddToDoItemViewController.m。若是未顯示,請點按右邊的編輯器中的文件名,並選取XYZAddToDoItemViewController.m。

    輔助編輯器可以讓您一次打開兩個文件,以便可以在它們之間執行操做。例如,在源文件中鍵入一個屬性,而源文件的對象又在接口文件中。

  3. 在串聯圖中選擇文本欄。

  4. 按住 Control 鍵從畫布上的文本欄拖到右邊編輯器中的代碼顯示窗口,到達XYZAddToDoItemViewController.m中的@interface行正下方時中止拖移。

    image: ../Art/assistant_editor_drag_2x.png
  5. 在出現的對話框中,爲「Name」欄鍵入「textField」。

    讓選項的其他部分保持不變。您的對話框應以下圖所示:

    image: ../Art/configure_text_field_outlet.pdf
  6. 點按「Connect」。

    Xcode 會將必要的代碼添加到XYZAddToDoItemViewController.m,用於儲存指向文本欄的指針,並配置串聯圖來設置該鏈接。

      另外,您須要知道什麼時候建立項目。若是想要僅在「Done」按鈕被輕按時才建立項目,那麼請將「Done」按鈕添加爲 Outlet。

將「Done」按鈕鏈接到視圖控制器

  1. 在串聯圖中,打開輔助編輯器,將最右邊的窗口設定爲XYZAddToDoItemViewController.m。

  2. 在串聯圖中選擇「Done」按鈕。

  3. 按住 Control 鍵從畫布上的「Done」按鈕拖到右邊的編輯器中的代碼顯示窗口,到達XYZAddToDoItemViewController.m中的textField屬性正下方的行時中止拖移。

  4. 在出現的對話框中,在「Name」欄鍵入「doneButton」。

    保持選項的其他部分不變。對話框應以下圖所示:

    image: ../Art/configure_done_button_outlet_2x.png
  5. 點按「Connect」。

      您如今有了識別「Done」按鈕的方式。因爲想在輕按「Done」按鈕時建立一個項目,因此須要知道該按鈕什麼時候被按下。

      當用戶輕按「Done」按鈕時,它會啓動一個 unwind segue,返回到待辦事項列表,這正是您在第二個教程中配置的接口。在 segue 執行前,系統經過調用prepareForSegue:,給所包含的視圖控制器一次準備機會。這即是檢查用戶是否輕按了「Done」按鈕的時候。若是是,將會建立一個新的待辦事項。您能夠檢查輕按了哪個按鈕,若是是「Done」按鈕,將會建立項目。

輕按「Done」按鈕後建立項目

  1. 在項目導航器中選擇XYZAddToDoItemViewController.m。

  2. 在@implementation行下方添加prepareForSegue:方法:

    1. - (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    2. {
    3. }
  3. 在此方法中,請查看「Done」按鈕是否按下。

    若是未按下就不存儲項目,而是讓方法返回但不執行任何其餘操做。

    1. if (sender != self.doneButton) return;
  4. 查看一下文本欄中是否有文本。

    1. if (self.textField.text.length > 0) {
    2. }
  5. 若是有文本,將會建立一個新項目,並用文本欄中的文本爲其命名。另外,請確保完成狀態被設定爲「NOfalse」。

    1. self.toDoItem = [[XYZToDoItem alloc] init];
    2. self.toDoItem.itemName = self.textField.text;
    3. self.toDoItem.completed = NO;

    若是沒有文本,您就不須要存儲項目,也不須要執行任何其餘操做。

您的prepareForSegue:方法應以下圖所示:

  1. - (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
  2. {
  3.     if (sender != self.doneButton) return;
  4.     if (self.textField.text.length > 0) {
  5.         self.toDoItem = [[XYZToDoItem alloc] init];
  6.         self.toDoItem.itemName = self.textField.text;
  7.         self.toDoItem.completed = NO;
  8.     }
  9. }

      既然建立了一個新項目,那麼就須要將該項目傳遞迴XYZToDoListViewController,以便它能夠將項目添加到待辦事項列表。要完成此功能,請從新訪問您在第二個教程中編寫的unwindToList:方法。當用戶輕按「Cancel」或「Done」按鈕,XYZAddToDoItemViewController場景會在關閉時調用該方法。

      就像做爲 unwind segue 目標的全部方法同樣,unwindToList:方法也採用 segue 做爲參數。segue 參數是從XYZAddToDoItemViewController展開並返回到XYZToDoListViewController的過渡。因爲 segue 是兩個視圖控制器之間的過渡,因此知道它的源視圖控制器是XYZAddToDoItemViewController。經過向 segue 對象請求其源視圖控制器,您能夠用unwindToList:方法訪問儲存在源視圖控制器中的任何數據。目前,您想要訪問toDoItem。若是它是nil,則該項目並未建立。緣由多是文本欄沒有文本,或者是用戶輕按了「Cancel」按鈕。若是toDoItem有值,則能夠取回該項目,再添加到toDoItems數組,並經過從新載入表格視圖中的數據將其顯示在待辦事項列表中。

儲存並顯示新項目

  1. 在項目導航器中,選擇XYZToDoListViewController.m。

  2. 將 import 聲明添加到@interface行上方的XYZAddToDoItemViewController類中。

    1. #import "XYZAddToDoItemViewController.h"
  3. 找到您在第二個教程中添加的unwindToList:方法。

  4. 在此方法中,取回源視圖控制器XYZAddToDoItemViewController,即您要展開的控制器。

    1. XYZAddToDoItemViewController *source = [segue sourceViewController];
  5. 取回控制器的待辦事項。

    1. XYZToDoItem *item = source.toDoItem;

    這就是輕按「Done」按鈕時建立的項目。

  6. 看看這個項目是否存在。

    1. if (item != nil) {
    2. }

    若是是nil,多是「Cancel」按鈕關閉了屏幕,或者是文本欄中沒有文本,所以沒必要存儲該項目。

    若是項目存在,請添加到toDoItems數組。

    1. [self.toDoItems addObject:item];
  7. 從新載入表格中的數據。

    由於表格視圖不會跟蹤其數據,因此數據源(在這個程序中是表格視圖控制器)有責任通知表格視圖什麼時候有新數據供其顯示。

    1. [self.tableView reloadData];

      您的unwindToList:方法應以下圖所示:

  1. - (IBAction)unwindToList:(UIStoryboardSegue *)segue
  2. {
  3.     XYZAddToDoItemViewController *source = [segue sourceViewController];
  4.     XYZToDoItem *item = source.toDoItem;
  5.     if (item != nil) {
  6.         [self.toDoItems addObject:item];
  7.         [self.tableView reloadData];
  8.     }
  9. }

      檢查點:運行您的應用程序。如今,當您點按添加按鈕 (+) 並建立一個新項目時,它應該會顯示在待辦事項列表中。恭喜您!您已經建立了一個應用程序,它能接收用戶的輸入,將其儲存在對象中,並在兩個視圖控制器之間傳遞該對象。對於基於串聯圖的應用程序,這是在場景之間移動數據的基礎。

小結

      您差很少完成了開發 iOS 應用程序的入門之旅。最後一部分更詳細地講述瞭如何查詢文稿材料,而且爲您學習建立更高級的應用程序給出了一些後續建議。

相關文章
相關標籤/搜索