Swift5.2 - UITableView的简单实现

Swift - UITableView的简单实现

记录整理下tableView的实现,方便日后查看。分为三部分进行记录学习:

1.使用UITableViewCell实现一个简单的tableView

2.使用自定义cell实现带索引列表的tableView

3.与UISearchBar的简单结合使用

  • 以下是Demo演示
UITableView
  • 以下是代码实现

使用UITableViewCell实现一个简单的tableView

//
//  TableView1.swift
//  UITableView
//
//  Created by StYiWe on 2020/9/14.
//  Copyright © 2020 stYiwe. All rights reserved.
//

import UIKit

class TableView1: UIViewController, UITableViewDelegate, UITableViewDataSource {

    //tableView
    var tableView = UITableView()
    
    //数据
    var dataList: NSMutableArray = []
    
    
    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = .white
        self.title = "使用系统cell"
        
        //右上角编辑按钮
        self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(barButtonSystemItem: .edit, target: self, action: #selector(editAction))
        
        //数据
        dataList = NSMutableArray.init(array: ["🐰", "秃子", "鹰酱", "毛熊", "棒子", "脚盆鸡", "高卢鸡", "狗大户", "🐫", "沙某", "河马"])
        
        //UI
        createTableViewUI()
        
    }
    
    //MARK: - 实例化tableView
    func createTableViewUI() {
        tableView = UITableView.init(frame: UIScreen.main.bounds, style: .plain)
        tableView.delegate = self
        tableView.dataSource = self
        //注册cell
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellID")
        //去除分割线
//        tableView.separatorStyle = .none
        //去掉多余的分割线
        tableView.tableFooterView = UIView()
        
        self.view.addSubview(tableView)
    }
    
    //MARK: - 编辑
    @objc func editAction() {
        //设置可编辑
        tableView.setEditing(true, animated: true)
        
        //完成按钮
        self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(barButtonSystemItem: .done, target: self, action: #selector(doneAction))
    }
    
    //MARK: - 编辑完成
    @objc func doneAction() {
        //设置不可编辑
        tableView.setEditing(false, animated: true)
        
        //右上角编辑按钮
        self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(barButtonSystemItem: .edit, target: self, action: #selector(editAction))
        
    }
    
    //MARK: - 返回多少行
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataList.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cellID", for: indexPath)
        
        cell.textLabel?.text = dataList[indexPath.row] as? String
        
        return cell
    }

    //MARK: - 行高
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 60
    }
    
    //MARK: - 点击cell
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print(dataList[indexPath.row])
    }
    
    //MARK: - 使cell的分割线与屏幕两端对齐
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
            cell.separatorInset = .zero
        }
        if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
            cell.layoutMargins = .zero
        }
    }
    
    //MARK: - 设置编辑样式
    func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
        //编辑的时候返回带有选择按钮的样式
//        return UITableViewCell.EditingStyle(rawValue: UITableViewCell.EditingStyle.RawValue(UInt8(UITableViewCell.EditingStyle.insert.rawValue) | UInt8(UITableViewCell.EditingStyle.delete.rawValue)))!
        
        //添加
//        return .insert
        
        //删除
        return .delete
    }
    
    //MARK: - 删除单元格
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            print("要删除\(dataList[indexPath.row])")
            
            //提示
            let alertC = UIAlertController.init(title: "温馨提示", message: "确定要删除\(dataList[indexPath.row])?", preferredStyle: .alert)
            alertC.addAction(UIAlertAction.init(title: "确定", style: .destructive, handler: { (UIAlertAction) in
                self.dataList.removeObject(at: indexPath.row)
                tableView.reloadData()
            }))
            
            alertC.addAction(UIAlertAction.init(title: "取消", style: .cancel, handler: nil))
            
            present(alertC, animated: true, completion: nil)
        }
        
        if editingStyle == .insert {
            print("增加")
        }
    }
    
    //MARK: - 允许排序
    func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        return true
    }
    
    //MARK: - 排序
    func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
        
        tableView.moveRow(at: sourceIndexPath, to: destinationIndexPath)
        dataList.exchangeObject(at: sourceIndexPath.row, withObjectAt: destinationIndexPath.row)
        tableView.reloadData()
    }
      
}

使用自定义cell实现带索引列表的tableView

//
//  TableView2.swift
//  UITableView
//
//  Created by StYiWe on 2020/9/14.
//  Copyright © 2020 stYiwe. All rights reserved.
//

import UIKit

//cell Identifier
let cellID = "cellID"

