制作通訊錄聽起來很麻煩但是其有一個套路,明白了這一個套路,以后制作類似的東東就有思路了,什么套路呢?
這是做成的基本效果
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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//默認傳入一個存名字的數組
{
*************
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.我們完成了對通訊錄的分組顯示

這是做成的基本效果
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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;
}
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.我們完成了對通訊錄的分組顯示