Swift - 动态添加删除TableView的单元格(以及内部元件)
在Swift开发中,我们有时需要动态的添加或删除列表的单元格。


3,源码下载:
hangge_727.zip
比如我们做一个消息提醒页面,默认页面只显示两个单元格。当点击第二个单元格(时间标签)时,下面会再添加一个单元格放置日期选择控件(同时新增单元格的高度也会变化)。而再次点击第二个单元格,日期选择控件又会隐藏。


1,首先创建一个静态单元格的tableViewController
将其设置成一个分区,两个单元个。并在单元格内部放置好相关组件。

2,添加其关联代码
这个 Scene 关联的代码(MyTableViewController.swift)如下。(代码已升级为Swift3)
import UIKit class MyTableViewController: UITableViewController { @IBOutlet weak var dueDateLabel: UILabel! //日期选择器显示状态 var datePickerVisible:Bool = false override func viewDidLoad() { super.viewDidLoad() self.title = "添加任务" //去除尾部多余的空行 self.tableView.tableFooterView = UIView(frame:CGRect.zero) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } //选择cell的row之后 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { self.tableView.deselectRow(at: indexPath, animated: true) //当执行到日期选择器上一行的时候,可以判断是否要显示日期选择器了 if indexPath.section == 0 && indexPath.row == 1{ if !datePickerVisible{ self.showDatePicker() }else{ self.hideDatePicker() } } print(indexPath.row) } //显示日期选择器 func showDatePicker(){ //日期选择器的状态设为打开 datePickerVisible = true let indexPathDatePicker = IndexPath(row: 2, section: 0) self.tableView.insertRows(at: [indexPathDatePicker], with: .automatic) } //隐藏日期选择器 func hideDatePicker(){ if datePickerVisible { //日期选择器的状态设为关闭 datePickerVisible = false let indexPathDatePicker = IndexPath(row: 2, section: 0) self.tableView.deleteRows(at: [indexPathDatePicker], with: .fade) } } override func numberOfSections(in tableView: UITableView) -> Int { return 1 } //设置cell override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { //因为日期选择器的位置在日期显示Label下面。它的位置就是第2个section 和第3个row if indexPath.section == 0 && indexPath.row == 2{ //用重用的方式获取标识为DatePickerCell的cell var cell = tableView.dequeueReusableCell(withIdentifier: "DatePickerCell") as UITableViewCell? //如果没找到就创建一个 if cell == nil { //创建一个标识为DatePickerCell的cell cell = UITableViewCell(style: .default, reuseIdentifier: "DatePickerCell") //设置cell的样式 cell?.selectionStyle = .none //创建日期选择器 let datePicker = UIDatePicker(frame: CGRect(x:0, y:0, width:320, height:216)) //给日期选择器的tag datePicker.tag = 100 //将日期选择器区域设置为中文,则选择器日期显示为中文 datePicker.locale = Locale(identifier: "zh_CN") //将日期选择器加入cell cell?.contentView.addSubview(datePicker) //注意:action里面的方法名后面需要加个冒号“:” datePicker.addTarget(self, action:#selector(dateChanged(_:)), for: .valueChanged) } return cell! }else{ return super.tableView(tableView, cellForRowAt: indexPath) } } //日期选择器响应方法 func dateChanged(_ datePicker: UIDatePicker){ //更新提醒时间文本框 let formatter = DateFormatter() //日期样式 formatter.dateFormat = "yyyy年MM月dd日 HH:mm:ss" self.dueDateLabel.text = formatter.string(from: datePicker.date) } //根据日期选择器的隐藏与否决定返回的row的数量 override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if section == 0 && datePickerVisible{ return 3 }else{ return super.tableView(tableView, numberOfRowsInSection: section) } } //因为日期选择器插入后会引起cell高度的变化,所以要重新设置 override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { //当渲染到达日期选择器所在的cell的时候将cell的高度设为217 if indexPath.section == 0 && indexPath.row == 2{ return 216.0 }else{ return super.tableView(tableView, heightForRowAt: indexPath) } } //当覆盖了静态的cell数据源方法时需要提供一个代理方法。 //因为数据源对新加进来的日期选择器的cell一无所知,所以要使用这个代理方法 override func tableView(_ tableView: UITableView, indentationLevelForRowAt indexPath: IndexPath) -> Int { if indexPath.section == 0 && indexPath.row == 2{ //当执行到日期选择器所在的indexPath就创建一个indexPath然后强插 let newIndexPath = IndexPath(row: 0, section: indexPath.section) return super.tableView(tableView, indentationLevelForRowAt: newIndexPath) }else{ return super.tableView(tableView, indentationLevelForRowAt: indexPath) } } }
3,源码下载:

很喜欢这里的文章,使用还很清楚,思路明确,偶尔看到了,很厉害
航哥,搞定了,不用提供demo了,谢谢,要把table view的 content设置为static,就好了,麻烦了
航哥,请教,我用storyboard建立个新的Table View Controller,建立了新的swift文件,复制了文章内容。然后设置了Custom Class 为MyTableViewController。运行但是在模拟器是空白的,不知错在哪里。能提供个这个例子的demo吗,您费心了,谢谢!
test很不错的网站,这个demo的全部源码在哪呢,能不能提供一个下载链接呢
真的是太好了,偶然发现的这个网站...立马喜欢上了,看了好多,解决了我很多问题...代码很容易懂!赞
太喜欢这个站了,潜水很久,一直默默收藏,这个站帮了很多,代码很容易懂,支持大大,有群吗
简直赞,这就是我想要的