美文网首页IOS
swift实现tableview分组-防微信通讯录的实现

swift实现tableview分组-防微信通讯录的实现

作者: 瑟闻风倾 | 来源:发表于2019-02-15 17:27 被阅读17次

    1. 界面展示

    员工分组列表.png

    2. 界面设计

    tableview视图.png

    3.具体实现

    (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实现搜索

      1. 遵从UISearchResultsUpdating协议


        遵从UISearchResultsUpdating协议.png
      1. 定义UISearchController


        定义UISearchController.png
      1. UISearchController初始化


        UISearchController初始化.png
      1. 获取所有员工集合


        获取所有员工集合.png
      1. 实现搜索框相关代理方法


        实现搜索框相关代理方法.png
      1. 修改和添加tableview相关代理方法


        修改tableview相关代理方法.png
        添加tableview相关代理方法.png

    相关文章

      网友评论

        本文标题:swift实现tableview分组-防微信通讯录的实现

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