swift实现tableview分组-防微信通讯录的实现
2019-02-15 本文已影响17人
瑟闻风倾
1. 界面展示
员工分组列表.png2. 界面设计
tableview视图.png3.具体实现
(1)StaffManageTableViewController.swift
//
// StaffManageTableViewController.swift
// JackUChat
//
// Created by 徐云 on 2019/1/22.
// Copyright © 2019 Liy. All rights reserved.
//
import UIKit
import Alamofire
import SwiftyJSON
import HandyJSON
import Kingfisher
class StaffManageTableViewController: UITableViewController {
//let letter:[String] = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z","#"]
var staffsDict = [String: [Staff] ] ()//初始化用于存储员工列表的空字典
var staffSectionTitles = [String] ()//初始化用于存储表的块标题的空数组,此处块标题是员工名的首字母
override func viewDidLoad() {
super.viewDidLoad()
getListByAlomafire()
}
// MARK: - Table view data source
//返回表视图中所有的部分:通常将section的数量设置为1。如果有多个部分,把这个值设置为大于1的数字.
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return staffSectionTitles.count
}
//组标题:返回不同部分的标题,则此方法是可选的
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return staffSectionTitles[section]
}
//返回特定部分中的行总数.
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
let staffKey = staffSectionTitles[section]
guard let staffValues = staffsDict[staffKey] else { return 0 }
return staffValues.count
}
//返回特定部分的表数据
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
// Configure the cell...
let cellId = String(describing: StaffCell.self)
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! StaffCell
let staffKey = staffSectionTitles[indexPath.section]
if let staffValues = staffsDict[staffKey] {
let staff = staffValues[indexPath.row]
cell.staffNameLabel?.text = staff.staffName
cell.staffPhoneLabel.text = staff.staffPhone
cell.staffDeptLabel.text = getPosition(key: staff.staffDept)
let imgUrl = URL(string: staff.staffAvatar)
cell.staffImageView.kf.setImage(with: imgUrl)
}
return cell
}
//单元格高度:有效避免tableviewcell动态加载不同尺寸的网络图片时,上下滑动会导致图片拉伸、单元格高度不定的问题
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
//右侧索引:返回出现在表视图右边的索引列表中的索引标题,如返回包含从a到Z值的字符串数组.
override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
//return letter
return staffSectionTitles
}
//返回当用户点击特定索引时,表视图应该跳转到的部分索引.
// override func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
// return 0
// }
/*
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/
// override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
// return section.description
// }
// MARK: - network
func getListByAlomafire() {
AlamofireHelper.shareInstance.requestData(.get, url: "Employee/index") { (result) in
let jsonDictory = JSON(result as Any)
let code = jsonDictory["code"].string
let msg = jsonDictory["msg"].string
if(code == "0"){
print("成功:"+code!+","+msg!)
let sectionList = jsonDictory["data"]["userList"].array
for section in sectionList! {
let staffKey = section["first_char"].string//得到首字母
let userList = section["data"].array
var staffs:[Staff] = []
for user in userList!{
let staff = Staff(staffLetter: user["fc"].string ?? "", staffName: user["name"].string ?? "", staffPhone: user["mobile"].string ?? "", staffAvatar: user["avatar"].string ?? "", staffDept: user["dept"].string ?? "")
staffs.append(staff)
//创建字典:首字母被作为字典的键,字典的值为指定键的员工数组
if var staffValues = self.staffsDict[staffKey!]{
staffValues.append(staff)
self.staffsDict[staffKey!] = staffValues//添加到已有的员工数组
}else{
self.staffsDict[staffKey!] = staffs//创建新的员工数组
}
}
//从字典关键字中获取表每部分的标题并排序
self.staffSectionTitles = [String](self.staffsDict.keys)//从字典的键中检索表每块的标题
self.staffSectionTitles = self.staffSectionTitles.sorted(by: { $0 < $1 })//sort函数根据所提供的排序闭包的输出返回已知类型的值的排序数组
}
//异步获取数据,需在主线程中更新
OperationQueue.main.addOperation {
self.tableView.reloadData()
self.tableView.refreshControl?.endRefreshing()//加载完数据后停止下拉刷新动画
}
}else{
print("失败")
}
}
}
func getPosition(key:String) -> String {
var positionDict = ["1":"管理员","2":"班组长","3":"机修","4":"财务","5":"员工"]
guard let positionValues = positionDict[key] else { return "职位未知" }
return positionValues
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
问题
:tableviewcell动态加载不同尺寸的网络图片时,上下滑动会导致图片拉伸、单元格高度不定(故事版中虽然已设置了tableview单元格的高度)。
解决
:可通过代码设置单元格的高度进行避免,。
(2) StaffCell.swift
//
// StaffCell.swift
// JackUChat
//
// Created by 徐云 on 2019/1/22.
// Copyright © 2019 Liy. All rights reserved.
//
import UIKit
class StaffCell: UITableViewCell {
@IBOutlet weak var staffImageView: UIImageView!
@IBOutlet weak var staffNameLabel: UILabel!
@IBOutlet weak var staffPhoneLabel: UILabel!
@IBOutlet weak var staffDeptLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
(3) Staff.swift
//
// Staff.swift
// JackUChat
//
// Created by 徐云 on 2019/2/15.
// Copyright © 2019 Liy. All rights reserved.
//
struct Staff:Codable {
var staffLetter:String
var staffName:String
var staffPhone:String
var staffAvatar:String
var staffDept:String
}
备注
:获取的网络数据示例
{
"code": "0",
"msg": "success",
"data": {
"userList": [
{
"first_char": "A",
"data": [
{
"user_id": "74",
"company_id": "50",
"fc": "A",
"name": "Abel",
"dept": "1",
"avatar": "https://wx.qlogo.cn/mmopen/vi_32/Zb5XAibrJOtjnq00qf7OygIlZcH24sfSfef1diasbWlfRQDx8TvFyA6LaKQIYftsgiccxHBQB3N9LPdp1ribCqyRag/132",
"mobile": "13014578115",
"is_root": "1",
"i": 1
}
]
},
{
"first_char": "L",
"data": [
{
"user_id": "89",
"company_id": "50",
"fc": "L",
"name": "龙**",
"dept": "4",
"avatar": "https://wx.qlogo.cn/mmopen/vi_32/ibUGnnCI4WtU7ZMrmbHr7AuAicLE2WicH8A6RGOczwAkGMRUBPOW9ZPG6d8VKaGuj6FrXEgeESBP1hqGLxmvUkMCw/132",
"mobile": "13874788765",
"is_root": "0",
"i": 2
},
{
"user_id": "128",
"company_id": "50",
"fc": "L",
"name": "李**",
"dept": "1",
"avatar": "https://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJ1SuqYBqrQ6VuplXr9Jibqo1yfdnWTQlLRMq7DVGVzTx5wGfNxCVoOia55CiahUWqBXf3BogelWib5icA/132",
"mobile": "18925673890",
"is_root": "1",
"i": 3
},
{
"user_id": "158",
"company_id": "50",
"fc": "L",
"name": "刘**",
"dept": "1",
"avatar": "https://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTLNJLCAU08JNhX2NTia5t93RR2rLLWOSUHCZCvw10SXkBw5HEsIX3U9PuOwqffb869FMYBsB3ViaXmw/132",
"mobile": "10987145674",
"is_root": "0",
"i": 4
}
]
},
{
"first_char": "M",
"data": [
{
"user_id": "82",
"company_id": "50",
"fc": "M",
"name": "梦**",
"dept": "4",
"avatar": "http://s.uchat.com.cn/public/images/nopic300.png",
"mobile": "19876724568",
"is_root": "0",
"i": 5
}
]
},
{
"first_char": "S",
"data": [
{
"user_id": "38",
"company_id": "50",
"fc": "S",
"name": "宋**",
"dept": "0",
"avatar": "https://wx.qlogo.cn/mmopen/vi_32/gwMicH3Nx4SYdiaGwHXeEsWiaUo7gNk06Wynt5rF1HCtwjlyQUFnqw5ODHibrK72ticI4cRZHNXFdvIH9xqS14be0BA/132",
"mobile": "19900765434",
"is_root": "1",
"i": 6
}
]
},
{
"first_char": "W",
"data": [
{
"user_id": "42",
"company_id": "50",
"fc": "W",
"name": "王**",
"dept": "99",
"avatar": "https://wx.qlogo.cn/mmopen/vi_32/DYAIOgq83eokG03icFicBSarapj5ia4CjsiaZZyvVqGmPsoIlCRI2Z8BIc5PTy0fO5aVffoGtXNibUbENDZicmYxdrbA/132",
"mobile": "19872456261",
"is_root": "1",
"i": 7
},
{
"user_id": "156",
"company_id": "50",
"fc": "W",
"name": "www",
"dept": "1",
"avatar": "http://s.uchat.com.cn/public/images/nopic300.png",
"mobile": "19876245091",
"is_root": "0",
"i": 8
}
]
},
{
"first_char": "Y",
"data": [
{
"user_id": "92",
"company_id": "50",
"fc": "Y",
"name": "姚**",
"dept": "99",
"avatar": "http://s.uchat.com.cn/public/images/nopic300.png",
"mobile": "17367535670",
"is_root": "0",
"i": 9
}
]
},
{
"first_char": "Z",
"data": [
{
"user_id": "2",
"company_id": "50",
"fc": "Z",
"name": "郑**",
"dept": "1",
"avatar": "https://wx.qlogo.cn/mmopen/vi_32/DYAIOgq83eo7DMGRk2q8TpAHrZndK4Kyg01qEQRhBK5HHvFqBzicaHibmVf2Zicgd02NjUYlEAMo3TMTxFud4Cgvw/132",
"mobile": "12345678901",
"is_root": "1",
"i": 10
}
]
}
],
"company_id": "50"
}
}
重点
:tableview相关代理方法,获取到的原始数据转化为需要的字典模型(key对应section的标题,values对应每个section的列表内容)
4. 优化-添加搜索
(1)界面展示
搜索前.png
搜索后.png
(2)修改StaffManageTableViewController.swift实现搜索
-
遵从UISearchResultsUpdating协议
遵从UISearchResultsUpdating协议.png
-
-
定义UISearchController
定义UISearchController.png
-
-
UISearchController初始化
UISearchController初始化.png
-
-
获取所有员工集合
获取所有员工集合.png
-
-
实现搜索框相关代理方法
实现搜索框相关代理方法.png
-
-
修改和添加tableview相关代理方法
修改tableview相关代理方法.png
添加tableview相关代理方法.png
-