以编程方式打开UITableView编辑操作按钮

时间:2015-07-21 15:48:15

标签: ios swift uitableview

我的UIPageViewController内有UITableViewControllers,并且在UIPageViewController之间滑动左手势会在视图之间发生变化,并且UITableViewCells手势会打开编辑操作,因此我需要在单元格中单击某个按钮时显示编辑操作。

我的问题是,我是否可以通过编程方式显示编辑操作按钮,而不是在滑动手势上显示它们?

5 个答案:

答案 0 :(得分:10)

Apple有一个私有API可以让你这样做,但是,请注意,除非你使用像 Method Swizzling 这样的东西来混淆所述API的使用,否则这可能会让你的应用程序被App Store拒绝。以下是执行此操作的步骤:

  1. 创建一个名为PrivateMethodRevealer的协议,允许您访问所需的私有Apple API,即显示和关闭编辑操作的API。致this answer提供此公开私有API的方法。协议中的方法声明为optional,因此,如果Apple更改方法的名称,应用程序不会崩溃,而是,它不会显示编辑操作。

    @objc protocol PrivateMethodRevealer {
        optional func setShowingDeleteConfirmation(arg1: Bool)
        optional func _endSwipeToDeleteRowDidDelete(arg1: Bool)
    }
    

    请注意,尽管这些方法引用了delete,但它会显示单元格中的所有UITableViewRowAction

  2. 创建一个函数,用于处理UITableViewCell子类中编辑操作的显示和隐藏(如果有的话),或者在UITableViewCell extension中创建方法。我将此方法命名为showActions以用于演示目的。

  3. 将以下正文添加到您的函数中:

    func showActions() {
        (superview?.superview as? AnyObject)?._endSwipeToDeleteRowDidDelete?(false)
        (self as AnyObject).setShowingDeleteConfirmation?(true)
    }
    

    首先通过调用_endSwipeToDeleteRowDidDelete:(这是单元格的超级视图的超级视图)上的UITableView来解除任何可见单元格的编辑操作,然后显示单元格自己的编辑操作(通过调用{{1 }})。请注意,我们需要关闭其他单元格的操作,因为使用编辑操作显示多行非常错误。

  4. 如果需要,您还可以在setShowingDeleteConfirmation:中创建一个取消当前正在编辑的单元格的按钮。要执行此操作,只需调用以下方法,其中UIViewController是您对tableView的引用:

    UITableView
  5. 如果(tableView as AnyObject)?._endSwipeToDeleteRowDidDelete?(false) UIPageViewController之间的滑动手势存在冲突,只需覆盖UITableViewCell方法即可返回tableView:editingStyleForRowAtIndexPath:

    最后,您的代码可能会产生以下结果 Demo video

    编辑:以下是使用方法调配隐藏API使用情况的快捷方法。致this website提供此方法的基本实现。请注意,我无法保证它能够正常工作,因为无法对其进行实时测试。

    为此,请使用以下代码替换协议,无论您致电.None还是setShowingDeleteConfirmation(true),请将其替换为_endSwipeToDeleteRowDidDelete(false)showRowActions()。但是,此方法似乎会产生一些意想不到的影响,例如hideRowActions()在编辑操作可见时无法响应用户交互。

    UITableViewCell

答案 1 :(得分:0)

我和kabiroberai在找到这个答案的解决方案时走的是同一条路,但采用了两种不同的协议,而不是一种可能被滥用的Objective-C / NSObject协议。这也可以防止必须使协议方法可选。

首先,创建两个单独的协议以在 $http({ method: 'GET', url: 'http://localhost:3000/api/quotes.json', responseType: "json" }).then(function(response) { let quotes = response.data; angular.copy(quotes, quoteArray) quotes.forEach(function (element) { let currentDate = element.expiration_date; console.log(currentDate); var moment = require('moment') var todaysDate = moment("05/17/2016"); var date2 = moment(currentDate) var answer = moment(todaysDate).diff(date2, "days") console.log("this is the answer", answer); if (answer >= 2) { dailyQuoteArray.push(answer) } if (answer <= 7) { weeklyQuoteArray.push(answer) console.log("weeklyquotear length", weeklyQuoteArray.length); } }) }); UITableView上公开私有方法。我通过挖掘每个班级的private headers找到了这些。

