返回 导航

Swift

hangge.com

Swift - 自定义tableViewCell滑动事件按钮1(使用iOS8的左滑按钮接口)

作者:hangge | 2017-12-18 08:10
我们知道在 iOS 系统的邮件 App 中,当我们向左滑动某个条目时,右侧会出现三个按钮,点击即可对该条目进行相关的操作。

iOS8 起,Apple 开放了 editActionsForRowAt 这个代理方法,使用这个方法我们可以很轻松地实现这种滑动单元格时出现更多选项的功能。

1,效果图

(1)我们在 tableView 上向左滑动某个 cell 时,其右侧会出现“更多”“旗标”“删除”这三个按钮选项。
                      

(2)当点击“更多”“旗标”按钮时,页面上会弹出相关的操作信息。
           

(3)最右侧的“删除”按钮除了点击会触发外,如果系统是 iOS11 的话直接往左一滑到底也会触发,触发后会将当前行数据给删除。
                      

2,样例代码

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
    
    var tableView:UITableView?
    
    var items = ["这个是条目1","这个是条目2","这个是条目3","这个是条目4",
                 "这个是条目5","这个是条目6","这个是条目7","这个是条目8",]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //创建表格视图
        self.tableView = UITableView(frame:self.view.frame, style:.plain)
        self.tableView!.delegate = self
        self.tableView!.dataSource = self
        //创建一个重用的单元格
        self.tableView!.register(UITableViewCell.self,
                                 forCellReuseIdentifier: "SwiftCell")
        self.view.addSubview(self.tableView!)
    }
    
    //在本例中,有1个分区
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    //返回表格行数(也就是返回控件数)
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count
    }
    
    //创建各单元显示内容(创建参数indexPath指定的单元)
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
        -> UITableViewCell {
            //为了提供表格显示性能,已创建完成的单元需重复使用
            let identify:String = "SwiftCell"
            //同一形式的单元格重复使用,在声明时已注册
            let cell = tableView.dequeueReusableCell(
                withIdentifier: identify, for: indexPath)
            cell.textLabel?.text = items[indexPath.row]
            return cell
    }
    
    //返回每一个行对应的事件按钮
    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath)
        -> [UITableViewRowAction]? {
            //创建“更多”事件按钮
            let more = UITableViewRowAction(style: .normal, title: "更多") {
                action, index in
                UIAlertController.showAlert(message: "点击了“更多”按钮")
            }
            more.backgroundColor = UIColor.lightGray
            
            //创建“旗标”事件按钮
            let favorite = UITableViewRowAction(style: .normal, title: "旗标") {
                action, index in
                UIAlertController.showAlert(message: "点击了“旗标”按钮")
            }
            favorite.backgroundColor = UIColor.orange
            
            //创建“删除”事件按钮
            let delete = UITableViewRowAction(style: .normal, title: "删除") {
                action, index in
                //将对应条目的数据删除
                self.items.remove(at: index.row)
                tableView.reloadData()
            }
            delete.backgroundColor = UIColor.red
            
            //返回所有的事件按钮
            return [delete, favorite, more]
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

//扩展UIAlertController
extension UIAlertController {
    //在指定视图控制器上弹出普通消息提示框
    static func showAlert(message: String, in viewController: UIViewController) {
        let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "确定", style: .cancel))
        viewController.present(alert, animated: true)
    }
    
    //在根视图控制器上弹出普通消息提示框
    static func showAlert(message: String) {
        if let vc = UIApplication.shared.keyWindow?.rootViewController {
            showAlert(message: message, in: vc)
        }
    }
}

附:禁用在 iOS11 下默认的滑动到底行为

1,问题描述

使用 editActionsForRowAt 方法配置的事件按钮,在 iOS11 前的系统下只能通过点击触发。而在 iOS11 系统下除了点击外,滑动到底后还会自动调用第一个按钮的事件。但有时可能我们不想要这个新特性。

2,解决办法

(1)如果应用只需要支持 iOS11 的话,直接改用 iOS11 提供的 trailingSwipeActionsConfigurationForRowAt 新接口即可,它可以设置是否要启用滑动行为。具体参考:Swift - 自定义tableViewCell滑动事件按钮2(使用iOS11的滑动按钮接口)

(2)如果还需要支持低版本系统,那就两个方法都写。低版本下设备肯定没有滑动触发行为。而到了 iOS11 设备下,新的接口方法又回自动覆盖老方法,所有也是没问题的。
//返回每一个行对应的事件按钮
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath)
    -> [UITableViewRowAction]? {
        //创建“删除”事件按钮
        let delete = UITableViewRowAction(style: .normal, title: "删除") {
            action, index in
            //将对应条目的数据删除
            self.items.remove(at: index.row)
            tableView.reloadData()
        }
        delete.backgroundColor = UIColor.red
        
        //返回所有的事件按钮
        return [delete]
}

//尾部滑动事件按钮(左滑按钮)
@available(iOS 11.0, *)
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt
    indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    //创建“删除”事件按钮
    let delete = UIContextualAction(style: .destructive, title: "删除") {
        (action, view, completionHandler) in
        //将对应条目的数据删除
        self.items.remove(at: indexPath.row)
        completionHandler(true)
    }
    
    //返回所有的事件按钮
    let configuration = UISwipeActionsConfiguration(actions: [delete])
    configuration.performsFirstActionWithFullSwipe = false
    return configuration
}
评论

全部评论(2)

回到顶部