(本文代码已升级至Swift3)

本文演示如何制作一个可以编辑单元格内容的表格(UITableView)。

1,效果图
(1)默认状态下,表格不可编辑,当点击单元格的时候会弹出提示框显示选中的内容。
         
(2)点击导航栏右侧编辑按钮,表格进入可以编辑状态
(3)这时我们可以删除表格项。
(4)也可以拖动调整单元格的顺序。
(5)然后就是本文的重点,在编辑状态下。直接点击单元格,即可在当前页面下直接编辑修改单元格中的内容。
2,单元格编辑功能讲解
(1)通过自定义 UITableViewCell,在其内部添加一个 textField 来实现可编辑的cell。
(2)通过改变 userInteractionEnabled 属性,可以让 textField 在可编辑与只读两个状态间切换。
(3)在编辑状态下要加大 textField 的左边距,因为左侧会出现个删除按钮图标。

(4)同时在编辑 cell 内容的时候,由于键盘会弹出挡到后面的表格。所以我们在键盘出现的时候,要通过改变 edgeInsets 的办法在底部加大 tableview 的 contentview 大小。

而结束编辑隐藏键盘时,需要还原 tableview 的 contentview 的尺寸。
3,程序代码
--- MyTableViewCell.swift(自定义单元格类)---
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import UIKit
//表格数据实体类
class ListItem: NSObject {
    var text: String
     
    init(text: String) {
        self.text = text
    }
}
//单元格类
class MyTableViewCell: UITableViewCell, UITextFieldDelegate {
    //单元格内部标签(可输入)
    let label:UITextField
    //单元格左边距
    var leftMarginForLabel: CGFloat = 15.0
     
    //单元格数据
    var listItem:ListItem? {
        didSet {
            label.text = listItem!.text
        }
    }
     
    //单元格是否可编辑
    var labelEditable:Bool? {
        didSet {
            label.isUserInteractionEnabled = labelEditable!
            //如果是可以编辑的话,要加大左边距(因为左边有个删除按钮)
            leftMarginForLabel = labelEditable! ? 45.0 : 15.0
            self.setNeedsLayout()
        }
    }
     
    //初始化
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        //初始化文本标签
        label = UITextField(frame: CGRect.null)
        label.textColor = UIColor.black
        label.font = UIFont.systemFont(ofSize: 16)
         
        super.init(style: style, reuseIdentifier: reuseIdentifier)
         
        //设置文本标签代理
        label.delegate = self
        label.contentVerticalAlignment = UIControlContentVerticalAlignment.center
        //添加文本标签
        addSubview(label)
    }
     
    //布局
    override func layoutSubviews() {
        super.layoutSubviews()
        label.frame = CGRect(x: leftMarginForLabel, y: 0,
                             width: bounds.size.width - leftMarginForLabel,
                             height: bounds.size.height)
    }
     
    //键盘回车
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return false
    }
     
    //结束编辑
    func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
        if listItem != nil {
            listItem?.text = textField.text!
        }
        return true
    }
     
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

