UITableView --- 通讯录demo1

准备工作:

创建一个工程

Model:

载有数据的 Person.plist 文件(里面包含了通讯录的所有内容,包括姓名 ,电话号码,头像等)

Person 类

把装有 头像图片的文件夹 拖入到工程中

-------------------------------------------------------------------------------------------------------------------------------

主要代码:

ContactView.h

#import <UIKit/UIKit.h>

@interface ContactView : UIView

@property(nonatomic,strong)UITableView *mainTableView;

@end


ContactView.m

#import "ContactView.h"

@implementation ContactView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self createMainTableView];
    }
    return self;
}

-(void)createMainTableView{
    
    //UITableViewStyleGrouped 分组有头部和尾部
    //UITableViewStylePlain 无分组,可加
    self.mainTableView = [[UITableView alloc]initWithFrame:[UIScreen mainScreen].bounds style:UITableViewStylePlain];
    
    [self addSubview:self.mainTableView];
    
    
    
}
@end


对应的控制器

ContactViewController.m

//
//  ContactViewController.m
//  UI10_lesson1
//
//  Created by lanou3g on 15/11/4.
//  Copyright (c) 2015年 lirui. All rights reserved.
//

#import "ContactViewController.h"
#import "ContactView.h"
#import "Person.h"
#import "DetailViewController.h"



@interface ContactViewController ()<UITableViewDataSource,UITableViewDelegate>
//创建根视图
@property(nonatomic,strong)ContactView *rootView;
//创建字典,存储联系人
@property(nonatomic,strong)NSMutableDictionary *contactDict;
//定义数组,专门用来存放分组名(A,B,C...)
@property(nonatomic,strong)NSMutableArray *groupNameArray;
@end

@implementation ContactViewController

//懒加载 字典
-(NSMutableDictionary *)contactDict{
    
    if (_contactDict == nil) {
        _contactDict = [NSMutableDictionary dictionary];
    }
    return _contactDict;
}
//懒加载 数组
-(NSMutableArray *)groupNameArray{
    
    if (_groupNameArray == nil) {
        _groupNameArray = [NSMutableArray array];
    }
    return _groupNameArray;
}




-(void)loadView{
    
    self.rootView = [[ContactView alloc]initWithFrame:[UIScreen mainScreen].bounds];
    self.view = self.rootView;
    
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.title = @"通讯录";
    
    //plist 文件路径
    NSString *path = [[NSBundle mainBundle]pathForResource:@"Person" ofType:@"plist"];
    //取出 plist 文件整体的内容
    NSDictionary *sumDict = [NSDictionary dictionaryWithContentsOfFile:path];
    
    //循环遍历 sumDict (相当于遍历分组名)
    for (NSString *key in sumDict) {
        //拿出分组所在的数组(存储的是一组联系人)
        NSArray *valueArray = [sumDict objectForKey:key];
        //把分组名存储起来(groupNameArray)
        [self.groupNameArray addObject:key];
        //创建可变数组,用来存储联系人模型
        NSMutableArray *array = [NSMutableArray array];
        
        //遍历 valueArray(遍历一个分组联系人)
        for (NSDictionary *dict in valueArray) {
            //创建对应的模型,并且使用 KVC 赋值
            Person *p = [[Person alloc]init];
            [p setValuesForKeysWithDictionary:dict];
            //把模型存入对应的可变数组
            [array addObject:p];
        }
        
        //把上面创建的 可变数组 存入 ContactDict;
        [self.contactDict setObject:array forKey:key];
    }
    
    //给 groupNameArray 进行排序(仅限数组存的是 字符串)
    [self.groupNameArray sortUsingSelector:@selector(compare:)];

    
    //设置 mainTableView 的代理
    self.rootView.mainTableView.dataSource = self;
    self.rootView.mainTableView.delegate = self;
    
    UIBarButtonItem *rightButton = [[UIBarButtonItem alloc]initWithTitle:@"编辑" style:UIBarButtonItemStylePlain target:self action:@selector(rightButtonDidClicked:)];
    self.navigationItem.rightBarButtonItem = rightButton;
    
}
#pragma mark 导航栏右侧按钮的编辑事件
-(void)rightButtonDidClicked:(UIBarButtonItem *)sender {
    
    if ([sender.title isEqualToString:@"编辑"]) {
        //让  mainTableView 进入编辑状态
        [self.rootView.mainTableView setEditing:YES animated:YES];
        sender.title = @"完成";
    } else {
        // 结束编辑状态
        [self.rootView.mainTableView setEditing:NO animated:YES];
        sender.title = @"编辑";
    }
    
}




#pragma mark 返回多少个分组
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    
    return self.groupNameArray.count;
}

