思路
要实现类似苹果自带的通讯录联系人按首字母分组的效果,使用UITabView思路大致如下:
- 姓名转成拼音
- 拼音首字母大写
- 取第一个首字母,去重+排序
比如:
let contacts : [String ] = [张三,张全蛋,李四,王五,people,王尼玛]
得到
[Z,L,W,P]
实现
- 实体类,增加一个首字母字段
class FriendUserModel {
var userInfo: CIM_Def_CIMUserInfo!
var nameFirstCharacter: Character! // 昵称首字母
init(user: CIM_Def_CIMUserInfo) {
userInfo = user
// 汉字转成拼音
let str = NSMutableString(string: user.nickName) as CFMutableString
CFStringTransform(str, nil, kCFStringTransformToLatin, false)
// 拼音去掉拼音的音标
CFStringTransform(str, nil, kCFStringTransformStripDiacritics, false)
// 大写字母
var s: String = String(str)
s = s.capitalized // 大写首字母
nameFirstCharacter = s[s.startIndex]
}
}
上述代码,通过注入一个基础的用户信息(包括用户ID、昵称等),然后自动计算大写拼音首字母。
- 循环数据源,去重计算分组
class IMFriendViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet var userTabview: UITableView!
var userList: [FriendUserModel] = [] // 数据源
var group: [Character] = [] // 首字母去重后的分组
override func viewDidLoad() {
// 这里省略userList从服务器拉取加载的代码
//for item in rsp.userInfoList {
// let model = FriendUserModel(user: item)
// self.userList.append(model)
//}
// 计算首字母分组
for item in self.userList {
// 去重判断
if self.group.firstIndex(of: item.nameFirstCharacter) == nil {
self.group.append(item.nameFirstCharacter)
}
}
// 排序
self.group = self.group.sorted(by: { (caracter0, character1) -> Bool in
return caracter0 < character1
})
}
- TableViewDataSource 代理处理加载逻辑
extension IMFriendViewController {
// 几组?
func numberOfSectionsInTableView(_ tableView: UITableView) -> Int {
return group.count
}
// 每组多少人?
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return userList.filter { (emp) -> Bool in emp.nameFirstCharacter == group[section] }.count
}
// 组名?
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if group.count > 0 {
return String(group[section])
}
return nil
}
// 如果不需要分组,直接返回列表的大小
// func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// return userList.count
// }
// 返回一个TabViewCell实例,TabViewCell就是一行数据,真正用来显示的
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// cellId是类名
let classType = IMFriendViewCell.self
let cellId = String(describing: classType)
// 找到这一组要显示的用户
let showUsers: [FriendUserModel] = userList.filter { (emp) -> Bool in
emp.nameFirstCharacter == group[indexPath.section]
}
// 获取一个可重复使用的Cell,没有就收到创建
var cell = tableView.dequeueReusableCell(withIdentifier: cellId) as? IMFriendViewCell
if cell == nil {
cell = IMFriendViewCell(style: .default, reuseIdentifier: cellId)
}
// 渲染一行
cell!.setContent(user: showUsers[indexPath.row].userInfo)
return cell!
}
}