class TableView2: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    //tableView
    var tableView = UITableView()
    
    //数据
    var dataList = [String]()
    
    //处理后的数据(根据首字母进行分组)
    var resultDict = [String : [String]]()
    
    //组头标题数组
    var sectionTitles = [String]()
    

    override func viewDidLoad() {
        super.viewDidLoad()

        self.title = "带索引的UITableView"
        self.view.backgroundColor = .white
        
        //原始数据
        dataList = ["🐰", "秃子", "鹰酱", "毛熊", "Cat", "棒子", "脚盆鸡", "高卢鸡", "狗大户", "🐫", "沙某", "河马", "Big Dog", "Apple"]
        
        //数据处理
        createResultDict()
        
        //tableVIew
        tableView = UITableView.init(frame: UIScreen.main.bounds, style: .plain)
        tableView.delegate = self
        tableView.dataSource = self
        //去掉多余的分割线
        tableView.tableFooterView = UIView()
        //注册cell
        tableView.register(UINib(nibName: "TableView2Cell", bundle: nil), forCellReuseIdentifier: cellID)
        self.view.addSubview(tableView)
        
    }
    
    //MARK: - 数据处理,根据首字母进行分组
    /**
                ```
                数据**处理**,根据`首字母`进行分组
                ```
     */
    func createResultDict() {
        for str in dataList {
            //获得首字母
            let firstLetterIndex = str.index(str.startIndex, offsetBy: 1)
            var firstLetter = String(str[..<firstLetterIndex])
            
            //转成大写字母
            firstLetter = firstletterFromString(str: firstLetter)
            
            if var values = resultDict[firstLetter] {
                values.append(str)
                resultDict[firstLetter] = values
            } else {
                resultDict[firstLetter] = [str]
            }
            
            //组头标题
            sectionTitles = [String](resultDict.keys)
            //排序
            sectionTitles = sectionTitles.sorted(by: {$0 < $1})
        }
    }
    
    //MARK: - 将中文转成大写字母
    func firstletterFromString(str: String) -> String {
        //转变成可变字符串
        let mutableStr = NSMutableString.init(string: str)
        
        //将中文转变成带声调的拼音
        CFStringTransform(mutableStr as CFMutableString, nil, kCFStringTransformToLatin, false)
        
        //去掉声调
        let pyStr = mutableStr.folding(options: .diacriticInsensitive, locale: .current)
        
        //将拼音换成大写
        let PYStr = pyStr.uppercased()
        
        //截取大写首字母
        let index = PYStr.index(PYStr.startIndex, offsetBy: 1)
        let firstStr = PYStr[..<index]
        
        //判断首字母是否为大写
        let uppercaseLetter = "^[A-Z]$"
        let predicateLetter = NSPredicate.init(format: "SELF MATCHES %@", uppercaseLetter)
        
        return String(predicateLetter.evaluate(with: firstStr) ? firstStr : "#")
    }
    
    
    //MARK: - 返回多少组
    func numberOfSections(in tableView: UITableView) -> Int {
        return sectionTitles.count
    }
    
    //MARK: - 每组多少行
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let key = sectionTitles[section]
        guard let values = resultDict[key] else {
            return 0
        }
        return values.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath) as! TableView2Cell
        
        let key = sectionTitles[indexPath.section]
        let values = resultDict[key]
        
        cell.titleLabel.text = values?[indexPath.row]
        
        return cell
    }
    
    //MARK: - 行高
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 60
    }
    
    //MARK: - section标题
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return sectionTitles[section]
    }
    
    //MARK: - 索引列表
    func sectionIndexTitles(for tableView: UITableView) -> [String]? {
        return sectionTitles
    }
    

}

与UISearchBar的简单结合使用

//
//  TableView3.swift
//  UITableView
//
//  Created by StYiWe on 2020/9/15.
//  Copyright © 2020 stYiwe. All rights reserved.
//

import UIKit

class TableView3: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {

    //searchBar
    var searchBar : UISearchBar!
    
    //tableView
    var tableView : UITableView!
    
    //数据
    var dataList = ["🐰", "秃子", "鹰酱", "毛熊", "Cat", "棒子", "脚盆鸡", "高卢鸡", "狗大户", "🐫", "沙某", "河马", "Big Dog", "Apple"]
    
    //搜索数据
    var searchDataList: [String] = []
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "与UISearchBar一起使用"
        self.view.backgroundColor = .white
        
        //搜索数据默认加载全部
        searchDataList = dataList
        
        //UI
        creatUI()
        
    }
    
    func creatUI() {
        //tableView
        tableView = UITableView.init(frame: UIScreen.main.bounds, style: .plain)
        tableView.delegate = self
        tableView.dataSource = self
        tableView.tableFooterView = UIView()
        //注册cell
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellID")
        self.view.addSubview(tableView)
        
        //searchBar
        searchBar = UISearchBar.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 60))
        //显示取消按钮
        searchBar.showsCancelButton = true
        searchBar.delegate = self
        tableView.tableHeaderView = searchBar
        
    }
    
    //MARK: - 取消搜索
    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        self.view.endEditing(true)
        searchBar.text = ""
        searchDataList = dataList
        tableView.reloadData()
    }
    
    //MARK: - 搜索代理,每次改变搜索内容都会调用
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        print("搜索内容:\(searchText)")
        //没有搜索内容时显示全部数据
        if searchText == "" {
            searchDataList = dataList
        } else {
            //获取搜索栏文字,筛选后更新列表
            let text = searchText.trimmingCharacters(in: .whitespaces)
            //获取符合的数据
            searchFilter(text: text)
        }
        
        tableView.reloadData()
    }
    
    //MARK: - 添加一个筛选器方法:使用Swift数组系统filter方法,返回一个符合条件的新数组
    func searchFilter(text: String) {
        searchDataList = dataList.filter({ (str) -> Bool in
            return str.localizedCaseInsensitiveContains(text)
        })
    }
    

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return searchDataList.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cellID", for: indexPath)
        
        cell.textLabel?.text = searchDataList[indexPath.row]
        
        return cell
    }

}

附上Demo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354