#pragma mark 每个分组返回多少行

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
    //取出 key 值 (分组名)
    NSString *key = self.groupNameArray[section];
    NSArray *groupArray = self.contactDict[key];
    return groupArray.count;
    
}
#pragma mark 每行显示的内容(cell 上面的内容)
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    //cell 的重用机制
   
    static NSString *cell_id = @"flag"; //(static 只创建一次)
    //先到重用池里找可用的 cell (flag 标示符必须一样)
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cell_id];
    //如果找不到,重新创建
    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cell_id];
    }
    // cell 的下一级菜单指示
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    // 可以 自定义 : 添加到 cell.accessoryView
    
    
    
    
    
    
    //赋值操作
    NSString *key = self.groupNameArray[indexPath.section];
    NSArray *valuesArray = self.contactDict[key];
    Person *p = valuesArray[indexPath.row];
    
    cell.textLabel.text = p.name;
    cell.detailTextLabel.text = p.phoneNumber;
    cell.imageView.image = [UIImage imageNamed:p.picture];
    
    return cell;
}

#pragma mark 返回cell的高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    return 50.0f;
}

#pragma mark 设置分组头部的 title
//-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
//    
//    return self.groupNameArray[section];
//}

#pragma mark 自定义 tableView 分区头部
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    
    UIView *headerView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 30)];
    UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"NavBar_64@2x.jpg"]];
    imageView.frame = headerView.bounds;
    //把图片添加到 headerView
    [headerView addSubview:imageView];
    
    UILabel *label = [[UILabel alloc]initWithFrame:headerView.bounds];
    label.text = self.groupNameArray[section];
    
    label.textAlignment = NSTextAlignmentCenter; //居中
    [headerView addSubview:label];
    
    
    
    return headerView;
    
}







#pragma mark 设置分区头部的高度
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    
    return 30.0f;
}
#pragma mark 以下是关于 tableView 设置尾部的方法(只是为了看看效果,太丑了,就注释了)
/* ------
#pragma mark 设置尾部的高度
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    
    return 20;
}
#pragma mark 尾部的 title
-(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
    
    return @"玩完了";
}

#pragma mark 自定义尾部
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
    
    return nil;
}
  ------------------------- */

#pragma mark  tableView 索引
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    
    return self.groupNameArray;
}

#pragma mark tableView cell 的点击方法
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
    //细节处理:取消 cell 的选中状态
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    
    
    //跳转到详情页面
    DetailViewController *detailVC = [[DetailViewController alloc]init];
    
    //通过属性传值过程
    NSString *key = self.groupNameArray[indexPath.section];
    NSArray *personArray = self.contactDict[key];
    detailVC.receivePerson = personArray[indexPath.row];
    

    [self.navigationController pushViewController:detailVC animated:YES];
}


//以下 3个方法 一起使用
#pragma mark 通知 tableView 哪些行可以进行编辑(添加和删除)
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    
    return YES;
}

#pragma mark 指定编辑的类型(删除还是添加)
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    if (indexPath.section == 0) {
        return UITableViewCellEditingStyleDelete;//删除
    }else {
        return UITableViewCellEditingStyleInsert;//添加
    }
}

#pragma mark 提交编辑结果
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        
        //1.必须首先修改数据源
        NSString *key = self.groupNameArray[indexPath.section];
        NSMutableArray *mutableArray = self.contactDict[key];
        //根据下标 删除数组里面对应的模型
        [mutableArray removeObjectAtIndex:indexPath.row];
        
        //如果 分组里面元素个数 小于1 (没有其他联系人了),需要删除整个分组
        if (mutableArray.count < 1) {
            [self.contactDict removeObjectForKey:key];
            [self.groupNameArray removeObject:key];
            
        }
        
        //2.修改UI
        // 方式① ---- reloadData 直接刷新数据
        //    [tableView reloadData];
        //方式②
        if (mutableArray.count < 1) {
            //删除整个分组
            NSIndexSet *deleteIndexSet = [NSIndexSet indexSetWithIndex:indexPath.section];
            [tableView deleteSections:deleteIndexSet withRowAnimation:UITableViewRowAnimationAutomatic];
            
        } else {
            //删除某一行
            [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
            
        }
    
        
    } else {
        //添加联系人
        Person *insertPerson = [[Person alloc]init];
        insertPerson.name = @"测试添加";
        insertPerson.phoneNumber = @"13011777838";
        
        //1.修改数据源
        //分组名
        NSString *key = self.groupNameArray[indexPath.section];
        NSMutableArray *personArray = self.contactDict[key];
        
        //给数组插入一个元素
        [personArray insertObject:insertPerson atIndex:indexPath.row + 1];
        
        //2.修改 UI
        //方式①
//        [tableView reloadData];
        
        //方法②
        //构造一个新的 indexPath
        NSIndexPath *insertIndexPath = [NSIndexPath indexPathForRow:indexPath.row + 1 inSection:indexPath.section];
        
        [tableView insertRowsAtIndexPaths:@[insertIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
        
    
        
    }
    

    
}

#pragma mark 修改滑动删除时候的显示字样,默认是 Delete
-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    return @"删除";
}






- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

其中重点部分有:1. plist文件的解析过程

                             2.cell 的重用机制

设置代理后,代理方法的使用也要熟练掌握。



点击 导航栏 右侧的 编辑按钮


左滑进行删除


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值