UITableViewCell

@objc protocol UITableViewCellPrivate { func setShowingDeleteConfirmation(arg1: Bool) } @objc protocol UITableViewPrivate { func _endSwipeToDeleteRowDidDelete(arg1: Bool) } 中,保留对要显示编辑操作的单元格(或多个单元格)的引用:

cellForRowAtIndexPath

现在,解雇私有方法。我使用了class MyTableViewController: UITableViewController { var cell: UITableViewCell? // ... override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("Cell")! // ... if indexPath.row == 1 { self.cell = cell } return cell } } ,或者您可以使用按钮。

performSelector:withObject:afterDelay

直接致电override func viewDidLoad() { super.viewDidLoad() self.performSelector(#selector(showActionsForCell), withObject: nil, afterDelay: 2.0) } func showActionsForCell() { if let cell = cell { let cellPrivate = unsafeBitCast(cell, UITableViewCellPrivate.self) let tableViewPrivate = unsafeBitCast(self.tableView, UITableViewPrivate.self) // Dismiss any other edit actions that are open tableViewPrivate._endSwipeToDeleteRowDidDelete(false) // Open the edit actions for the selected cell cellPrivate.setShowingDeleteConfirmation(true) } } 是危险的。为安全起见,请检查unsafeBitCastUITableView是否响应这些选择器,或使功能可选。

答案 2 :(得分:0)

在我的情况下(swift 3,iOS11)MGSwipeTableCell非常完美。您可以在

中配置呼叫按钮
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: prettyIdentifier, for: indexPath)

    cell.allowsButtonsWithDifferentWidth = true
    cell.rightButtons = [MGSwipeButton(title: "Delete\npermanently", backgroundColor: #colorLiteral(red: 0.9745360017, green: 0.7205639482, blue: 0.3932176828, alpha: 1)), MGSwipeButton(title: "Undo",backgroundColor: .black)]
    cell.rightSwipeSettings.transition = .rotate3D
    cell.delegate = self

    return cell
}

而不是

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

并接触

extension RecordingViewController: MGSwipeTableCellDelegate {
    func swipeTableCell(_ cell: MGSwipeTableCell, tappedButtonAt index: Int, direction: MGSwipeDirection, fromExpansion: Bool) -> Bool {
        cell.hideSwipe(animated: true)
        // do your stuff here like
        if index == 0 {
            print("right button")
        }

        return true
    }
}

答案 3 :(得分:-2)

设置表视图使用IBAction或其他方法编辑:

@IBAction func editOn(sender: UIBarButtonItem) {
    self.tableView.setEditing(true, animated: true)
}

您可以使用UITableViewController中的方法:

// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    // Return false if you do not want the specified item to be editable.
    return true
}

此方法是编辑动作:

override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
    let action = UITableViewRowAction(style: .Default, title: "Delete") { (rowAction: UITableViewRowAction, indexPAth: NSIndexPath) in
        //code for delete
        print("Delete")
    }
    let action2 = UITableViewRowAction(style: .Normal, title: "Share") { (rowAction: UITableViewRowAction, indexPAth: NSIndexPath) in
        //code for share
        print("Share")
    }
    return [action, action2]
}

希望它有所帮助。

答案 4 :(得分:-4)

点击你的按钮点击活动,请尝试使用以下功能。

func setEditing(_ editing: Bool,
   animated animated: Bool)

这是函数的快速语法。

根据Apple developer support网站,它将执行以下操作,

  

当您使用编辑设置为true的值调用此方法时,和   UITableViewCell对象配置为具有控件,即单元格   显示插入(绿色加)或删除控制(红色减号)   每个单元格的左侧和右侧的重新排序控制。   当这个方法在每个可见单元格上调用时   setEditing:animated:调用UITableView的方法。打电话给这个   编辑设置为false的方法将从单元格中删除控件。

希望这能回答这个问题。