Ios 如何更改UITableViewRowAction的标题

Ios 如何更改UITableViewRowAction的标题,ios,swift,Ios,Swift,我有一个用例,需要更改UITableViewRowAction的标题。例如,我有一个餐厅手机,向右滑动时,我会显示“bookmark(104)”,其中“bookmark”是动作,104表示有104人将其加入书签。当点击它时,我希望它变成“bookmark(105)”,因为很明显有一个新用户(当前用户自己)将其添加到了书签中。我该怎么做?尝试了以下代码,但无效 let likeAction = UITableViewRowAction(style: UITableViewRowActionStyl

我有一个用例,需要更改
UITableViewRowAction
的标题。例如,我有一个餐厅手机,向右滑动时,我会显示“bookmark(104)”,其中“bookmark”是动作,104表示有104人将其加入书签。当点击它时,我希望它变成“bookmark(105)”,因为很明显有一个新用户(当前用户自己)将其添加到了书签中。我该怎么做?尝试了以下代码,但无效

let likeAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "bookmark\n\(count)", handler:{(action, indexpath) -> Void in
        ....
        count++
        action.title = "bookmark\n\(count)"
    });

这里有一个简单的例子

假设你有一家有名字和价值的一流餐厅:

class Restaurant {
    var name: String?
    var likes: Int = 0
}
初始化一组
餐厅
对象,并将它们放入名为
数据源
的数组中。您的表视图数据源方法如下所示:

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.
}
我不打算从头开始写一个可滚动的单元格,因为它有很多选项可以使用

然而,我对Andrew Carter试图迭代子视图以直接访问编辑操作中的
ui按钮的尝试很感兴趣。以下是我的尝试:

首先,创建对要修改的
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
}
在共享操作中,遍历按钮的子视图。我们正在寻找和对象(链接以供参考的私有标题)


@JAL是完全正确的-您需要制作自己的滑动视图来完成此操作,或者可以重新加载单元格并在下一张幻灯片中更新。只是为了好玩,我试着在子视图中找到标签,并找到了它,但有趣的是,苹果以某种方式阻止了对标签文本的任何更改。您可以更改其背景色/其他属性,但不能更改文本

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) {

    }

}

此答案使用私有API,不建议在应用商店中使用。显然,无法更改本机
UITableViewRowAction
标题。您可能必须按照其他人的建议实施自定义解决方案,以实现您想要的结果

这里我将遍历
UITableViewCell
的子视图,其中包含私有子视图,并且可能会发生更改,因此如果苹果更改视图层次结构,您的代码可能会在未来的iOS版本中崩溃。 我找到了
UIButtonLabel
的标题

iOS 9.2中的当前视图层次结构为

UITableViewCell
    UITableViewCellDeleteConfirmationView
        _UITableViewCellActionButton
            UIButtonLabel
                UIButton
代码如下:

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]
} 

什么是书签(104)?导航栏中的标题?@SaqibOmer行操作中的标题view@the_UB没有更多的代码了。我不知道如何编码。@SaqibOmer我对这个问题做了一点编辑。当用户滑动单元格时,它会显示带有标题
bookmark(104)
的按钮,当用户点击它时,单元格会向后滑动,隐藏按钮,对吗?因此,下次用户刷卡时,您仍然会看到文本
书签(104)
?您是否检查过count属性,看看它在第二次迭代中是否实际具有值105?这正是我尝试过的方法,但它不起作用。单元格将向后滑动,如果再次向右滑动,您将看到更改。但我希望它能随着来回滑动而改变。我想给用户一些即时反馈。@Edmond如果使用
UITableViewRowAction
,则在不重新加载单元格的情况下无法更改编辑操作的文本。您必须创建自己的自定义滑动视图。这种方法安全吗@JAL@Edmond应用商店安全吗?当然,您正在迭代子视图并使用KVO。您没有使用任何私有API。我已经发布了很多应用程序,在这些应用程序中,我反复浏览并修改/删除了私有类的子视图。@RaphaelOliveira使用
respondsToSelector
和unwrapping optionals以“更安全”的方式编辑了我的答案。但根据我的检查,没有
UILabel
。检查我找到的子视图
cell!。子视图[0]
将成为
UITableViewCellDeleteConfirmationView
单元格!。子视图[0]。子视图[0]
将成为
\u UITableViewCellActionButton
单元格!。子视图[0]。子视图[0]。子视图[0]
将成为
UIButtonLabel
。然而,我们在这里处理的是私有API,所以这并不重要。我们可能无法控制它。@RaphaelOliveira很高兴知道它。谢谢你深入了解@拉斐洛里维拉:不错的尝试。我已使用成功修改
\u UITableViewCellActionButton
文本
值的版本编辑了我的答案。看看吧,这种方法有潜在的危险。你应该迭代子视图,检查每个子视图的类,而不是假设顺序不会改变。我知道,这只是一种理论方法,我在回答中指出,子视图会被修改,可能会导致将来崩溃,不应该在应用商店上使用。好的。现在我认为唯一的方法是创建一个自定义单元格,将一些按钮作为子视图添加到该单元格中,当向右滑动时,将该按钮移动到屏幕上。这个图书馆也许能做到这一点。你们中有谁能总结一个答案,这样我就可以把它记下来。
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]
}