UI基础 - UITableView 05:对单元格进行编辑(同步了数据源)
■ 对单元格的编辑处理:同步数据源
1. 当我们对 cell 进行编辑时,往往伴随着对数据的处理,无数据处理的编辑是没有任何意义的!
// - Student.h:数据存储
1 #import <Foundation/Foundation.h> 2 @interface Student : NSObject 3 4 @property(nonatomic,copy)NSString *name; 5 @property(nonatomic,copy)NSString *sex; 6 @property(nonatomic,copy)NSString *age; 7 @property(nonatomic,copy)NSString *phoneNumer; 8 9 @end
// - StudentData.h:管理数据源的 model 层
1 #import <Foundation/Foundation.h> 2 // 注意引用 UIKit 头文件,否则 .m 文件中使用 indexPath 不提示,报错 3 #import <UIKit/UIKit.h> 4 @class Student; 5 @interface StudentData : NSObject 6 7 @property(nonatomic,strong)NSMutableArray *dataArray;// 数据源:学生信息 8 9 + (StudentData *)shareData;// 单例 10 11 /** @brief 根据 indexPath 返回一个学生实例 12 */ 13 -(Student*)studentAtIndexPath:(NSIndexPath*)indexPath; 14 15 /**@brief 根据区号返回区头标题 16 */ 17 -(NSString *)headerTitleInsection:(NSInteger )section; 18 19 /**@brief 根据 indexPath 删除一个学生实例 20 */ 21 - (void)removeStudentAnIndexPath:(NSIndexPath *)indexPath; 22 23 /**@brief 根据 indexPath 添加一个学生实例 24 */ 25 - (void)insertStudentIndesPath:(NSIndexPath*)indexPath; 26 27 /**@brief 把一个学生从一个位置移动到另一个位置 28 */ 29 - (void)moveStudentFromSourceIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath; 30 31 @end
// - StudentData.m:实现编辑操作,如 增、删、拖动
1 #import "StudentData.h" 2 #import "Student.h" 3 static StudentData *dataHandle = nil; 4 5 @implementation StudentData 6 7 + (StudentData *)shareData{ 8 9 if (!dataHandle) { 10 11 dataHandle = [[StudentData alloc]init]; 12 [dataHandle loadHardCode]; 13 } 14 15 return dataHandle; 16 } 17 18 // 加载数据 19 -(void)loadHardCode{ 20 21 self.dataArray = [NSMutableArray array]; 22 for (int i = 0; i < 2; i ++) { 23 24 NSMutableArray *smallArray = [NSMutableArray arrayWithCapacity:1]; 25 26 // 每轮创建 10 个学生 27 for (int j =0; j < 10; j ++) { 28 29 Student *stu = [[Student alloc] init]; 30 // 姓名 31 if (i == 0) { 32 stu.name = [NSString stringWithFormat:@"Hazell%d号",j]; 33 }else{ 34 35 stu.name = [NSString stringWithFormat:@"Bruce%d号",j]; 36 } 37 38 // 年龄 39 stu.age = [NSString stringWithFormat:@"%d",arc4random()%20 +20];// 20-39 40 // 手机号码 41 stu.phoneNumer = [NSString stringWithFormat:@"185%08d",arc4random()%100000000]; 42 43 // 性别判断 44 if (j % 2 == 0) { 45 stu.sex = @"male"; 46 }else{ 47 stu.sex = @"female"; 48 } 49 50 [smallArray addObject:stu]; 51 } 52 53 [self.dataArray addObject:smallArray]; 54 } 55 } 56 57 58 - (Student *)studentAtIndexPath:(NSIndexPath *)indexPath{ 59 60 return [[self.dataArray objectAtIndex:indexPath.section ] objectAtIndex:indexPath.row]; 61 } 62 63 - (NSString *)headerTitleInsection:(NSInteger )section{ 64 65 return [[NSArray arrayWithObjects:@"H组",@"B组", nil] objectAtIndex:section]; 66 } 67 68 - (void)removeStudentAnIndexPath:(NSIndexPath *)indexPath{ 69 70 [_dataArray[indexPath.section] removeObjectAtIndex:indexPath.row]; 71 } 72 73 - (void)insertStudentIndesPath:(NSIndexPath*)indexPath{ 74 75 Student *stu = [[Student alloc] init]; 76 NSInteger j = 1000000+arc4random()%100; 77 stu.name = [NSString stringWithFormat:@"Hazell%ld号",j]; 78 stu.age = [NSString stringWithFormat:@"%d",arc4random()%20 +20];//20-39 79 stu.phoneNumer = [NSString stringWithFormat:@"185%08d",arc4random()%100000000]; 80 if (j % 2 == 0) { 81 stu.sex = @"male"; 82 }else{ 83 stu.sex = @"female"; 84 } 85 86 [_dataArray[indexPath.section] insertObject:stu atIndex:indexPath.row]; 87 } 88 89 - (void)moveStudentFromSourceIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{ 90 91 // 获取原位置的实例 92 Student *stu = [self studentAtIndexPath:sourceIndexPath]; 93 // 从原位置删除 94 [self removeStudentAnIndexPath:sourceIndexPath]; 95 // 添加到新位置:先取到小数组(分区),再在小数组(分区)中添加元素; 96 [[self.dataArray objectAtIndex:destinationIndexPath.section] insertObject:stu atIndex:destinationIndexPath.row]; 97 } 98 @end
// - ViewController.m
1 #import "ViewController.h" 2 #import "StudentData.h" 3 #import "Student.h" 4 @interface ViewController ()<UITableViewDataSource,UITableViewDelegate> 5 6 @property(nonatomic,strong)UITableView *tableView; 7 8 @end 9 10 @implementation ViewController 11 12 - (void)viewDidLoad { 13 [super viewDidLoad]; 14 15 self.navigationItem.title = @"cell编辑"; 16 self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"编辑" style:UIBarButtonItemStyleDone target:self action:@selector(editTableView:)]; 17 self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height-64) style:UITableViewStylePlain]; 18 _tableView.dataSource = self; 19 _tableView.delegate = self; 20 [self.view addSubview:_tableView]; 21 } 22 23 // 编辑 24 - (void)editTableView:(UIBarButtonItem *)barItem{ 25 26 if (_tableView.editing) { 27 barItem.title = @"编辑"; 28 }else{ 29 barItem.title = @"完成"; 30 } 31 32 [_tableView setEditing:!_tableView.editing animated:YES]; 33 } 34 35 #pragma mark - <UITableViewDataSource> 36 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 37 38 return [[StudentData shareData].dataArray[section] count]; 39 } 40 41 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ 42 43 return [StudentData shareData].dataArray.count; 44 } 45 46 // cell 47 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 48 static NSString *cellIndetifier = @"cell"; 49 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIndetifier]; 50 if (!cell) { 51 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIndetifier]; 52 } 53 54 Student * stu = [[StudentData shareData] studentAtIndexPath:indexPath]; 55 cell.textLabel.text = [NSString stringWithFormat:@"Name:%@ Sex:%@",stu.name,stu.sex]; 56 cell.detailTextLabel.text = [NSString stringWithFormat:@"Age:%@ phoneNumer:%@",stu.age,stu.phoneNumer]; 57 return cell; 58 } 59 60 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ 61 62 return [[StudentData shareData] headerTitleInsection:section]; 63 } 64 65 #pragma mark - 编辑 66 -(void)setEditing:(BOOL)editing animated:(BOOL)animated{ 67 68 [super setEditing:editing animated:animated]; 69 [_tableView setEditing:editing animated:animated]; 70 } 71 72 //// 哪些行可以编辑:默认是全部可以 73 //- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{ 74 // 75 // if (indexPath.row == 0 && indexPath.section == 1){ 76 // return NO; 77 // } 78 // return YES; 79 //} 80 81 82 - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{ 83 84 if (indexPath.row == 1 | indexPath.row == 5) { 85 return UITableViewCellEditingStyleInsert;// 添加 86 }else{ 87 return UITableViewCellEditingStyleDelete;// 删除 88 } 89 } 90 91 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{ 92 93 if (editingStyle == UITableViewCellEditingStyleDelete) { 94 95 [[StudentData shareData] removeStudentAnIndexPath:indexPath]; 96 [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 97 98 }else if (editingStyle == UITableViewCellEditingStyleInsert){ 99 100 NSIndexPath *inserIndexPath = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section]; 101 [[StudentData shareData] insertStudentIndesPath:inserIndexPath]; 102 [tableView insertRowsAtIndexPaths:[NSArray arrayWithObjects:inserIndexPath, nil] withRowAnimation:UITableViewRowAnimationFade]; 103 } 104 } 105 106 #pragma mark - 移动 107 - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath{ 108 109 return YES; 110 } 111 112 - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{ 113 114 [[StudentData shareData] moveStudentFromSourceIndexPath:sourceIndexPath toIndexPath:destinationIndexPath]; 115 } 116 117 // 限制跨区移动 118 - (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath{ 119 120 if (sourceIndexPath.section == proposedDestinationIndexPath.section){ 121 return proposedDestinationIndexPath; 122 123 }else{ 124 return sourceIndexPath; 125 } 126 } 127 128 #pragma mark - <UITableViewDelegate> 129 // 进入编辑且点击删除,修改提示标题 130 - (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath{ 131 132 if (indexPath.row == 0) { 133 return @"delete"; 134 } 135 return @"删除"; 136 } 137 138 // 设置进入编辑状态时,cell 不会缩进 139 // 前提是在 editingStyleForRowAtIndexPath: 方法中,编辑样式为 UITableViewCellEditingStyleNone 140 - (BOOL)tableView: (UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath{ 141 142 return NO; 143 } 144 145 @end
运行效果:编辑状态
分类:
UI章节
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律