iOS_12_tableViewCell的删除更新_红楼梦
来源:互联网 发布:金山数据恢复大师vip 编辑:程序博客网 时间:2024/06/16 15:06
最终效果图:
Girl.h
//// Girl.h// 12_tableView的增删改//// Created by beyond on 14-7-27.// Copyright (c) 2014年 com.beyond. All rights reserved.//#import <Foundation/Foundation.h>@interface Girl : NSObject// UI控件用weak,字符串用copy,其他对象用strong// 头像图片名@property(nonatomic,copy)NSString *headImgName;// 姓名@property(nonatomic,copy)NSString *name;// 判词@property(nonatomic,copy)NSString *verdict;// 提供一个类方法,即构造函数,返回封装好数据的对象(返回id亦可)+ (Girl *)girlNamed:(NSString *)name headImgName:(NSString*)headImgName verdict:(NSString *)verdict;// 类方法,字典 转 对象 类似javaBean一次性填充+ (Girl *)girlWithDict:(NSDictionary *)dict;// 对象方法,设置对象的属性后,返回对象- (Girl *)initWithDict:(NSDictionary *)dict;@end
Girl.m
//// Girl.m// 12_tableView的增删改//// Created by beyond on 14-7-27.// Copyright (c) 2014年 com.beyond. All rights reserved.//#import "Girl.h"@implementation Girl// 提供一个类方法,即构造函数,返回封装好数据的对象(返回id亦可)+(Girl *)girlNamed:(NSString *)name headImgName:(NSString *)headImgName verdict:(NSString *)verdict{ Girl *girl = [[Girl alloc]init]; girl.name = name; girl.headImgName = headImgName; girl.verdict = verdict; return girl;}// 类方法,字典 转 对象 类似javaBean一次性填充+ (Girl *)girlWithDict:(NSDictionary *)dict{ // 只是调用对象的initWithDict方法,之所以用self是为了对子类进行兼容 return [[self alloc]initWithDict:dict];}// 对象方法,设置对象的属性后,返回对象- (Girl *)initWithDict:(NSDictionary *)dict{ // 先调用父类NSObject的init方法 if (self = [super init]) { // 设置对象自己的属性 self.name = dict[@"name"] ; self.headImgName = dict[@"headImg"] ; self.verdict = dict[@"verdict"]; } // 返回填充好的对象 return self;}@end
BeyondViewController.h
//// BeyondViewController.h// 12_tableView的增删改//// Created by beyond on 14-7-27.// Copyright (c) 2014年 com.beyond. All rights reserved.//#import <UIKit/UIKit.h>@interface BeyondViewController : UIViewController// 标题@property (weak, nonatomic) IBOutlet UILabel *titleStatus;// tableView@property (weak, nonatomic) IBOutlet UITableView *tableView;// 清空按钮@property (weak, nonatomic) IBOutlet UIBarButtonItem *trashBtn;// 全选 反选按钮@property (weak, nonatomic) IBOutlet UIBarButtonItem *checkAllBtn;// 清空- (IBAction)trashBtnClick:(UIBarButtonItem *)sender;// 全选 or 反选- (IBAction)checkAll:(UIBarButtonItem *)sender;@end
BeyondViewController.m
//// BeyondViewController.m// 12_tableView的增删改//// Created by beyond on 14-7-27.// Copyright (c) 2014年 com.beyond. All rights reserved.//#import "BeyondViewController.h"#import "Girl.h"@interface BeyondViewController ()<UITableViewDataSource,UITableViewDelegate>{ // 从plist文件中加载的所有girls,返回字典数组 NSArray *_arrayWithDict; // 所有的对象数组 NSMutableArray *_girls; // 被勾选的行的对应该的模型数组 // 不用数组也行,只要在模型中增加一个属性:记录是否被选中 NSMutableArray *_checkedGirls;}@end@implementation BeyondViewController- (void)viewDidLoad{ [super viewDidLoad]; // 所有的对象数组 _girls = [NSMutableArray array]; // 被勾选的行的数组 _checkedGirls = [NSMutableArray array]; // 调用自定义方法,加载plist文件 [self loadPlist]; }// 自定义方法,加载plist文件- (void)loadPlist{ // sg_bundle模板代码,1,获得.app主要的包;2,返回主要的包中某个文件的fullPath全路径 NSBundle *mainBundle = [NSBundle mainBundle]; NSString *fullPath = [mainBundle pathForResource:@"girls.plist" ofType:nil]; // 从plist文件中根据全路径,返回字典数组 _arrayWithDict = [NSArray arrayWithContentsOfFile:fullPath]; // 再调用自定义方法,将字典数组,转换成对象数组 [self dictArrayToModel]; }// 自定义方法,将字典数组,转换成对象数组- (void)dictArrayToModel{ // 字典数组 _arrayWithDict // 方式1:for in,这种情况下,控制器知道的东西太多了,如果模型增加属性,还要改控制器中的代码 /* for (NSDictionary *dict in _arrayWithDict) { Girl *girl = [Girl girlNamed:dict[@"name"] headImgName:dict[@"headImg"] verdict:dict[@"verdict"]]; [_girls addObject:girl]; } */ // 方式2:类方法返回对象,参数只要一个字典数组即可 for (NSDictionary *dict in _arrayWithDict) { // 参数只要字典,这样一来,控制器就不用知道太多东西了 // Girl *girl = [[Girl alloc]initWithDict:dict]; Girl *girl = [Girl girlWithDict:dict]; [_girls addObject:girl]; }}// 数据源方法,默认是单组,共有多少行 (每次刷新数据都会调用此行)- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ // 返回数组中对应的字典的长度 return _girls.count;}// 数据源方法,每一组的每一行应该显示怎么的界面(含封装的数据),重点!!!必须实现否则,Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *cellID = @"Beyond"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; if (cell == nil) { // 如果池中没取到,则重新生成一个cell /* cell的4种样式: 1,default 左图右文字 2,subtitle 左图 上文字大 下文字小 3,value 1 左图 左文字大 右文字小 3,value 2 恶心 左文字小 右文字大 */ cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID]; } // 设置cell中独一无二的内容 Girl *girl = _girls[indexPath.row]; cell.textLabel.text = girl.name; cell.imageView.image = [UIImage imageNamed:girl.headImgName]; cell.detailTextLabel.text = girl.verdict; // 判断,如果模型存在于checkedArray中,则标记为checked if ([_checkedGirls containsObject:girl]) { cell.accessoryType = UITableViewCellAccessoryCheckmark; } else { cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; } // 返回cell return cell;}// 代理方法,每一行的高度- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 83;}// 代理方法,点击行,新版本 MVC- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ // 取消tableView点击后背景高亮的蓝色 [tableView deselectRowAtIndexPath:indexPath animated:YES]; // 获得被点击的行的对应的数据模型 Girl *girl = [_girls objectAtIndex:indexPath.row]; // 判断,若没被勾选过,则勾选,否则取消勾选 // 方式2:只修改模型,不动cell,让tableView reload数据即可,符合MVC~ if ([_checkedGirls containsObject:girl]) { // 取消勾选,从勾选数组中移除,然后再次reloadData [_checkedGirls removeObject:girl]; } else { // 加入到选中数组中,然后再次reloadData! [_checkedGirls addObject:girl]; } // 再次reloadData [_tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; // 最后调用自定义方法,检查trash按钮的可用性,以及标题的变化 [self statusCheck]; }// 代理方法,点击行----旧版本- (void)oldVersionTableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ // 取消tableView点击后背景高亮的蓝色 [tableView deselectRowAtIndexPath:indexPath animated:YES]; // 获得被点击的行 UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; // 获得被点击的行的对应的数据模型 Girl *girl = [_girls objectAtIndex:indexPath.row]; // 判断,若没被勾选过,则勾选,否则取消勾选 // 方式1:手动设置cell的样式,但是,这不符合MVC思想~ /* if (cell.accessoryType != UITableViewCellAccessoryCheckmark) { // 勾选上,同时要加入到数组中,记住! cell.accessoryType = UITableViewCellAccessoryCheckmark; [_checkedGirls addObject:girl]; } else { // 取消勾选,同时要移除 cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; [_checkedGirls removeObject:girl]; } */ // 方式2:只修改模型,不动cell,让tableView reload数据即可,符合MVC~ if (cell.accessoryType != UITableViewCellAccessoryCheckmark) { // 加入到选中数组中,然后再次reloadData! [_checkedGirls addObject:girl]; [_tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; } else { // 取消勾选,从勾选数组中移除,然后再次reloadData [_checkedGirls removeObject:girl]; [_tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; } // 最后调用自定义方法,检查trash按钮的可用性,以及标题的变化 [self statusCheck];}// 当点击了toolBar中的trash 按钮时调用- (IBAction)trashBtnClick:(UIBarButtonItem *)sender { // 可变数组,成员是所有的勾选的行组成的indexPath NSMutableArray *indexPaths = [NSMutableArray array]; // 遍历checkedGirls,得到勾选的行号们,并封装成一个个indexPath,然后添加到indexPaths数组,目的是后面tableView删除行方法中用到 for (Girl *girl in _checkedGirls) { // 勾选的行的行号 int row = [_girls indexOfObject:girl]; // 封装成IndexPath NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0]; // 添加到IndexPaths数组 [indexPaths addObject:indexPath]; } // 先修改模型(从所有的对象数组中删除 勾选的对象们,并且清空勾选的对象数组),最后再deleteRowsAtIndexPaths(注意reload前提是数据源个数不能增加或减少) [_girls removeObjectsInArray:_checkedGirls]; [_checkedGirls removeAllObjects]; // deleteRows删除行之后,剩余的行数,必须与数据源的行数相等,意思就是:数据源中也要删除同样多的行的数据,才可以调用deleteRows方法 [_tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationRight]; // 最后调用自定义方法,检查trash按钮的可用性,以及标题的变化 [self statusCheck];}// 最后调用自定义方法,检查trash按钮的可用性,以及标题的变化- (void)statusCheck{ // 如果表格没有数据了,则直接禁用掉全选按钮 if (_girls.count == 0) { _checkAllBtn.enabled = NO; } // 设置显示checked的行数 if (_checkedGirls.count != 0) { // 如果没有被选中的行,则禁用 删除按钮 _trashBtn.enabled = YES; // 显示数字(默认bar button item中的文本是不可更改的,所以改成label标签) NSString *titleStatus = [NSString stringWithFormat:@"红楼梦(%d)",_checkedGirls.count]; _titleStatus.text = titleStatus; } else { _trashBtn.enabled = NO; _titleStatus.text = @"红楼梦"; }}// toolBar最右边的 全选 or 反选按钮- (IBAction)checkAll:(UIBarButtonItem *)sender { if (_girls.count == _checkedGirls.count) { // 取消全选 先修改模型,再reload [_checkedGirls removeAllObjects]; [_tableView reloadData]; } else { // 全选 先修改模型,再reload // 必须先清空checked数组,再全部添加 [_checkedGirls removeAllObjects]; [_checkedGirls addObjectsFromArray:_girls]; [_tableView reloadData]; } // 调用自定义方法 修改检测状态 [self statusCheck]; }@end
属性列表文件girls.plist
main.storyboard
因为bar button item的文字不可更改, 遂换成label,
label不接收点击事件,所以可以向后传递给button处理点击事件
1 0
- iOS_12_tableViewCell的删除更新_红楼梦
- iOS_13_tableView的编辑模式_红楼梦
- lucene索引_创建_域选项和lucene索引_的删除、更新.
- JPA加载_删除_更新对象
- 永远的红楼梦
- 红楼梦命名的艺术
- 《红楼梦》的方位观念
- 《红楼梦》的香文化
- 《红楼梦》的香气空白
- 《红楼梦》的香气韵调
- 红楼梦
- 红楼梦
- 红楼梦
- 红楼梦
- 数据库__SQL的主键和外键约束_级联更新_级联删除
- 新版《红楼梦》的问题在哪儿?
- 红楼梦描写眼睛的词
- 你不知道的红楼梦
- fedora 20(64位)虚拟机磁盘容量扩展
- dedecms安装,dedecms教程,dedecms安装教程,80端口屏蔽动态IP无公网IP发布外网
- 地图的加载
- 1407281127-hd-Rock, Paper, or Scissors.cpp
- hdu 2164 石头剪刀布
- iOS_12_tableViewCell的删除更新_红楼梦
- TOMCAT 连接池数据库密码可以加密
- 机器学习的最佳学习资源
- Unofficial Windows Binaries for Python Extension Packages
- 地图的滚动(根据触摸点)
- IOS 应用程序国际化
- ppt转换成pdf转换器免费
- svn命令之冲突解决
- .net 导出excel数据