[英]How to change the title for UITableViewRowAction
I have a use case where I need to change the title of the UITableViewRowAction
. 我有一个用例,我需要更改
UITableViewRowAction
的标题。 For example, I have a restaurant cell, and when swipe right I show "bookmark(104)" where "bookmark" is the action and 104 means there have been 104 people bookmarked it. 例如,我有一个餐厅单元格,当向右滑动时,我显示“书签(104)”,其中“书签”是动作,104表示已有104人为其添加书签。 When click on it, I want it to change to "bookmark(105)" because obviously there's a new user(the current user himself) has bookmarked it.
单击它时,我希望它更改为“书签(105)”,因为显然有一个新用户(当前用户自己)已经为其添加了书签。 How do I do that?
我怎么做? Tried the below code and it doesn't work.
尝试下面的代码,它不起作用。
let likeAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "bookmark\n\(count)", handler:{(action, indexpath) -> Void in
....
count++
action.title = "bookmark\n\(count)"
});
Here's a quick and dirty example. 这是一个快速而肮脏的例子。
Say you have a class Restaurant with a name and likes value: 假设你有一个餐厅,名字和喜欢的价值:
class Restaurant {
var name: String?
var likes: Int = 0
}
You initialize a bunch of Restaurant
objects, and put them in an array called dataSource
. 初始化一堆
Restaurant
对象,并将它们放在一个名为dataSource
的数组中。 Your table view data source methods will look like this: 您的表视图数据源方法如下所示:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.dataSource.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .Default, reuseIdentifier: "cell");
cell.textLabel?.text = dataSource[indexPath.row].name
return cell
}
// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
// This can be empty if you're not deleting any rows from the table with your edit actions
}
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
// First, create a share action with the number of likes
let shareAction = UITableViewRowAction(style: .Default, title: "\(self.dataSource[indexPath.row].likes)") { (action, indexPath) -> Void in
// In your closure, increment the number of likes for the restaurant, and slide the cell back over
self.dataSource[indexPath.row].likes++
self.tableView.setEditing(false, animated: true)
}
return [shareAction] // return your array of edit actions for your cell. In this case, we're only returning one action per row.
}
I'm not going to write a scrollable cell from scratch, since this question has a bunch of options you can use. 我不打算从头开始编写可滚动的单元格,因为这个问题有很多你可以使用的选项。
I was, however, intrigued by Andrew Carter's attempt to iterate through subviews to access the UIButton
in the edit action directly. 然而,我对Andrew Carter试图通过子视图直接访问编辑动作中的
UIButton
感到好奇。 Here is my attempt: 这是我的尝试:
First, create a reference to the UITableViewCell
(or an array of cells), you wish to modify, for this example, I'll be using a single cell: 首先,创建对
UITableViewCell
(或单元格数组)的引用,您希望修改,对于此示例,我将使用单个单元格:
var cellRef: UITableViewCell?
// ...
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .Default, reuseIdentifier: "cell");
cell.textLabel?.text = dataSource[indexPath.row].name
cellRef = cell;
return cell
}
In your share action, iterate through the button's subviews. 在您的共享操作中,遍历按钮的子视图。 We're looking for the
UITableViewCellDeleteConfirmationView
and _UITableViewCellActionButton
objects (private headers linked for reference). 我们正在寻找
UITableViewCellDeleteConfirmationView
和_UITableViewCellActionButton
对象(链接的私有头文件以供参考)。
let shareAction = UITableViewRowAction(style: .Default, title: "\(self.dataSource[indexPath.row].likes)") { (action, indexPath) -> Void in
var deleteConfirmationView: UIView? // UITableViewCellDeleteConfirmationView
if let subviews = self.cellRef?.subviews {
for subview in subviews {
if NSClassFromString("UITableViewCellDeleteConfirmationView") != nil {
if subview.isKindOfClass(NSClassFromString("UITableViewCellDeleteConfirmationView")!) {
deleteConfirmationView = subview
break
}
}
}
}
if let unwrappedDeleteView = deleteConfirmationView {
if unwrappedDeleteView.respondsToSelector("_actionButtons") {
let actionbuttons = unwrappedDeleteView.valueForKey("_actionButtons") as? [AnyObject]
if let actionButton = actionbuttons?.first as? UIButton { // _UITableViewCellActionButton
actionButton.setTitle("newText", forState: .Normal)
}
}
}
}
This answer uses private API and it's NOT recommended to be used on the App Store. 此答案使用私有API , 不建议在App Store上使用。 Apparently there is no way to change the
title
of the native UITableViewRowAction
. 显然,无法更改本机
UITableViewRowAction
的title
。 You may have to implement your custom solution as suggested by others to achieve the result you want. 您可能必须按照其他人的建议实施自定义解决方案,以实现您想要的结果。
Here I'm traversing the subviews of UITableViewCell
which contains private subviews and are subject to change so your code may crash on future iOS releases if Apple changes the view hierarchy. 在这里,我将遍历
UITableViewCell
的子视图,其中包含私有子视图,并且可能会发生变化,因此如果Apple更改视图层次结构,您的代码可能会在未来的iOS版本上崩溃。 I found the header of UIButtonLabel
here . 我在这里找到了
UIButtonLabel
的标题。
The current view hierarchy as per iOS 9.2 is iOS 9.2的当前视图层次结构是
UITableViewCell
UITableViewCellDeleteConfirmationView
_UITableViewCellActionButton
UIButtonLabel
UIButton
Here is the code: 这是代码:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let shareAction = UITableViewRowAction(style: .Default, title: "\(dataList[indexPath.row].likes)") { (action, indexPath) -> Void in
self.dataList[indexPath.row].likes++
let cell = tableView.cellForRowAtIndexPath(indexPath)
let privateView = cell!.subviews[0].subviews[0].subviews[0]
let privateButton = privateView.valueForKey("_button") as! UIButton
privateButton.setTitle("\(self.dataList[indexPath.row].likes)", forState: .Normal)
}
return [shareAction]
}
@JAL is totally right- you need to make your own sliding view to accomplish this, or be ok with reloading the cell and having it updated on the next slide out. @JAL是完全正确的 - 您需要创建自己的滑动视图来完成此任务,或者可以重新加载单元格并在下一张幻灯片中更新它。 Just for fun I tried to hack my way through the subviews and find the label and was able to find it, but what's funny is Apple has somehow blocked any changes being made to the text of that label.
只是为了好玩,我试图通过子视图破解我的方式并找到标签并且能够找到它,但有趣的是Apple以某种方式阻止了对该标签文本的任何更改。 You can change it's background color / other properties but not the text!
您可以更改它的背景颜色/其他属性,但不能更改文本!
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
return cell
}
func findRowActionLabelForCell(cell: UITableViewCell?) -> UILabel? {
guard let cell = cell else {
return nil
}
var label: UILabel? = nil
for view in cell.subviews {
label = findRowActionLabelForView(view)
if label != nil {
break
}
}
return label
}
func findRowActionLabelForView(view: UIView) -> UILabel? {
for subview in view.subviews {
if let label = subview as? UILabel {
return label
} else {
return findRowActionLabelForView(subview)
}
}
return nil
}
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let action = UITableViewRowAction(style: .Default, title: "Test", handler: { (action, indexPath) -> Void in
let cell = self.tableView.cellForRowAtIndexPath(indexPath)
if let label = self.findRowActionLabelForCell(cell) {
label.text = "New Value"
label.backgroundColor = UIColor.blueColor()
}
})
return [action]
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.