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 }