--- ViewController.swift(主类)---
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
import UIKit
class ViewController: UIViewController, UITableViewDelegate,
UITableViewDataSource{
     
    //表格
    var tableView:UITableView?
    //表格数据
    var listItems = [ListItem]()
     
    override func viewDidLoad() {
        super.viewDidLoad()
         
        //初始化数据
        listItems = [ListItem(text: "这是条目1"), ListItem(text: "这是条目2"),
                     ListItem(text: "这是条目3"), ListItem(text: "这是条目4"),
                     ListItem(text: "这是条目5"), ListItem(text: "这是条目6"),
                     ListItem(text: "这是条目7"), ListItem(text: "这是条目8"),
                     ListItem(text: "这是条目9"), ListItem(text: "这是条目10"),
                     ListItem(text: "这是条目11"), ListItem(text: "这是条目12"),
                     ListItem(text: "这是条目13"), ListItem(text: "这是条目14"),
                     ListItem(text: "这是条目15"), ListItem(text: "这是条目16"),
                     ListItem(text: "这是条目17")]
         
        //创建表视图
        self.tableView = UITableView(frame:self.view.frame, style:.plain)
        self.tableView!.delegate = self
        self.tableView!.dataSource = self
        //创建一个重用的单元格
        self.tableView!.register(MyTableViewCell.self, forCellReuseIdentifier: "tableCell")
        self.view.addSubview(self.tableView!)
         
        //监听键盘弹出通知
        NotificationCenter.default
            .addObserver(self,selector: #selector(keyboardWillShow(_:)),
                         name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        //监听键盘隐藏通知
        NotificationCenter.default
            .addObserver(self,selector: #selector(keyboardWillHide(_:)),
                         name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }
     
    //导航栏编辑按钮点击
    @IBAction func editBarBtnClick(_ sender: UIBarButtonItem) {
        //在正常状态和编辑状态之间切换
        if(self.tableView!.isEditing == false){
            self.tableView!.setEditing(true, animated:true)
            sender.title = "保存"
        }
        else{
            self.tableView!.setEditing(false, animated:true)
            sender.title = "编辑"
        }
        //重新加载表数据(改变单元格输入框编辑/只读状态)
        self.tableView?.reloadData()
    }
     
    //在本例中,有1个分区
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
     
    //返回表格行数
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return listItems.count
    }
     
    //创建各单元显示内容(创建参数indexPath指定的单元)
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
        -> UITableViewCell
    {
        let cell = tableView
            .dequeueReusableCell(withIdentifier: "tableCell", for: indexPath)
            as! MyTableViewCell
        //设置单元格内容
        let item = listItems[(indexPath as NSIndexPath).row]
        cell.listItem = item
        cell.accessoryType = UITableViewCellAccessoryType.disclosureIndicator
        //内容标签是否可编辑
        cell.labelEditable = tableView.isEditing
        return cell
    }
     
    // UITableViewDelegate 方法,处理列表项的选中事件
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
    {
        self.tableView!.deselectRow(at: indexPath, animated: true)
        let itemString = listItems[(indexPath as NSIndexPath).row].text
        let alertController = UIAlertController(title: "提示!",
                                                message: "你选中了【\(itemString)】",
            preferredStyle: .alert)
        let okAction = UIAlertAction(title: "确定", style: .cancel, handler: nil)
        alertController.addAction(okAction)
        self.present(alertController, animated: true, completion: nil)
    }
     
    //是否有删除功能
    func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath)
        -> UITableViewCellEditingStyle
    {
        if(self.tableView!.isEditing == false){
            return UITableViewCellEditingStyle.none
        }else{
            return UITableViewCellEditingStyle.delete
        }
    }
     
    //删除提示
    func tableView(_ tableView: UITableView,
                   titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath)
        -> String? {
            return "确定删除?"
    }
     
    //编辑完毕(这里只有删除操作)
    func tableView(_ tableView: UITableView,
                   commit editingStyle: UITableViewCellEditingStyle,
                   forRowAt indexPath: IndexPath) {
        if(editingStyle == UITableViewCellEditingStyle.delete)
        {
            self.listItems.remove(at: (indexPath as NSIndexPath).row)
            self.tableView!.reloadData()
            print("你确认了删除按钮")
        }
    }
     
    //在编辑状态,可以拖动设置cell位置
    func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        return true
    }
     
    //移动cell事件
    func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath,
                   to toIndexPath: IndexPath) {
        if fromIndexPath != toIndexPath{
            //获取移动行对应的值
            let itemValue:ListItem = listItems[(fromIndexPath as NSIndexPath).row]
            //删除移动的值
            listItems.remove(at: (fromIndexPath as NSIndexPath).row)
            //如果移动区域大于现有行数,直接在最后添加移动的值
            if (toIndexPath as NSIndexPath).row > listItems.count{
                listItems.append(itemValue)
            }else{
                //没有超过最大行数,则在目标位置添加刚才删除的值
                listItems.insert(itemValue, at:(toIndexPath as NSIndexPath).row)
            }
        }
    }
     
    // 键盘显示
    func keyboardWillShow(_ notification: Notification) {
        let userInfo = (notification as NSNotification).userInfo!
        //键盘尺寸
        let keyboardSize = (userInfo[UIKeyboardFrameBeginUserInfoKey]
            as! NSValue).cgRectValue
        var contentInsets:UIEdgeInsets
        //判断是横屏还是竖屏
        let statusBarOrientation = UIApplication.shared.statusBarOrientation
        if UIInterfaceOrientationIsPortrait(statusBarOrientation) {
            contentInsets = UIEdgeInsetsMake(64.0, 0.0, (keyboardSize.height), 0.0);
        } else {
            contentInsets = UIEdgeInsetsMake(64.0, 0.0, (keyboardSize.width), 0.0);
        }
        //tableview的contentview的底部大小
        self.tableView!.contentInset = contentInsets;
        self.tableView!.scrollIndicatorInsets = contentInsets;
    }
     
    // 键盘隐藏
    func keyboardWillHide(_ notification: Notification) {
        //还原tableview的contentview大小
        let contentInsets:UIEdgeInsets = UIEdgeInsetsMake(64.0, 0.0, 0, 0.0);
        self.tableView!.contentInset = contentInsets
        self.tableView!.scrollIndicatorInsets = contentInsets
    }
     
    //页面移除时
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidAppear(animated)
        //取消键盘监听通知
        NotificationCenter.default.removeObserver(self)
    }
     
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

源码下载:hangge_1175.zip
原文出自:www.hangge.com  转载请保留原文链接:http://www.hangge.com/blog/cache/detail_1175.html

