1 #import <UIKit/UIKit.h> 2 3 @interface TWFXViewController : UIViewController<UITableViewDataSource,UITableViewDelegate> 4 5 - (IBAction)btnClick:(UIButton *)sender; 6 @property (retain, nonatomic) IBOutlet UITextField *textOutlet; 7 @property(nonatomic,retain) NSMutableArray *mdata; 8 9 @end
1 // 2 // TWFXViewController.m 3 // DemoTableView 4 // 5 // Created by Lion User on 12-11-27. 6 // Copyright (c) 2012年 Lion User. All rights reserved. 7 // 8 9 #import "TWFXViewController.h" 10 11 @interface TWFXViewController () 12 13 @end 14 15 @implementation TWFXViewController 16 17 @synthesize mdata; 18 19 20 - (void)viewDidLoad 21 { 22 [super viewDidLoad]; 23 // Do any additional setup after loading the view, typically from a nib. 24 25 /*基礎知識 26 表視圖UItableView用來顯示表中可見部分的表 27 表視圖單元UITableViewCell負責顯示表中的一行 28 29 表視圖從遵循UITableViewDelegate協議的對象中獲取配置數據(配置表視圖的外觀並處理一些與用戶的交互) 30 表視圖從遵循UITableViewDataSource協議的對象中獲得行數據 31 32 表視圖有兩種基本樣式:分組表(多個Section)和無格式表(單個Section,默認樣式) 33 */ 34 35 /* 36 創建一個NSMutableArray充當數據源 37 */ 38 NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:@"0",@"1",@"2", 39 @"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"11",@"12", 40 @"13",@"14",@"15",@"16",@"17",@"18",@"19", nil]; 41 42 //賦值給控制器的屬性mdata后,把array release 43 self.mdata = array; 44 [array release]; 45 46 47 /* 48 創建一個UITableView,並指定其顯示區域和顯示樣式 49 style參數指定該表視圖的樣式,UITableViewStylePlain 表示是無格式表,即只有一個section; 50 UITableViewStyleGrouped表示分組表,有多個section,若選擇此樣式,表視圖的delegate對象還要實現 51 numberOfSectionsInTableView: 方法,以指定該表視圖有多少個section 52 */ 53 UITableView *tableview = [[UITableView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 480.0f) 54 style:UITableViewStylePlain]; 55 56 //指定UITableView的數據源對象和委托對象 57 tableview.dataSource = self; 58 tableview.delegate = self; 59 60 //添加到view顯示,然后引用計數器減一 61 [self.view addSubview: tableview]; 62 [tableview release]; 63 } 64 65 66 /* 67 UITableView通過該方法得知有多少section 68 UITableViewDataSource協議里的方法,當UITableView的樣式是UITableViewStyleGrouped時需要實現該方法 69 demo里的UITableView的style是UITableViewStylePlain,所以返回1即可,也可以不現實該方法 70 */ 71 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 72 { 73 return 1; 74 } 75 76 77 /* 78 UITableView通過該方法得知指定的section有多少行 79 UITableViewDataSource協議里的方法 80 在demo里,數組里的一項作為一行,所以返回數組的項數即可 81 */ 82 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 83 { 84 return self.mdata.count; 85 } 86 87 88 /* 89 當表視圖需要繪制其中一行時,會調用這個方法,這是 UITableViewDataSource協議里的方法 90 這個方法詳細描述了在繪制cell時的具體信息 91 參數tableview:表示發出請求的表 92 參數indexpath:NSIndexPath類型,指明需要繪制的是表視圖里的哪個section和哪一行 93 */ 94 -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 95 { 96 //此字符串充當表示 某種 表單元/cell 的鍵,即是cell一種標識符,也就是表示cell的某種特性 97 //背景:每個UITableViewCell都是一個對象,都是需要資源開銷的.如果數據有有一萬條數據,那么系統也要為應用創建一萬個cell么?這將要耗費巨大的資源,不現實 98 //而SimpleTableIdentifier特性表示cell是可重用的(即當表視圖滑動時從屏幕上面滾出去的cell會被放到一個可重用隊列里,當屏幕底部繼續繪制新行時,將優先使用這些cell而不是創建新的cell),這樣不管數據源有多少條,程序都只創建有限數量的cell,當屏幕滑動時,那些cell還是以前的那些cell,只不過將顯示的數據換了一批而已.大體思想是這樣的,具體有點不同,可以自己度娘 99 static NSString *SimpleTableIdentifier = @"SimpleTableIdentifier"; 100 101 //當表視圖需要繪制一行時,會優先使用表視圖里的可重用隊列里的cell 102 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier]; 103 104 /* 105 當可重用隊列里沒有多余的cell后(在程序剛開始運行時,肯定是沒有的啦),就只能新建了, 106 當然,新建的cell也是指定為SimpleTableIdentifier的,同時還要指定新建的cell的style屬性 107 當系統內存緊張時,表視圖會刪除這些可重用隊列里的cell 108 把新建的cell指定為自動釋放 109 110 cell的style包括圖像 文本 和詳細文本三種元素, style參數具體值的說明如下: 111 UITableViewCellStyleDefault:只顯示文本和圖片 112 UITableViewCellStyleValue1:顯示文本 圖片 和詳細文本,詳細文本在cell的右邊,顏色為淺藍色 113 UITableViewCellStyleValue2:只顯示文本和詳細文本並局中顯示,但文本顏色為淺藍色,並且字體變小顏色為淺藍色,使用於電話/聯系人應用程序 114 UITableViewCellStyleSubtitle:顯示文本 圖片 和詳細文本,詳細文本在文本的下面,顏色為淺灰色 115 它們具體使用的場合有待度娘 116 */ 117 if (cell == nil) { 118 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 119 reuseIdentifier:SimpleTableIdentifier]; 120 [cell autorelease]; 121 } 122 123 //根據表視圖的行數,從數組里獲取對應索引的數據 124 NSInteger mRow = [indexPath row]; 125 cell.textLabel.text = [self.mdata objectAtIndex:mRow]; 126 127 //為每個cell的imageView屬性指定一個值,表示在左邊顯示一張圖片 128 UIImage *image = [UIImage imageNamed:@"Argentina.png"]; 129 cell.imageView.image = image; 130 131 //為cell的highlightedImage屬性指定一個值,表示當該行被選中時在左邊顯示的圖片將會被換成highlightedImage 132 UIImage *highlightImage = [UIImage imageNamed:@"Austria.png"]; 133 cell.imageView.highlightedImage = highlightImage; 134 135 136 //為cell添加detailTextLabel屬性 137 if (mRow < 7) { 138 cell.detailTextLabel.text = @"zou"; 139 } else { 140 cell.detailTextLabel.text = @"鄒"; 141 } 142 143 144 return cell; 145 } 146 147 /* 148 UITableViewDelegate協議里的方法-----設置行縮進 149 疑問:UITableView在繪制每一行時都調用此方法?應該是的,但表視圖怎么知道有這個方法呢?莫非在為表視圖指定delegate對象后, 150 表視圖在進行某一動作時都會根據該動作對應的指定信息來調用相應的方法鏈? 151 */ 152 -(NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath 153 { 154 NSUInteger row = [indexPath row]; 155 return row; 156 } 157 158 159 /* 160 UITableViewDelegate協議里的方法-----處理行的選擇 161 該方法獲取傳遞過來的indexpath,indexpath表示哪項被選中 162 該方法提供了一個機會給我們來攔截行選中事件? 163 在行被選中時調用? 行選中這個事件包含里一個方法鏈,方法鏈里就包括了這個方法? 164 */ 165 -(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath 166 { 167 NSUInteger row = [indexPath row]; 168 // NSIndexPath *path = [NSIndexPath indexPathForRow:2 inSection:0]; 169 if (row == 0) { 170 //返回nil表示沒有行被選中 171 return nil; 172 } 173 174 return indexPath; 175 } 176 177 178 - (void)didReceiveMemoryWarning 179 { 180 [super didReceiveMemoryWarning]; 181 // Dispose of any resources that can be recreated. 182 183 self.mdata = nil; 184 } 185 186 - (IBAction)btnClick:(UIButton *)sender { 187 188 if (self.textOutlet.text.length != 0) { 189 [self.mdata addObject:self.textOutlet.text]; 190 } 191 192 if ([self.textOutlet isFirstResponder]) { 193 [self.textOutlet resignFirstResponder]; 194 } 195 // [tableview reloadData]; 196 } 197 198 199 200 201 - (void)dealloc { 202 [_textOutlet release]; 203 [mdata release]; 204 // [tableView release]; 205 [super dealloc]; 206 } 207 @end
對tableview進行編輯:增刪改移
1 /* 2 實現標記功能 3 當tableview進入編輯模式時,無法進行標記 4 */ 5 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 6 { 7 //canAccessoryCell作為標示量,標示是否能標記cell 8 if (canAccessoryCell) { 9 10 UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 11 12 if (cell.accessoryType == UITableViewCellAccessoryNone) { 13 cell.accessoryType = UITableViewCellAccessoryCheckmark; 14 } 15 16 else 17 { 18 cell.accessoryType = UITableViewCellAccessoryNone; 19 } 20 } 21 22 23 /* 24 UITableViewCell的accessoryType屬性表示該行的標記樣式,有以下幾種常量: 25 26 UITableViewCellAccessoryCheckmark //在右邊顯示一個勾 27 UITableViewCellAccessoryDetailDisclosureButton //在右邊顯示一個圖標控件 28 UITableViewCellAccessoryDisclosureIndicator //在右邊顯示一個 > 圖標 29 UITableViewCellAccessoryNone //不顯示任何標記 30 */ 31 32 33 /* 34 下面這個函數,使得行的選擇效果一閃即消失,即無法選中某行.不是無法標記,而是無法選中,無法突出高亮那種效果 35 */ 36 // [tableView deselectRowAtIndexPath:indexPath animated:YES]; 37 } 38 39 40 /* 41 進入編輯模式后,首先要選則一種模式:刪除 \ 增加 \ 移動. 42 默認是刪除模式,既是在行的左邊顯示一個紅色的刪除按鈕 43 */ 44 -(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath 45 { 46 //在demo里,定義了一個屬性,該屬性保存了當前的編輯模式,在button的 touchupinside 事件里賦值. 47 return self.editingStyle; 48 } 49 50 51 52 /* 53 進入編輯模式 選擇了具體的刪除 增加 編輯模式后,執行編輯 54 */ 55 -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 56 { 57 NSInteger row = [indexPath row]; 58 if (self.editingStyle == UITableViewCellEditingStyleDelete) { 59 60 /* 61 在tableview界面上刪除和增加記錄時,在后台的處理要先操作數據源(刪除或增加),然后才調用tableview的刪除或增加rows的方法 62 這涉及到tableview和數據源的底層交互的機制問題,估計是一些映射之類的機制,暫時不清楚 63 操作完數據源之后,可以調用tableview的刪除或增加方法,也可以直接reload數據源,但這樣子就沒有動畫效果了 64 */ 65 [self.m_data removeObjectAtIndex:row]; 66 67 /* 68 創建一個NSArray數組,里面放的是一組 NSIndexPath 類型 的對象,作為tableview進行操作的對象的索引 69 */ 70 NSArray *array = [NSArray arrayWithObjects:indexPath,nil]; 71 72 [tableView deleteRowsAtIndexPaths:array 73 withRowAnimation:UITableViewRowAnimationRight]; 74 75 /* 76 withRowAtimation參數是一個UITableViewRowAnimation類型的枚舉變量,表示該操作對應的動畫效果, 77 一般用UITableViewRowAnimationAutomatic就行了,其他值如下: 78 79 typedef enum { 80 UITableViewRowAnimationFade, 81 UITableViewRowAnimationRight, 82 UITableViewRowAnimationLeft, 83 UITableViewRowAnimationTop, 84 UITableViewRowAnimationBottom, 85 UITableViewRowAnimationNone, 86 UITableViewRowAnimationMiddle, 87 UITableViewRowAnimationAutomatic = 100 88 } UITableViewRowAnimation; 89 */ 90 91 } 92 else if(self.editingStyle == UITableViewCellEditingStyleInsert) 93 { 94 if (self.textFieldNewData.text.length != 0) { 95 96 NSString *newString = self.textFieldNewData.text; 97 [self.m_data insertObject:newString atIndex:row]; 98 99 NSArray *array = [NSArray arrayWithObjects:indexPath,nil]; 100 [tableView insertRowsAtIndexPaths:array 101 withRowAnimation:UITableViewRowAnimationAutomatic]; 102 } 103 else{ 104 105 UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Attention!" message:@"new data is nil!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; 106 107 [alertView show]; 108 [alertView release]; 109 } 110 111 } 112 } 113 114 115 /* 116 是否允許移動cell 117 */ 118 -(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath 119 { 120 return YES; 121 } 122 123 124 /* 125 執行移動操作 126 只是對數據源執行了移動操作,會自動映射到tableview? 127 */ 128 -(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath 129 { 130 NSUInteger fromRow = [sourceIndexPath row]; 131 NSUInteger toRow = [destinationIndexPath row]; 132 133 id object = [self.m_data objectAtIndex:fromRow]; 134 [self.m_data removeObjectAtIndex:fromRow]; 135 [self.m_data insertObject:object atIndex:toRow]; 136 } 137 138 139 - (IBAction)btnDone:(UIButton *)sender { 140 141 self.editingStyle = UITableViewCellAccessoryNone; 142 [self.myTableView setEditing:NO]; 143 } 144 145 - (IBAction)btnDelete:(UIButton *)sender { 146 147 //要先給editingStyle賦值在啟動tableview的編輯模式,因為一啟動tableview的編輯模式,就會調用 tableview: editingStyleForRowAtIndexPath: 方法來獲取當前的編輯模式 148 self.editingStyle = UITableViewCellEditingStyleDelete; 149 [self.myTableView setEditing:NO]; 150 [self.myTableView setEditing:YES animated:YES]; 151 } 152 153 - (IBAction)btnRemove:(UIButton *)sender { 154 155 //移動cell不需要進入 刪除 或者 增加 編輯模式 156 self.editingStyle = UITableViewCellAccessoryNone; 157 [self.myTableView setEditing:NO]; 158 [self.myTableView setEditing:YES animated:YES]; 159 } 160 161 - (IBAction)btnAdd:(UIButton *)sender { 162 163 self.editingStyle = UITableViewCellEditingStyleInsert; 164 [self.myTableView setEditing:NO]; 165 [self.myTableView setEditing:YES animated:YES]; 166 } 167 168 - (IBAction)btnSelect:(UIButton *)sender { 169 170 if ([self.textFieldNewData isFirstResponder]) { 171 [self.textFieldNewData resignFirstResponder]; 172 } 173 174 if (canAccessoryCell) { 175 canAccessoryCell = NO; 176 } else { 177 canAccessoryCell = YES; 178 } 179 }