iOS UItableView通讯录(分组显示)

来源:互联网 发布:视频图片拼接软件 编辑:程序博客网 时间:2024/05/22 09:26

 

制作通讯录听起来很麻烦但是其有一个套路,明白了这一个套路,以后制作类似的东东就有思路了,什么套路呢?
通讯录(分组显示)---ios
这是做成的基本效果
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1.建一个新的ViewController,添加一个UITableView
    self.studentTable=[[UITableView alloc]initWithFrame:CGRectMake(0,0,320,460-44)style:UITableViewStyleGrouped];//TableView初始化   style:UITableViewStylePlain(不分组的), UITableViewStyleGrouped(分组的)
   
    self.studentTable.delegate=self;//设置代理
    self.studentTable.dataSource=self;//设置数据源
    [self.view addSubview:self.studentTable];//添加到视图
2.建几个必要的数组字典集合
    self.tempA=[[NSMutableArray alloc]init];//将所有学生通过中文排序后的数组(存储的均为Student*对象)
   
    self.xingset=[[NSMutableSet alloc]init];//存所有同学的姓(去重)
   
    self.xingarray=[[NSMutableArray alloc]init];//将不重复的姓从集合转为数组(便于操作)
   
    self.studic=[[NSMutableDictionary alloc]init];//万能的学生字典
   
    NSMutableArray *arr=[[NSMutableArray alloc]init];//将所有学生通过中文排序后的数组(存储的均为ChineseString对象)
   
    self.keyarray=[[NSMutableArray alloc]init];//key

3.通过arr=[ZhonWenPaiXu zhongWenPaiXu:[Student findall]];//将数据库的数据检索出来(Student*)返回的是(ChineseString*)
***注意这里的中文排序方法默认是牌纯姓名的数组但是这里的数组是(Student*)对象所以要对中文排序的方法改一下
***注意我在ChineseString类中加了一个属性Nsstring*xing来存学生的姓
*************
+(NSMutableArray *)zhongWenPaiXu:(NSMutableArray *)newArray;
+(NSMutableArray *)zhongWenPaiXu:(NSMutableArray *)newArray//默认传入一个存名字的数组

     //中文排序。
    NSMutableArray *chineseStringsArray=[NSMutableArray array];//存返回的顺序数组
   
    for(int i=0;i<[newArray count];i++)遍历数组中每个名字
    {   
       
        ChineseString *chineseString=[[ChineseString alloc]init];//对chinesestring进行初始化(类中包括string名字和pinyin名字中所有汉字的开头大写字母) 
       
       chineseString.string=[NSString stringWithString:[newArray objectAtIndex:i]];//将名字存在string
         替换为下面的语句:
         chineseString.string=[NSString stringWithString:[[newArray objectAtIndex:i] sname] ];
//[newArray objectAtIndex:i]得到(Student*)对象,student有个sname属性存学生的名字
       
        if(chineseString.string==nil)//判断名字是否为空
        {   
           
            chineseString.string=@"";//如果名字是空就将string赋为0    
           
        }                   
       
       

        if(![chineseString.string isEqualToString:@""])//判断名字是否为空
        {   
            //名字不为空的时侯
           
            NSString *pinYinResult=[NSString string];  //存每个名字中每个字的开头大写字母

       加上以下代码同时获得学生得姓
         chineseString.xing=[[NSString stringWithFormat:@"%c",pinyinFirstLetter([chineseString.string characterAtIndex:0])]uppercaseString];//每个名字的姓

   
           
            for(int j=0;j<chineseString.string.length;j++)//遍历名字中的每个字
            {    
               
                NSString *singlePinyinLetter=[[NSString stringWithFormat:@"%c",pinyinFirstLetter([chineseString.string characterAtIndex:j])]uppercaseString];//取出字中的开头字母并转为大写字母    
               
                    pinYinResult=[pinYinResult stringByAppendingString:singlePinyinLetter];//取出名字的所有字的开头字母 
            }             
           
            chineseString.pinYin=pinYinResult;//将名字中所有字的开头大写字母chinesestring对象的pinYin中
       }
        else
       {           
            //名字为空的时侯
            chineseString.pinYin=@"";     
           
        }         
       
        [chineseStringsArray addObject:chineseString];//将包含名字的大写字母和名字的chinesestring对象存在数组中     
    }             
   
    //按照拼音首字母对这些Strings进行排序   
   
    NSArray *sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"pinYin" ascending:YES]];//对pinyin 进行排序  就像sql中的order by后指定的根据谁排序   生成一个数组 
   
    [chineseStringsArray sortUsingDescriptors:sortDescriptors]; 
               
   
    // 如果有需要,再把排序好的内容从ChineseString类中提取出来   
   
    NSMutableArray *result=[NSMutableArray array];  
   
    for(int i=0;i<[chineseStringsArray count];i++)
    {     
       
        [result addObject:((ChineseString*)[chineseStringsArray objectAtIndex:i]).string];     
    }       
   
    return chineseStringsArray;
   
}