转载于:https://www.cnblogs.com/Free-Thinker/p/7264300.html

Swift - 可编辑表格样例(可直接编辑单元格中内容、移动删除单元格)相关推荐

  1. android 编辑自定义可编辑表格,smart 框架 列表 可编辑表格

    可编辑表格常用属性 colModel: [ {label: "主键ID", name: "hellop1",hidden:true}, {label: &quo ...

  2. wps html编辑表格,手机版wps如何编辑表格图解

    我们可以在手机版本的wps中对表格进行编辑,对于新手来说可能不知如何操作,其实方法很简单,关键是多看多练,下面就让学习啦小编告诉你如何在手机wps中编辑表格 的方法,欢迎大家来到学习啦学习. 在手机w ...

  3. JS合并表格中内容一样的单元格

    1.页面效果 2.js代码 function mergeCells() {var colNumber = tablecontent.rows.item(0).cells.length; //获取表格列 ...

  4. 【Latex】表格样例大全

    1 % 所需包 \usepackage{type1cm} \begin{table*}[t]\caption{Performance of MeFA (Adult). }\label{tab_1

  5. Java 8 时间日期库的20个使用演示样例

    除了lambda表达式,stream以及几个小的改进之外,Java 8还引入了一套全新的时间日期API,在本篇教程中我们将通过几个简单的任务演示样例来学习怎样使用Java 8的这套API.Java对日 ...

  6. pytorch geometric GraphSAGE代码样例reddit和ogbn_products_sage,为何subgraph_loader将sizes设成[-1]

    pytorch geometric GraphSAGE代码样例reddit和ogbn_products_sage,为何subgraph_loader将sizes设成[-1] loader infere ...

  7. android 如何制作可编辑的表格,在手机wps中编辑表格的方法

    我们可以在手机版本的wps中对表格进行编辑,对于新手来说可能不知如何操作,下面就让学习啦小编告诉你如何在手机wps中编辑表格的方法,希望对大家有所帮助. 在手机wps中编辑表格的方法 首先,下载并安装 ...

  8. Ant Design Pro使用之--EditableProTable 可编辑表格

    前言--EditableProTable 与 ProTable的对比 首先:可编辑表格 EditableProTable 与 ProTable 的功能基本相同: 但是如果用ProTable的话,增和改 ...

  9. html表格无法编辑,html 可编辑表格

    场景:HTML+JS兑现可编辑表格 HTML+JS实现可编辑表格 实现可视化编辑表格操作... HTML文件: 编辑表格数据 可编辑的表格 序号 商品名称 数量 单价 合计 1 C 0 0 0 2 D ...

最新文章

  1. HTML5(WebSockets)的脆弱性?
  2. jvm可以运行多种语言吗
  3. boost::interprocess::offset_ptr用法的测试程序
  4. 禅道之需求追踪和多角色协作流程
  5. jzoj5702-[gdoi2018day2]滑稽子图【树形dp,二项式定理】
  6. 英雄联盟祖安服务器要维护多久,祖安玩家的春天!英雄联盟将回归队内语音,娱乐玩家遭殃了?...
  7. 使用Anaconda3安装tensorflow,opencv,使其可以在spyder中运行
  8. 兼容性测试中如何切换和管理多个JDK版本
  9. 56)函数模板的基本语法
  10. 人都喜欢抬杠:一时不抬杠就浑身难受综合症候群
  11. c语言中 临时变量的作用,C语言 临时变量不能作为函数的返回值?
  12. 修复ipad提示无法连接到服务器,修复无法连接到iPad的App Store
  13. JavaScript基础之函数截流、防抖、柯理化
  14. ng-template、ng-container、ng-content 的用法
  15. 三相有功无功电流检测方法
  16. 计算机域名设置方法,windows电脑加入域的设置方法步骤(图文)
  17. 在香港,无法使用迅雷下载怎么办?
  18. nginx设置cookie
  19. Linux命令 - zip命令
  20. 【陈工笔记】【复盘】# 服务器集群使用方式 #

热门文章

  1. leetcode C++ 46. 全排列 给定一个 没有重复 数字的序列,返回其所有可能的全排列。
  2. STM32F103的PC13、PB3和PB4定义为普通IO口使用
  3. matlab 读取txt文件数据
  4. php没有phpapache,php没有被apache解析怎么办
  5. 拉格朗日插值--11次切比雪夫多项式零点作为节点Python实现并计算误差
  6. 讲解泊松融合文章推荐
  7. 2.1.3 正则化(归一化)的用处以及何时使用
  8. 空行替换_Word怎么批量删除空行和空格?有技巧很简单!
  9. LaTeX中警告类型及说明
  10. .Net NPOI 根据excel模板导出excel、直接生成excel