延續之前與 UITableView 相關的文章,你可以在「索引式搜索」中的「元件設定」分類裡找到所有有關 UITableView 的文章,UITableView 支援項目新增、移動、與刪除等操作,而本篇要介紹的是新增項目的方法,在此提供兩種方法來動態新增表格內的項目:透過 UIBarButtonItem 與按下編輯表格時增加一個新增項目的欄位。
注意事項
在開始撰寫刪除程式碼之前,請務必確認以下項目:
- 對應的操作陣列形態必須是 NSMutableArray
UITableView 在做新增項目的動作時,我們同樣也需要對陣列裡的元素作新增的動作,由於傳統的 NSArray 並不支援 addObject: 方法函式,應此在陣列的形態上請務必都宣告成 NSMutableArray,如果你的陣列也同時包含巢狀結構,也請務必確認所有子結構下的陣列形態都是 NSMutableArray。
- 陣列結構的正確性
由於每次在對 UITableView 做新增項目的動作時,表格的內容都會隨即更新,也就是會重新執行那些表格基本設定的方法函式,像是設定表格的欄位數目、分類數目等等,如果你陣列的結構有錯誤,無法與 UITableView 相互對應,例如 index 錯誤無法在陣列中找到資料等問題,程式會出現 crash 的可能。
- 任何時候都應先對陣列操作,之後才是 UITableView
原因同上,如果先對 UITableView 進行操作,在更新表格內容時極有可能出現無法與陣列內元素對應的情形,在新增表格項目中一個比較好的做法, 就是先改變陣列內的元素,在直接呼叫 UITableView 的 reloadData 方法函式,來重新顯示表格的資料。
掌握以上技巧之後,下面就可以開始撰寫動態新增表格項目的程式碼了。
開啟編輯表格的功能
在未啓用此功能之前,使用者只能點選表格項目來顯示詳細資料,有關其他新增、刪除、移動等功能都無法使用,若要開啓表格的互動功能,可以使用以下內建的方法函式,並回傳一個 YES 的布林值即可(預設值為 NO)。
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
使用 UIBarButtonItem 來新增項目
透過使用 UIBarButtonItem 做新增項目的動作方法非常簡單,只要製作一個 UIBarButtonItem 並設定他所要觸發的方法函式,之後在其方法函式中對陣列增加想要的元素,之後在使用 UITableView 的 reloadData 方法函式來更新表格資訊即可。
下列程式碼是在 Navigation Bar 的左邊加上一個 UIBarButtonItem,並且設定按鈕按下時所要觸發的方法函式 addHeroicaItem,你可以將增加 UIBarButtonItem 的程式碼撰寫在 viewDidLoad 方法函式中。
- (void)viewDidLoad {
[super viewDidLoad];
[self setTitle:@"LEGO Heroica"];
//製作增加項目的UIBarButtonItem
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addHeroicaItem)];
[self.navigationItem setLeftBarButtonItem:addButton];
//資料初始化
roleArray = [[NSMutableArray alloc] initWithObjects:@"野蠻人", @"法師", @"弓箭手", @"盜賊", @"德魯伊", @"騎士", nil];
monsterArray = [[NSMutableArray alloc] initWithObjects:@"哥布林戰士", @"哥布林護衛", @"哥布林軍官", @"哥布林王", @"黑暗德魯伊", @"狼人", @"傀儡護衛", @"傀儡領主", @"蜘蛛", @"蝙蝠", nil];
heroicaArray = [[NSMutableArray alloc] initWithObjects:roleArray, monsterArray, nil];
}
//在每個分類裡都添加一筆資料
- (void) addHeroicaItem {
for (id item in heroicaArray) {
[item addObject:@"被增加的項目"];
}
[self.tableView reloadData];
}
現在每當按下 UIBarButtonItem 之後,表格內所有分類都會在最後增加一個名為「被增加的項目」的項目。
透過在編輯表格時的新增項目欄位
此方法是希望在對表格按下「編輯」時,可以出現新增欄位的選項,方便使用者做新增欄位的動作,雖然說這是一個很不錯的做法,但是執行起來卻相對複雜,我們將分成以下幾個步驟來實作。
*重新設定顯示資料的數目
由於我們希望再按下表格的編輯按鈕時,能夠動態替每個分類增加一個欄位,好讓使用者點選並新增資料,因此表格是否處於編輯狀態,它所顯示的資料數目也不盡相同,我們可以利用 self.tableView.editing 來判斷目前表格是否處於編輯狀態,設定回傳不同的欄位數目。
//設定資料數目
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (self.tableView.editing) {
return [[heroicaArray objectAtIndex:section] count] +1;
} else {
return [[heroicaArray objectAtIndex:section] count];
}
}
*重新設定顯示的資料內容
原因同上,在按下表格的編輯按鈕時,所顯示的資料會比實際陣列中的資料多1,而多的這一比資料,就是用來新增欄位的項目。下面程式碼是判斷該欄位如果是該分類的最後一個時,就將欄位名稱設定成「點我增加項目」。
// 設定資料內容
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//製作可重復利用的表格欄位Cell
static NSString *CellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//設定按編輯時的新增欄位
if (self.tableView.editing && indexPath.row == [[heroicaArray objectAtIndex:indexPath.section] count]) {
cell.textLabel.text = @"點我增加項目";
} else {
cell.textLabel.text = [[heroicaArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
}
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
return cell;
}
*設定項目編輯時的類型
項目預設的編輯類型是 UITableViewCellEditingStyleDelete,也就是刪除,但是我們的最後一個項目的編輯類型可不能是刪除,它必須是 UITableViewCellEditingStyleInsert,我們才能動態對表格新增資料,若要設定項目編輯時的類型,可以透過 UITableView 內建的方法函式並回傳一個 UITableViewCellEditingStyle 參數來設定。
//設定編輯時的類型
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == [[heroicaArray objectAtIndex:indexPath.section] count]) {
return UITableViewCellEditingStyleInsert;
} else {
return UITableViewCellEditingStyleDelete;
}
}
*實作新增項目的程式碼
透過下列另一個內建的 UITableView 方法函式,撰寫在選擇新增項目之後所要處理動作的程式碼,同樣也是先對陣列增加元素,再去呼叫 UITableView 的 reloadData 方法函式,來重新顯示表格的資料,與之前的方法不同的是,在此新增的項目只針對該分類,並非所有分類。
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
//判斷編輯表格的類型為「新增」
if (editingStyle == UITableViewCellEditingStyleInsert) {
[[heroicaArray objectAtIndex:indexPath.section] addObject:@"被增加的項目"];
[self.tableView reloadData];
}
}
*重新製作表格的「編輯」按鈕
到目前為止已經完成新增項目的程式碼,但是仍有一個小問題在,就是當按下「編輯」按鈕時,表格雖然處於編輯狀態,但是並沒有出現新的項目好讓使用者操作,有就是表格並沒有 reloadData 重新繪製,原因是之前使用 self.navigationItem.rightBarButtonItem = self.editButtonItem 所製作出來的標準按扭,並不會觸發 UITableView 的 reloadData 方法函式,因此,現在我們要重新製作表格的「編輯」按鈕,你可以在 viewDidLoad 方法函式中撰寫以下製作「編輯」按鈕的程式碼。
//改寫編輯按鈕
UIBarButtonItem *editButton = [[UIBarButtonItem alloc] initWithTitle:@"編輯" style:UIBarButtonItemStyleBordered target:self action:@selector(editHeroicaItem)];
[self.navigationItem setRightBarButtonItem:editButton];
接著是按下按鈕所觸發的方法函式,在方法函式中利用 self.tableView.editing 參數來判斷表格是否處於編輯狀態,並依照表格現在的狀態來設定按鈕的文字,最後是表格編輯狀態的切換與資料的更新。
- (void)editHeroicaItem {
if (self.tableView.editing) {
[self.navigationItem.rightBarButtonItem setTitle:@"編輯"];
} else {
[self.navigationItem.rightBarButtonItem setTitle:@"完成"];
}
[self.tableView setEditing:!self.tableView.editing];
[self.tableView reloadData];
}
上述程式碼中,既使你使用 setEditing: animated: 方法還函式,表格在進入或是離開編輯狀態時,同樣也不會出現漸變的動畫,原因是因為表格索項目不一致所導致的。
關於新增項目的內容
文章中只有示範如何動態增加 UITableView 中的項目,並沒有對所要新增項目的內容加以琢磨,關於新增項目的內容都是給予固定值,若是你想要替項目設定不同的內容,可以在些關鍵的程式碼處開啓新的 View 來對陣列作設定,之後再去呼叫 UITableView 的 reloadData 方法函式,重新顯示表格的內容。
沒有留言:
張貼留言