Murat Kaya Murat Kaya - 1 year ago 138
Swift Question

Draw a border around a UITableviewCell when selected with UILongPressGestureRecognizer

I am trying to update UITableViewCell's border when the user performs a long press gesture on the cell, but it's not updating.

Here is my


let objLongPressHandler = UILongPressGestureRecognizer(target: self, action: #selector(self.longPressHandler(_:)))
objLongPressHandler.view?.tag = indexPath.row
objLongPressHandler.delegate = self
objLongPressHandler.enabled = true
objLongPressHandler.minimumPressDuration = 0.1


This is my function

func longPressHandler(objGesture: UILongPressGestureRecognizer) {

let center = objGesture.view?.center
let rootViewPoint = objGesture.view!.superview?.convertPoint(center!, toView: self.tableView)
let indexPath = self.tableView.indexPathForRowAtPoint(rootViewPoint!)
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath!) as! GroupTableViewCell
cell.contentView.layer.borderColor = UIColor.redColor().CGColor
cell.contentView.layer.borderWidth = 3

Answer Source
  1. Multiple gesture recognisers are not necessary. Use a single long tap gesture recogniser on the main view for the view controller.
  2. When handling the gesture, convert the location to table view coordinates using locationInView. Get the selected row by calling tableView.indexPathForRowAtPoint.
  3. Loop through the visible rows in the table view. If the row is at the selected index path then show the border, otherwise remove the border.


override func viewDidLoad() {

    // Install tap gesture recogniser on main view.
    let gesture = UILongPressGestureRecognizer(target: self, action: #selector(self.longPressHandler(_:)))
    gesture.enabled = true
    gesture.minimumPressDuration = 0.1


func longPressHandler(gesture: UILongPressGestureRecognizer) {

    // Get the location of the gesture relative to the table view.
    let location = gesture.locationInView(tableView)

    // Determine the row where the touch occurred.
    guard let selectedIndexPath = tableView.indexPathForRowAtPoint(location) else {

    // Iterate through all visible rows.
    guard let indexPaths = tableView.indexPathsForVisibleRows else {

    for indexPath in indexPaths {

        // Get the cell for each visible row.
        guard let cell = tableView.cellForRowAtIndexPath(indexPath) else {

        // If the index path is for the selected cell, then show the highlighted border, otherwise remove the border.
        let layer = cell.contentView.layer

        if indexPath == selectedIndexPath {
            layer.borderColor = UIColor.redColor().CGColor
            layer.borderWidth = 3
        else {
            layer.borderWidth = 0



override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 10

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
    cell.textLabel?.text = "Cell #\(indexPath.row)"
    return cell

enter image description here

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download