我的UIPageViewController
内有UITableViewControllers
,并且在UIPageViewController
之间滑动左手势会在视图之间发生变化,并且UITableViewCells
手势会打开编辑操作,因此我需要在单元格中单击某个按钮时显示编辑操作。
我的问题是,我是否可以通过编程方式显示编辑操作按钮,而不是在滑动手势上显示它们?
答案 0 :(得分:10)
Apple有一个私有API可以让你这样做,但是,请注意,除非你使用像 Method Swizzling 这样的东西来混淆所述API的使用,否则这可能会让你的应用程序被App Store拒绝。以下是执行此操作的步骤:
创建一个名为PrivateMethodRevealer
的协议,允许您访问所需的私有Apple API,即显示和关闭编辑操作的API。致this answer提供此公开私有API的方法。协议中的方法声明为optional
,因此,如果Apple更改方法的名称,应用程序不会崩溃,而是,它不会显示编辑操作。
@objc protocol PrivateMethodRevealer {
optional func setShowingDeleteConfirmation(arg1: Bool)
optional func _endSwipeToDeleteRowDidDelete(arg1: Bool)
}
请注意,尽管这些方法引用了delete
,但它会显示单元格中的所有UITableViewRowAction
。
创建一个函数,用于处理UITableViewCell
子类中编辑操作的显示和隐藏(如果有的话),或者在UITableViewCell
extension
中创建方法。我将此方法命名为showActions
以用于演示目的。
将以下正文添加到您的函数中:
func showActions() {
(superview?.superview as? AnyObject)?._endSwipeToDeleteRowDidDelete?(false)
(self as AnyObject).setShowingDeleteConfirmation?(true)
}
首先通过调用_endSwipeToDeleteRowDidDelete:
(这是单元格的超级视图的超级视图)上的UITableView
来解除任何可见单元格的编辑操作,然后显示单元格自己的编辑操作(通过调用{{1 }})。请注意,我们需要关闭其他单元格的操作,因为使用编辑操作显示多行非常错误。
如果需要,您还可以在setShowingDeleteConfirmation:
中创建一个取消当前正在编辑的单元格的按钮。要执行此操作,只需调用以下方法,其中UIViewController
是您对tableView
的引用:
UITableView
如果(tableView as AnyObject)?._endSwipeToDeleteRowDidDelete?(false)
和UIPageViewController
之间的滑动手势存在冲突,只需覆盖UITableViewCell
方法即可返回tableView:editingStyleForRowAtIndexPath:
。
编辑:以下是使用方法调配隐藏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)
}
}
是危险的。为安全起见,请检查unsafeBitCast
和UITableView
是否响应这些选择器,或使功能可选。
答案 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的方法将从单元格中删除控件。
希望这能回答这个问题。