美文网首页项目开发技巧
iOS树形结构的通讯录实现

iOS树形结构的通讯录实现

作者: bmydong | 来源:发表于2016-05-20 17:13 被阅读725次

    介绍

    需求来自之前做过的一个项目,要求做一个多级部门的通讯录,每一级可能包含下级部门和员工;服务端返回部门和员工数组,以一个标志位做区分;要求按照拼音(即展示所有人员)和按照部门两种方式展示。

    我的思路

    我们的整个架构按照MVC模式,界面的实现比较简单,暂时跳过不谈,这里谈谈M的实现(其中涉及到了数据库操作,这里也略过不谈)。

    1.我们把公司的整个架构看作一棵树,树的节点即某层次下的部门跟成员的合集。点击到任一部门,即得到该节点的成员。

    2.由于有个计数的需求,也为了减少计算,对节点的数据做了一个扩充,增加了成员的数目这个字段,在构建树的时候即得到该节点下的成员数目。

    具体实现

    几个对象:EmployeeInfo 员工信息类

    EmployeesList 员工列表(包含部门、员工)

    ContactDBManager 数据库管理类(暂时不讲)

    PinyinStructureNode 拼音树节点

    PinyinStructure 拼音结构树

    CompanyStructureNode 组织关系树节点

    CompanyStructure 组织关系树

    下面对每一个结构做介绍

    EmployeeInfo 员工信息类

    //员工信息
    @interface EmployeeInfo : NSObject
    @property (nonatomic, assign) NSInteger type;//0:员工;1:部门
    @property(nonatomic,copy) NSString *name;
    @property(nonatomic,copy) NSString *ID;
    @property(nonatomic,copy)NSString *parentName;//type=0员工所在部门名称   type=1上级部门名称
    @property(nonatomic,copy)NSString *parentId;//type=0员工所在部门ID   type=1上级部门ID
    @property(nonatomic,copy)NSString *mobilePhone;//移动电话
    //下面增加了字段,为了便于构造不同的树节点
    @property(nonatomic,copy) NSString *namePinyin;//名字拼音
    @property(nonatomic,copy) NSString *namePinyinPre;//名字拼音首字母(比方说:张三-》zs)
    @property(nonatomic,copy) NSString *namePinyinFirstAlpha;//姓首字母(张三-》z)
    @property(nonatomic,assign)NSInteger countOfPerson;//人员计数
    
    - (instancetype)initWithInfo:(NSDictionary *)info;
    + (instancetype)employeeInfoWithWithDictionary:(NSDictionary *)dic;
    
    @end
    

    员工信息,这里我们把员工跟部门都当做员工信息,无非是类型不一样,服务端返回员工信息(type:0 员工 1 部门)

    增加几个字段,具体实现无非是解析,增加字段,根据type,countOfPerson初始值设为0(部门)或者1(员工)。

    PinyinStructureNode 拼音节点类

    //拼音节点
    
    @interface PinyinStructureNode : NSObject
    
    @property(nonatomic,strong) NSString *alphaKey;//字母
    
    @property(nonatomic,strong)NSMutableArray *persons;//成员数组
    
    -(instancetype)initNodeWithPerson:(EmployeeInfo*)info;
    -(void)addPerson:(EmployeeInfo*)info;
    
    @end
    

    这个实现比较简单,alphaKey代表成员姓的拼音首字母。

    只有两个接口:构造,往节点增加成员。

    PinyinStructure 拼音结构树

    @interface PinyinStructure : NSObject
    
    @property(nonatomic,strong) NSMutableDictionary *alphaIndexDic;
    //所有分组
    @property(nonatomic,strong)NSMutableArray *groups;
    
    -(instancetype)initPinyinStructureWithPersonList:(NSMutableArray*)personList;
    @end
    

    这个实现比较简单,对通讯录做一个遍历,获得成员的拼音首字母,判断是否在分组字典alphaIndexDic 里面。在,则找到对应节点,往节点增加成员;不在,则构建对应的拼音节点PinyinStructureNode ,在alphaIndexDicgroups 增加成员。

    CompanyStructureNode 组织关系树节点

    @interface CompanyStructureNode : NSObject
    @property(nonatomic,strong) NSString *ID;
    //两个数组:一个数组记录所有的子部门,一个数组记录下级所有的人
    @property(nonatomic,strong)NSMutableArray *departmens;
    @property(nonatomic,strong)NSMutableArray *persons;
    
    -(instancetype)initNodeWithEmployeeInfo:(EmployeeInfo*)info fromDepList:(NSMutableArray*)depList andPersonList:(NSMutableArray*)personList;
    
    -(instancetype)initNodeWithId:(NSString*)Id fromDepList:(NSMutableArray*)depList andPersonList:(NSMutableArray*)personList;
    //某节点人员个数
    -(NSInteger)personNumberOfNode;
    @end
    

    为了避免反复去算人数,这直接在存数据库到时候计算了某节点下的人数,而不是反复递归。

    提供了三个接口:通过员工信息构造节点、通过ID构造节点、获得节点下所有员工数量。具体实现,无非就是遍历,遍历部门数组跟员工数组即可获得该级别下的所有部门和成员。

    CompanyStructure 组织关系树

    @interface CompanyStructure : NSObject
    @property(nonatomic,strong)NSMutableArray *allDepartments;
    @property(nonatomic,strong)NSMutableArray *allPersonInfo;
    //辅助数组,用来计算某ID下面所有的人
    @property(nonatomic,strong)NSMutableArray *subPersonsInfos;
    
    -(instancetype)initStructureWithInfoList:(NSArray*)infoList;
    //某节点下的人
    -(NSArray*)personsUnderId:(NSString*)Id employeeType:(EmployeeType)type;
    -(NSArray*)searchWithKeyword:(NSString*)keyword;
    @end
    

    这个结构相对会复杂一点,从解析到实现一步一步来讲可能会比较清楚。

    1. 服务端获得数据,解析生成EmployeeInfo 员工信息,生成员工信息列表

    2. 遍历员工信息列表,往部门数组allDepartments和员工数组增加成员allPersonInfo

    3. 遍历员工数组,每获得一个员工,就更新其部门的人员计数,直到树的根节点。

      这样,各部门的人员计数就获得了。

    4. 这样,要获得某层级的信息,无非调用CompanyStructureNode 的构造方法。

      到此,整个树形结构的通讯录树就完成了。

    相关文章

      网友评论

      • MonkeyLu:博主问一下:我现在的树形结构数据源需要在点击 cell 的时候才能获取下一级的数据,而且接口没有返回父级的 id 。现在能够展开,但是关闭的时候会错乱。有好的解决办法吗?谢谢
        bmydong:你不觉得你的数据结构比较简单么,而且,你那个更多属于UI层的东西,树形结构的tableView github上很多的
      • BSimmons:g_kai1120@126.com 邮箱 如果有demo可以发我邮箱吗
        bmydong:没有demo
      • BSimmons:现在在做 还是没有思路
      • BSimmons:有demo吗

      本文标题:iOS树形结构的通讯录实现

      本文链接:https://www.haomeiwen.com/subject/gwunrttx.html