IOS

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

2019-02-15  本文已影响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实现搜索

上一篇下一篇

猜你喜欢

热点阅读