UITableView 滑动关闭 iOS 11
UITableView swipe-to-close in iOS 11
我在使用 UITableView 滑动关闭手势关闭单元格中的操作时遇到了一些问题。当我打开单元格操作时它工作正常,但是当我试图关闭它时,它只会在几次尝试后关闭。
我已经在一个干净的项目中对其进行了测试,并注意到它是 iOS 11 行为,因为在之前的 iOS 版本中,这些操作会通过操作按钮区域外的任何触摸来关闭。
我怎样才能做同样的行为?
视频:https://www.youtube.com/watch?v=rKrk7q0HkeY
代码。就一个案例
class ViewController: UIViewController {
let tableView = UITableView(frame: .zero, style: .plain)
var data = (0...3)
.map { _ in
return (0...5).map { _ in return false }
}
override func loadView() {
super.loadView()
view = tableView
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data[section].count
}
func numberOfSections(in tableView: UITableView) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell.init(style: .default, reuseIdentifier: "cell")
let isSelected = data[indexPath.section][indexPath.row]
cell.textLabel?.text = "Section: \(indexPath.section) \nRow: \(indexPath.row)"
cell.textLabel?.numberOfLines = 0
cell.accessoryType = isSelected ? .checkmark : .none
return cell
}
@available(iOS 11.0, *)
func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(style: .normal, title: "Toggle 2") { [weak self] (action, view, handler) in
guard let data = self?.data else { return }
let isSelected = data[indexPath.section][indexPath.row]
self?.data[indexPath.section][indexPath.row] = !isSelected
self?.tableView.reloadRows(at: [indexPath], with: .fade)
handler(true)
}
action.backgroundColor = .blue
let configuration = UISwipeActionsConfiguration(actions: indexPath.section == 0 ? [action] : [])
configuration.performsFirstActionWithFullSwipe = true
return configuration
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let action = UITableViewRowAction(style: .default,
title: "Toggle") { [weak self] (action, indexPath) in
guard let data = self?.data else { return }
let isSelected = data[indexPath.section][indexPath.row]
self?.data[indexPath.section][indexPath.row] = !isSelected
self?.tableView.reloadRows(at: [indexPath], with: .fade)
}
return [action]
}
}
我找到了解决办法。如果添加前导操作,滑动关闭在 iOS 11 中效果很好。
@available(iOS 11.0, *)
func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(style: .normal, title: "Toggle 2") { [weak self] (action, view, handler) in
guard let data = self?.data else { return }
let isSelected = data[indexPath.section][indexPath.row]
self?.data[indexPath.section][indexPath.row] = !isSelected
self?.tableView.reloadRows(at: [indexPath], with: .fade)
handler(true)
}
action.backgroundColor = .blue
let configuration = UISwipeActionsConfiguration(actions: indexPath.section == 0 ? [action] : [])
configuration.performsFirstActionWithFullSwipe = true
return configuration
}
如果有人对完整代码感兴趣,我已经更新了问题源
我在使用 UITableView 滑动关闭手势关闭单元格中的操作时遇到了一些问题。当我打开单元格操作时它工作正常,但是当我试图关闭它时,它只会在几次尝试后关闭。
我已经在一个干净的项目中对其进行了测试,并注意到它是 iOS 11 行为,因为在之前的 iOS 版本中,这些操作会通过操作按钮区域外的任何触摸来关闭。
我怎样才能做同样的行为?
视频:https://www.youtube.com/watch?v=rKrk7q0HkeY
代码。就一个案例
class ViewController: UIViewController {
let tableView = UITableView(frame: .zero, style: .plain)
var data = (0...3)
.map { _ in
return (0...5).map { _ in return false }
}
override func loadView() {
super.loadView()
view = tableView
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data[section].count
}
func numberOfSections(in tableView: UITableView) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell.init(style: .default, reuseIdentifier: "cell")
let isSelected = data[indexPath.section][indexPath.row]
cell.textLabel?.text = "Section: \(indexPath.section) \nRow: \(indexPath.row)"
cell.textLabel?.numberOfLines = 0
cell.accessoryType = isSelected ? .checkmark : .none
return cell
}
@available(iOS 11.0, *)
func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(style: .normal, title: "Toggle 2") { [weak self] (action, view, handler) in
guard let data = self?.data else { return }
let isSelected = data[indexPath.section][indexPath.row]
self?.data[indexPath.section][indexPath.row] = !isSelected
self?.tableView.reloadRows(at: [indexPath], with: .fade)
handler(true)
}
action.backgroundColor = .blue
let configuration = UISwipeActionsConfiguration(actions: indexPath.section == 0 ? [action] : [])
configuration.performsFirstActionWithFullSwipe = true
return configuration
}
}
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let action = UITableViewRowAction(style: .default,
title: "Toggle") { [weak self] (action, indexPath) in
guard let data = self?.data else { return }
let isSelected = data[indexPath.section][indexPath.row]
self?.data[indexPath.section][indexPath.row] = !isSelected
self?.tableView.reloadRows(at: [indexPath], with: .fade)
}
return [action]
}
}
我找到了解决办法。如果添加前导操作,滑动关闭在 iOS 11 中效果很好。
@available(iOS 11.0, *)
func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(style: .normal, title: "Toggle 2") { [weak self] (action, view, handler) in
guard let data = self?.data else { return }
let isSelected = data[indexPath.section][indexPath.row]
self?.data[indexPath.section][indexPath.row] = !isSelected
self?.tableView.reloadRows(at: [indexPath], with: .fade)
handler(true)
}
action.backgroundColor = .blue
let configuration = UISwipeActionsConfiguration(actions: indexPath.section == 0 ? [action] : [])
configuration.performsFirstActionWithFullSwipe = true
return configuration
}
如果有人对完整代码感兴趣,我已经更新了问题源