我有一个表视图,它显示了一个名为请求的对象列表。它有三个部分。即接受、接收和发送。每个段的对象为3个数组。

我希望只为已接受和发送的段启用删除行(依次为对象)。

这是我目前的实现。
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
var deleteAction: UIContextualAction?
switch currentShowingStatus {
case .accepted:
deleteAction = UIContextualAction(style: .destructive, title: "Delete") { action, view, completionHandler in
let request = self.acceptedRequests[indexPath.row]
completionHandler(true)
}
case .sent:
deleteAction = UIContextualAction(style: .destructive, title: "Delete") { action, view, completionHandler in
let request = self.sentRequests[indexPath.row]
completionHandler(true)
}
default:
break
}
if let deleteAction = deleteAction {
let configuration = UISwipeActionsConfiguration(actions: [deleteAction])
configuration.performsFirstActionWithFullSwipe = false
return configuration
} else {
return UISwipeActionsConfiguration(actions: [])
}
}正如您所看到的,有相当多的重复代码。而且我无法提取出UIContextualAction声明部分,因为它是完成处理程序。选择要删除的对象就发生在那里。
我也不能将UISwipeActionsConfiguration定义为局部变量,并且由于必须使用UIContextualAction实例初始化类,所以减少了它的重复。
注意:为了不显示单元格中的滑动操作,您必须将一个空操作数组传递给UISwipeActionsConfiguration。返回nil并不能做到这一点。
所以所有这些都产生了一段丑陋的代码。我想知道是否有更好的方法来重构这个。
我没有先检查段,然后再添加多个删除操作,而是将段部件检查放在一个完成处理程序中,如下所示。
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
var actions = [UIContextualAction]()
let deleteAction = UIContextualAction(style: .destructive, title: "Delete") { action, view, completionHandler in
switch self.currentShowingStatus {
case .accepted:
let request = self.acceptedRequests[indexPath.row]
self.deleteClientRequest(request)
case .sent:
let request = self.sentRequests[indexPath.row]
self.deleteClientRequest(request)
default:
break
}
completionHandler(true)
}
switch currentShowingStatus {
case .accepted, .sent:
actions.append(deleteAction)
case .received:
actions.removeAll()
}
let configuration = UISwipeActionsConfiguration(actions: actions)
configuration.performsFirstActionWithFullSwipe = false
return configuration
}缺点是,我仍然必须再次检查段,以显示只接受和发送段的滑动动作。
发布于 2019-08-04 17:11:34
在第一个实现中,如果在开关语句的所有情况下对deleteAction进行初始化,则可以使它成为常量:
let deleteAction: UIContextualAction?
switch currentShowingStatus {
case .accepted:
deleteAction = UIContextualAction(...)
case .sent:
deleteAction = UIContextualAction(...)
case .received:
deleteAction = nil
}这就清楚地表明,变量在使用之前精确地初始化了一次。我还会用显式的default:代替case received:。这对读者来说是显而易见的,在这种情况下,不配置swipe操作(不查找枚举定义),如果添加了更多的情况,则强制您更新代码。
可以通过初始化操作数组来避免UISwipeActionsConfiguration的双重定义:
let actions: [UIContextualAction]
switch currentShowingStatus {
case .accepted:
actions = [UIContextualAction(...)]
case .sent:
actions = [UIContextualAction(...)]
default:
actions = []
}
let configuration = UISwipeActionsConfiguration(actions: actions)
configuration.performsFirstActionWithFullSwipe = false
return configuration不过,它仍然是UIContextualAction的代码复制。
在您的替代方法中,您可以从actions数组中追加或删除元素。但是这个数组最初是空的。与上面类似,您可以将其简化为
let deleteAction = ...
let actions: [UIContextualAction]
switch currentShowingStatus {
case .accepted, .sent:
actions = [deleteAction]
case .received:
actions = []
}但是- as,您注意到,- you不得不再次评估闭包中的self.currentShowingStatus。由于另一个原因,我会避免这样做:您所依赖的事实是,在执行闭包时,状态并没有改变。
如果首先初始化请求,则可以避免UIContextualAction的代码重复:
let request: Request?
switch currentShowingStatus {
case .accepted:
request = self.acceptedRequests[indexPath.row]
case .sent:
request = self.sentRequests[indexPath.row]
case .received:
request = nil
}
if let request = request {
let deleteAction = UIContextualAction(style: .destructive, title: "Delete") {
_, _, completionHandler in
self.deleteClientRequest(request)
completionHandler(true)
}
let configuration = UISwipeActionsConfiguration(actions: [deleteAction])
configuration.performsFirstActionWithFullSwipe = false
return configuration
} else {
return UISwipeActionsConfiguration(actions: [])
}还请注意,未使用的闭包参数可以被通配符参数_替换。
我可能会这样做,但你当然可以把这些技巧结合起来:
let request: Request?
switch currentShowingStatus {
case .accepted:
request = self.acceptedRequests[indexPath.row]
case .sent:
request = self.sentRequests[indexPath.row]
case .received:
request = nil
}
let actions: [UIContextualAction]
if let request = request {
actions = [UIContextualAction(style: .destructive, title: "Delete") {
_, _, completionHandler in
self.deleteClientRequest(request)
completionHandler(true)
}]
} else {
actions = []
}
let configuration = UISwipeActionsConfiguration(actions: actions)
configuration.performsFirstActionWithFullSwipe = false
return configurationhttps://codereview.stackexchange.com/questions/225447
复制相似问题