一 UITabelView 编辑
1.UItableView的编辑包括 cell 的添加和删除
2.使用场景:
1>删除一个下载好的视频,删除联系人
2>插入一条新的聊天记录
1. UITabelView 编辑的步骤:
1> 让 tableView 处于编辑状态(使用 TableView方法)
首先需要在给 tableView添加 cell 的时候,给导航条的右边添加编辑按钮self.navigationItem.rightBarButtonItem = self.editButtonItem;
接着实现 TableView的方法:
-(void)setEditing: (BOOL)editing animated: (BOOL)animated;
2> 指定 tableView 哪些行可以编辑(TableView DataSource 方法)
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath: (NSIndexPath *)indexPath;
3> 指定 tableView 编辑的样式(添加,删除)(TableView Delegate方法)
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;
4> 编辑完成(先操作数据源,再修改 UI)( TableView DataSource 方法)
-(void)tableView:(UITableView *)tableView commitEditingStyle:
(UITableViewCellEditingStyle)editingStyleforRowAtIndexPath: (NSIndexPath *)indexPath;
2. UITableView 的移动
1> 让 tableView 处于编辑状态(TableView方法)(参见 UITableView编辑步骤一)
2> 指定 tableView哪些行可以移动(TableViewDatasource 方法)
- (BOOL)tableView: (UITableView*)tableView canMoveRowAtIndexPath:
(NSIndexPath*)indexPath;
3> 移动完成(TableViewDatasource 方法)
-(void)tableView:(UITableView *)tableView moveRowAtIndexPath: (NSIndexPath *)sourceIndexPathtoIndexPath: (NSIndexPath *)destinationIndexPath;
4> 检测移动过程中,实现限制区移动
-(NSIndexPath *)tableView: (UITableView *)tableViewtargetIndexPathForMoveFromRowAtIndexPath: (NSIndexPath*)sourceIndexPathtoProposedIndexPath: (NSIndexPath *)proposedDestinationIndexPath;
3. UITableViewController控件(很牛逼的一个控件)
1> UITableViewController 继承自 UIViewController, 自带一个 tableView
2> self.view不是 UIView, 而是 UITableView
3> datasource 和 delegate 默认都是 self(UITableViewController)
4> 开发中只需要建立 UITableViewController 子类
5> UITableViewController 是封装好了各种 delegate 和 datasouce, 能提高开发速度.
4. 将 tableView指定为 self.view 的根视图
使用视图控制器中的加载视图的方法:
-(void)loadView{
self.tableView= [[UITableView alloc]initWithFrame:[UIScreen mainScreen]
.bounds];
self.view= self.tableView;
[self.tableViewrelease];
}
5. 设置UINavigationController导航条的外观
self.navigationController.navigationBar.barTintColor= [UIColor greenColor];
self.navigationItem.title= @”通讯录”;
6. 从**.plist 文件中获取数据
1> 获取路径
NSString*filePath = [[NSBundle mainBundle]pathForResource: @”Contacts” ofType: @”plist”];
2> 根据文件路径获取数据(存方到数组中)
self.dic = [NSMutableDictionary dictionaryWithContentsOfFile:filePath];
3> 再对字典进行操作,取出里面的数据.(见下面代码)
7. 数据源配置中的主要方法(前两个是必须实现的方法)
1>设置分区中的行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section{
return1;
};
2>为 tableView 添加 cell 和数据
- (UITableViewCell*)tableView: (UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath*)IndexPath;
3>每个分区的行数(返回每个分区的行数,也可以根据获得数据的个数进行计算)
-(NSInteger)numberOfSectionInTableView:(UITableView *)tableView;
4>给每一个分区设置页眉
- (NSString*)tableView: (UItableView *)tableView titleForHeaderInSection:(NSInteger)section;
5>设置右边的索引
- (NSArray*)sectionIndexTitleForTableView: (UITableView *)tableView;
11.代理中的常用的方法
1>点击的时候触发
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath;
12.UITableView编辑操作的主要方法
编辑操作的前提:(设置编辑按钮)
self.navigationItem.rightBarButtonItem =self.editButtonItem;
1>设置 cell 处于编辑状态
- (void)setEditing:(BOOL)editing animated: (BOOL)animated{
[super setEditing:editinganimated:animated]; 初始化父类
[self.tableView setEditing:editinganimated]; 让tableView 进入编辑状态,editing :YES/NO
}
2>设置哪一行可以进行编辑
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath: (NSIndexPath *)indexPath{
return indexPath.section <10 ? YES :NO;
}
3>设置 tableView 的编辑样式
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath: (NSIndexPath*)indexPath;
4>编辑完成
具体见代码.
RootViewController.m 文件#import "RootViewController.h"
#import "UIImage+Scale.h"
#import "DeatilViewController.h"
#import "DealiView.h"
@interface RootViewController ()
@property (nonatomic,retain) UITableView *tableView;
@property (nonatomic,retain) NSMutableDictionary *dic;
@property (nonatomic,retain) NSMutableArray *sortKeys;
@end
@implementation RootViewController
- (void)dealloc{
[_tableView release];
[_sortKeys release];
[_dic release];
[super dealloc];
}
// 将 self.tableView 设置为 self.view 的根视图
- (void)loadView{
self.tableView = [[UITableView alloc]initWithFrame:[UIScreen mainScreen].bounds];
self.view = self.tableView;
[self.tableView release];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
// 设置数据源代理
self.tableView.dataSource = self;
// 设置业务代理
self.tableView.delegate = self;
// 设置导航条外观
[self setNavigationAprefence];
// 读取**. plist 文件
[self readDataFromPlist];
}
// 设置导航条外观
- (void)setNavigationAprefence{
// 设置导航条的颜色为绿色
self.navigationController.navigationBar.barTintColor = [UIColor greenColor];
// 设置导航条的标题
self.navigationItem.title = @"通讯录";
}
// 读取 Contacts 文件的数据
- (void)readDataFromPlist{
// 1.获取路径
NSString *filePath = [[NSBundle mainBundle]pathForResource:@"Contacts" ofType:@"plist"];
// 2.根据文件路径取出数据并初始化
self.dic = [NSMutableDictionary dictionaryWithContentsOfFile:filePath];
#warning 对字典的操作
// 对存储的数据进行操作,以便于后面对数组中数据的修改
// 目的是将字典中的不可变数组 变为可变数组 方便后面的删除
// 1. 拷贝出一份字典的副本(原因是可变集合是不能在快速枚举的时候被修改的)
NSMutableDictionary *copDic = [NSMutableDictionary dictionaryWithDictionary:self.dic];
// 2. 快速枚举,使用拷贝的副本进行快速枚举
for (NSString *key in copDic) {
// 3.使用 key 值,取出字典中所有不可变数组
NSArray *group = [self.dic valueForKey:key];
// 4.拿不可变数组初始化可变数组
NSMutableArray *groupMul = [NSMutableArray arrayWithArray:group];
// 5.重新为 key 值对应的 value 赋值
[self.dic setValue:groupMul forKey:key];
}
// 6.取出 key 值并进行排序
NSArray *orderArray = [[self.dic allKeys] sortedArrayUsingSelector:@selector(compare:)];
// 7.获取所有的 key 值
self.sortKeys = [NSMutableArray arrayWithArray:orderArray];
}
#pragma mark ---------实现数据源中的方法----------
// 设置分区中的行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
// 1.根据分区下标获取对应的 key 值
NSString *key = self.sortKeys[section];
// 2.获取 key值对应 value 值的个数
return [self.dic[key] count];
}
// 添加 cell数据
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// 1.设置重用池标记
static NSString *indentifier = @"cell";
// 2.到重用池中取 cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:indentifier];
// 3.重用池为空的时候,创建 cell
if (!cell) {
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:indentifier]autorelease];
}
#warning 从字典中获取数据
// 1.根据 seciton 取出对应的 key 值
NSString *key = self.sortKeys[indexPath.section];
// 2.取出key 值对应的 value 值
NSArray *tempArray =self.dic[key];
// 3.根据 row取出数组中对应的元素
NSMutableDictionary *tempDic = tempArray[indexPath.row];
// 4.为 cell 赋值
cell.textLabel.text = tempDic[@"name"];
cell.detailTextLabel.text = tempDic[@"phone"];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.imageView.image = [[UIImage imageNamed:tempDic[@"imageName"]]scaleToSize:CGSizeMake(40, 40)];
// 在导航条的右边添加编辑按钮
self.navigationItem.rightBarButtonItem = self.editButtonItem;
return cell;
}
#pragma mark ----------UITableView 编辑操作--------------
// 1.设置 cell 处于编辑状态
- (void)setEditing:(BOOL)editing animated:(BOOL)animated{
// 初始化父类
[super setEditing:editing animated:animated];
// 让 tableView进入编辑状态, editing: YES/NO
[self.tableView setEditing:editing animated:animated];
}
// 2.设置那几行可以进行编辑
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return indexPath.section < 10 ? YES : NO;
}
// 3.设置 tableView编辑样式
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.section == 1) {
return UITableViewCellEditingStyleInsert;
}
return UITableViewCellEditingStyleDelete;
}
// 4.编辑完成
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
// 删除
// 1>获取对应行所在的分区的 key 值
NSString *key = self.sortKeys[indexPath.section];
// 2>根据 key 值获取对应的 value 值(并存储在数组中)
NSMutableArray *group = self.dic[key];
// 判断编辑样式
if (editingStyle == UITableViewCellEditingStyleDelete) { //处理删除操作,需要判断是否删除整个分区
if ([group count] == 1) {
// ①修改数据源,从字典中移除对应的key 值
[self.dic removeObjectForKey:key];
// ②删除右边索引数组的 key 值
[self.sortKeys removeObject:key];
// ③修改界面
// 创建 NSIndexSet 的数据
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:indexPath.section];
[tableView deleteSections:indexSet withRowAnimation:UITableViewRowAnimationLeft]; }
else{// 分区中有多个 cell 的情况
// 1>修改数据源,删除数组中对应下标的元素
[group removeObjectAtIndex:indexPath.row];
// 2>更新界面
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:(UITableViewRowAnimationRight)];
}
}else{ // 插入操作
// 1.设置数据源
NSDictionary *dic = @{@"name":@"钢蛋",@"gender":@"男",@"age":@"18",@"phone":@"110",@"imageName":@"0",@"says":@""};
// 向数组中插入数据
[group insertObject:dic atIndex:indexPath.row];
// 2.修改界面
[tableView insertRowsAtIndexPaths:@[indexPath]withRowAnimation:UITableViewRowAnimationRight];
}
}
#pragma mark ---------UITableView移动--------
// 1.设置哪些行可以移动
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
// 2.移动完成
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
// 因为 UI界面已经发生变化了,所以我们只需修改数据源就可以
// 1>获取分区对应的数组
NSMutableArray *group = self.dic[self.sortKeys[sourceIndexPath.section]];
// 2>将原来对应元素取出来
NSDictionary *dic = [group[sourceIndexPath.row] retain]; // retain引起计数器加一,如果不 retain, 当你在删除对应元素的时候,会造成操作元素的引用计数器为0,空间会被回收,下面将无法重用
// 3>将原来对应的元素删除
[group removeObjectAtIndex:sourceIndexPath.row];
// 4>将保存的元素插入到目的位置
[group insertObject:dic atIndex:destinationIndexPath.row];
}
// 3.检测移动过程,实现限制跨区移动(当拖动停止的时候触发,限制 cell 的跨区移动)
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath{
if (sourceIndexPath.section == proposedDestinationIndexPath.section) {
return proposedDestinationIndexPath;
}
return sourceIndexPath;
}
// 每个分区的行数
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return self.dic.count;
}
// 设置页眉
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
return self.sortKeys[section];
}
// 设置右边索引
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
return self.sortKeys;
}
#pragma mark ----------实现代理中的方法------------
// 点击 cell 的时候触发
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
DeatilViewController *rootVC = [[DeatilViewController alloc]init];
// 1.找到 key 值
NSString *key = self.sortKeys[indexPath.section];
// 2.取出 value 值
NSMutableArray *group = self.dic[key];
// 3.取出数组中的值
NSDictionary *dic = group[indexPath.row];
// 4. 为创建的属性赋值
rootVC.dic = dic;
[self.navigationController pushViewController:rootVC animated:YES];
[rootVC release];
}
// cell 编辑状态时,设置删除按钮的 title 标签
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath{
return @"删除";
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end
DeatilViewController.h 文件
#import
@interface DeatilViewController : UIViewController
@property (nonatomic,retain) NSDictionary *dic;
@end
DeatilViewController.m
//
// DeatilViewController.m
// HomeWork7-14
//
// Created by lanouhn on 15/7/14.
// Copyright (c) 2015年 lanouhn. All rights reserved.
//
#import "DeatilViewController.h"
#import "DealiView.h"
#import "UIImage+Scale.h"
@interface DeatilViewController ()
@property (nonatomic,retain) DealiView *deatilView;
@end
@implementation DeatilViewController
- (void)dealloc{
[_dic release];
[ _deatilView release];
[super dealloc];
}
- (void)loadView{
self.deatilView = [[DealiView alloc]initWithFrame:[UIScreen mainScreen].bounds];
self.view = self.deatilView;
[self.deatilView release];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor grayColor];
[self setData];
}
- (void)setData{
self.deatilView.imageView.image = [[UIImage imageNamed:self.dic[@"imageName"]]scaleToSize:CGSizeMake(120, 120)];
self.deatilView.nameLable.text = self.dic[@"name"];
self.deatilView.genderLable.text = self.dic[@"gender"];
self.deatilView.ageLage.text = self.dic[@"age"];
self.deatilView.phoneLable.text = self.dic[@"phone"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end
DealiView.h文件
#import
@interface DealiView : UIView
@property (nonatomic,retain) UIImageView *imageView;
@property (nonatomic,retain) UILabel *nameLable,*genderLable,*ageLage,*phoneLable;
@end
DealiView.m 文件
#import "DealiView.h"
@implementation DealiView
- (void)dealloc{
[_imageView release];
[_ageLage release];
[_phoneLable release];
[_nameLable release];
[_ageLage release];
[super dealloc];
}
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self set_Up];
}
return self;
}
- (void)set_Up{
self.imageView = [[UIImageView alloc]initWithFrame:CGRectMake(20, 84, 120, 120)];
self.imageView.backgroundColor = [UIColor whiteColor];
[self addSubview:self.imageView];
[self.imageView release];
self.nameLable = [[UILabel alloc]initWithFrame:CGRectMake(180, 84, 120, 30)];
self.nameLable.backgroundColor = [UIColor whiteColor];
[self addSubview:self.nameLable];
[self.nameLable release];
self.genderLable = [[UILabel alloc]initWithFrame:CGRectMake(180, 129, 120, 30)];
self.genderLable.backgroundColor = [UIColor whiteColor];
[self addSubview:self.genderLable];
[self.genderLable release];
self.ageLage = [[UILabel alloc]initWithFrame:CGRectMake(180, 174, 120, 30)];
self.ageLage.backgroundColor = [UIColor whiteColor];
[self addSubview:self.ageLage];
[self.ageLage release];
self.phoneLable = [[UILabel alloc]initWithFrame:CGRectMake(20, 224, 280, 40)];
self.phoneLable.backgroundColor =[UIColor whiteColor];
[self addSubview:self.phoneLable];
[self.phoneLable release];
}
// self.ageLage = [[UILabel alloc]initWithFrame:CGRectMake(CGRectGetMinX(self.nameLable.frame),(CGRectGetMaxY(self.genderLable.frame) + 20),CGRectGetWidth(self.nameLable.frame),CGRectGetHeight(self.nameLable.frame)}];
// self.ageLage.backgroundColor = [UIColor whiteColor];
// [self addSubview:self.ageLage];
// [self.ageLage release];
@end
UIImage+Scale.h
#import
@interface UIImage (Scale)
- (UIImage *)scaleToSize:(CGSize)size;
@end
UIImage+Scale.m 文件
#import "UIImage+Scale.h"
@implementation UIImage (Scale)
- (UIImage *)scaleToSize:(CGSize)size{
// 1.创建一个 bitmap 的 context,并把 context 设置为当前正在使用的环境
UIGraphicsBeginImageContext(size);
// 2.绘制改变大小的图片
[self drawInRect:CGRectMake(0, 0, size.width, size.height)];
// 3.从当前的 context 中创建一个改变大小后的图片
UIImage *scaleImage = UIGraphicsGetImageFromCurrentImageContext();
// 4.使用当前的 context 的出栈
UIGraphicsEndImageContext();
// 5.返回改变大小的图片
return scaleImage;
}
@end
-(void)dealloc{
[_window release];
[super dealloc];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
RootViewController *rootVC = [[RootViewController alloc]init];
UINavigationController *rootNC = [[UINavigationController alloc]initWithRootViewController:rootVC];
self.window.rootViewController = rootNC;
[rootNC release];
[rootVC release];
return YES;
}