如何以编程方式触发UITableViewCell editActions? [英] How to trigger UITableViewCell editActions programmatically?

查看:103
本文介绍了如何以编程方式触发UITableViewCell editActions?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在tableviewcell上进行了一些自定义编辑操作.滑动时效果很好,但是我想知道当我点击单元格时是否有任何触发这些动作的方法.另外,我已经看到很多人仅仅回答了类似的问题,

I have made a few custom edit actions on my tableviewcell. It works fine when I swipe, but I was wondering if there was any way to trigger these actions when I tap the cell. Also, I have seen lots of people answer similar questions with just,

tableView.setEditing(true, animated: true)

尽管这不是我正在寻找的解决方案.我希望这些动作可以立即显示,而无需按下另一个按钮.

though this is not the solution I am looking for. I want the actions to immediately get displayed without the press of another button.

推荐答案

简短的答案是-没有这种方法.

Short answer is - there is no such way.

但是,如果确实需要类似的内容,则可以模仿这种行为,尽管它需要您自己进行更多的实现和状态处理.

However, if you really need something like that, you can mimic this behaviour, though it requires lot more implementation and state handling on your own.

这是一个快速且非常肮脏的解决方案,它会覆盖自定义单元格的touchesEnded方法.请记住在相关情节提要的表视图中将Cell设置为该单元的动态原型,并将其重用标识符设置为identitifer.

Here is a quick and very dirty solution, which overrides touchesEnded method of your custom cell. Remember to set up Cell as a dynamic prototype of the cell in your table view in relevant storyboard and set its reuse identifier to identitifer.

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, CellDelegate {

    @IBOutlet weak var tableView: UITableView?
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "identifier") as? Cell else {
            return UITableViewCell()
        }
        cell.textLabel?.text = "\(indexPath.row)"
        cell.indexPath = indexPath
        cell.delegate = self
        return cell
    }

    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
        return nil
    }

    func doAction(for cell: Cell) {
        let indexPath = cell.indexPath
        print("doing action for cell at: \(indexPath!.row)")
        // your implementation for action
        // maybe delete a cell or whatever?
        cell.hideFakeActions()

    }

}

protocol CellDelegate: class {
    func doAction(for cell: Cell)
}

class Cell: UITableViewCell {

    weak var delegate: CellDelegate?
    var indexPath: IndexPath!

    @IBOutlet weak var buttonAction1: UIButton?
    @IBOutlet weak var constraintButtonFakeActionWidth: NSLayoutConstraint?

    override func awakeFromNib() {
        self.constraintButtonFakeActionWidth?.constant = 0
    }
    override func touchesEnded(_ touches: Set<UITouch>,
                               with event: UIEvent?) {
        guard let point = touches.first?.location(in: self) else {
            return
        }
        if self.point(inside: point, with: event) {

            print("event is in cell number \(indexPath.row)")
            self.showFakeActions()

        }
    }

    func showFakeActions() {
        self.constraintButtonFakeActionWidth?.constant = 80
        UIView.animate(withDuration: 0.3) {
            self.layoutIfNeeded()
        }
    }

    func hideFakeActions() {
        self.constraintButtonFakeActionWidth?.constant = 0
        UIView.animate(withDuration: 0.3) {
            self.layoutIfNeeded()
        }
    }

    @IBAction func fakeAction() {
        delegate?.doAction(for: self)
    }
}

那么它如何工作?每个单元都是从抽象UIResponder接口继承的UIView.您可以重写其方法,以代表分派给它们的事件自行执行操作.这是覆盖touchesEnded的第一步.

So how does it work? Each cell is a UIView which inherits from abstract UIResponder interface. You can override its methods to do actions on your own on behalf of events that are dispatched to them. This is the first step where you override touchesEnded.

看看界面生成器的屏幕截图-您必须连接约束.

Take a look at the screenshot from interface builder - you have to hook up the constraint.

我还实现了委托,该委托对于单元格的所有编辑操作均返回nil,因此它们不会干扰您的解决方法.

I've also implemented the delegate which returns nil for all edit actions of the cells, so they don't interfere with your workaround.

接下来,您设置一个自定义委托以从单元中获取回调.我还将IndexPath附加到该单元,以便于管理必须实现的dataSource中的数据.

Next, you set up a custom delegate to get a callback from the cell. I also attached IndexPath to the cell for the convenience of managing data in the dataSource, which you have to implement.

请记住,此代码缺少很多内容,例如prepareForReuse方法的实现.另外,您可能希望在touchesEnded覆盖中进行其他检查,以确保每次触摸均不会多次触发此委托回调,并防止多次触摸.此处也未实现用于禁用单元上的用户交互的逻辑.并且界面需要进行微调(例如,文本在动画过程中似乎被压缩).

Remember that this code lacks a lot, like prepareForReuse method implementation. Also, you probably want to do additional checks in touchesEnded override which would guarantee that this delegate callback is not fired more than once per touch and prevent multiple touches. The logic for disabling user interaction on a cell is not implemented here as well. And interface requires fine-tuning (like text appears to be squashed during the animation).

这篇关于如何以编程方式触发UITableViewCell editActions?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