*************
4.因为我们要将的是(Student*)对象,所以要通过下面方法将arr中的(ChineseString*)转为(Student*)存在TempA中
     Student *student1;
    //将chinesestring转为student对象
    for (int i=0; i<[arr count]; i++)
    {
       
        tempString1=[arr objectAtIndex:i];//取出一个对象
       
        [self.xingset addObject:tempString1.xing];//将姓存到xingset保证不重复
       
               
        student1=[Student findbysname:tempString1.string];//通过chinesestring对象的string(姓名)找到对应的学生对象
       
       
        [tempA addObject:student1];//将学生对象存起来
       
    }
5.将存姓的set转为数组
self.xingarray=(NSMutableArray*)[self.xingset allObjects];//set转为数组便于操作
6.将数据存为字典stuDic(这里默认大家已将学生数据存在数据库并通过sql语句实现了对数据库的检索更新删除增加为返回的均为Student*的对象****具体实现在博客中的其他文章中有写到)
字典的效果为每个姓(不重复)作为key值,同姓的学生组成一个数组为对应的Value

key:@"B"  Value:[@"白苏真",@"Ben"]
key:@"L"  Value:[@"李小曼",@"刘胡兰",@"李宁"]
studic字典的生成:
思路:有两个数组一个存姓一个存学生,依次拿每个学生和姓(作为key)相比较,若姓相同就存在一个数组中,使每次形成的数组都是存的相同姓氏的学生(作为Value)
具体代码:
for (int i=0; i<[self.xingarray count]; i++)//遍历所有姓
    {
        self.xing00=[[NSMutableArray alloc]init];
        for (int j=0; j<[self.tempA count]; j++)//遍历所有学生
        {
            tempString1=[arr objectAtIndex:j];//依次取出arr中的(chineseString*)对象
            if ([tempString1.xing isEqualToString:[self.xingarray objectAtIndex:i]]==YES) //将每个学生得姓跟每个姓比较
            {
                //姓相同就将对应的学生对象存起来

                [self.xing00 addObject:[self.tempA objectAtIndex:j]];//tempa中的对象顺序和arr中的顺序一样这里要得是学生对象所以直接从tempa中取
                //xing00存所有姓相同的学生
            }
        }
        [studic setObject:self.xing00 forKey:[self.xingarray objectAtIndex:i]];//生成对应的字典
    }

7.将stuDic的key值取出存为keyArray
        self.keyarray=(NSMutableArray*)[[studic allKeys]  sortedArrayUsingSelector:@selector(compare:)];//取出字典的key值并经过排序存在keyarray中
8.设置组(section)
//返回组数
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [self.keyarray count];//key的个数(姓的个数)就是组的个数
}
//组的名称
-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return [self.keyarray objectAtIndex:section];//key值(每个姓)就是组名
}
9.设置行(row)
//返回组中行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
    NSString*k=[self.keyarray objectAtIndex:section];//通过section在keyarray里拿到相应的key
    return [[studic objectForKey:k] count];//通过key在studic中找到(姓)对应的数组,数组中元素的个数就是每组对应的行数
}
***介绍一下什么是重用机制
我们的消息行和单元格数量不是一一对应的,实际上我们的系统只创建了一瓶多点的单元格,而有的单元格上做了重用标示,单元格分别存在两个数组中,一个存屏幕上显示的单元格,另一个存用过的单元格,当单元格划到屏外也就是要有新的单元格生成时,他不会马上创建而是到用过的单元格中找有没有单元格标有重用标示,若有便使用这个单元格,如没有再重新创建,这样节省内存,提高效率
//设置每行单元格的信息(包含重用机制)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString*identify=@"cell";//重用标示符
    UITableViewCell*cell=[self.studentTable dequeueReusableCellWithIdentifier:identify];//找一下有没有可重用的cell
    if (cell==nil)//没有可重用的cell
    {
        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identify];//重新创建
    }
   
    NSString*k=[self.keyarray objectAtIndex:section];//通过section在keyarray里拿到相应的key

    rowarray=[self.studic objectForKey:k];//通过key在studic中找到(姓)对应的数组(Student*)
   
   
    Student*stu=((Student*)[rowarray objectAtIndex:indexPath.row]);//取出对应的元素(Student*)
   
    //完成对单元格属性的赋值
    cell.textLabel.text=stu.sname ; 
    cell.detailTextLabel.text=[NSString stringWithFormat:@"%d",stu.sage];
    UIImage*image=[UIImage imageWithData:stu.simage];
    cell.imageView.image=image;
    //返回单元格
    return cell;
}
10.我们完成了对通讯录的分组显示
原创粉丝点击