How to change title for UITableViewRowAction

I have a use case when I need to change the title UITableViewRowAction. For example, I have a cell for a restaurant, and when the napkins are right, I show “bookmark (104),” where “bookmark” is the action, and 104 means that there were 104 people. When you click on it, I want it to change to "bookmark (105)", because obviously the new user (the current user himself) has bookmarked it. How can I do it? Tried the code below and it does not work.

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

Here is a quick and dirty example.

Say you have a restaurant with a name and he likes:

class Restaurant {
    var name: String?
    var likes: Int = 0
}

Restaurant dataSource. :

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

, , .

, , subviews UIButton . :

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
}

share, subviews . 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)
            }
        }

    }
}
+3

API, App Store. -, title UITableViewRowAction. , , , .

subviews UITableViewCell, , iOS, Apple . 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]
} 
+3

@JAL is absolutely right - you need to do your own rolling scan to accomplish this, or be ok with reloading the cell and updating it on the next slide. Just for fun, I tried to hack my way through subviews and find a shortcut and was able to find it, but what is funny, Apple somehow blocked any changes made to the text of this shortcut. You can change its background color / other properties, but not 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) {

    }

}

Before After

+2
source

Source: https://habr.com/ru/post/1624741/


All Articles