(本文代码已升级至Swift3)
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()
}
}
|
![](https://i-blog.csdnimg.cn/blog_migrate/b21d9ae556170caacaaa2b785159716c.gif)
原文出自:www.hangge.com 转载请保留原文链接:http://www.hangge.com/blog/cache/detail_1175.html