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

查看:134
本文介绍了如何以编程方式触发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)
    }
}

那么它是如何运作的?每个单元格都是 UIView ,它继承自抽象 UIResponder 界面。您可以覆盖其方法,以代表分派给它们的事件自行执行操作。这是您覆盖 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天全站免登陆