How to programmatically select a row in UITableView in Swift

IosSwiftUitableview

Ios Problem Overview


I need to select a row in a UITableView programmatically using Swift 1.2.

This is the simple code:

var index = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.selectRowAtIndexPath(index, animated: true, scrollPosition: UITableViewScrollPosition.Middle)
self.tableView(self.tableView, didSelectRowAtIndexPath: index)

The above gives me the following error:

>Cannot invoke 'selectRowAtIndexPath' with an argument list of type '(NSIndexPath!, animated: Bool, scrollPosition: UITableViewScrollPosition)'

What is wrong with my Swift 1.2 code?

My UItableView has been created in IB in the UIViewController that I am trying to call the code above. When I put the code in a UITableViewController the compiler does not give any errors. Do I need to embed a UITableViewController in a container or is there another way?

Ios Solutions


Solution 1 - Ios

Swift 3 to Swift 5 Solution

Selecting a Row

let indexPath = IndexPath(row: 0, section: 0)
myTableView.selectRow(at: indexPath, animated: true, scrollPosition: .bottom)
myTableView.delegate?.tableView!(myTableView, didSelectRowAt: indexPath)

DeSelecting a Row

let deselectIndexPath = IndexPath(row: 7, section: 0)
myTableView.deselectRow(at: deselectIndexPath, animated: true)
myTableView.delegate?.tableView!(myTableView, didDeselectRowAt: indexPath)

Solution 2 - Ios

The statement

self.tableView.selectRowAtIndexPath(index, animated: true, scrollPosition: UITableViewScrollPosition.Middle)

assumes that tableView is a property of the view controller, connected to a table view in the Storyboard. A UITableViewController, for example, already has this property.

In your case, the view controller is a not a table view controller but a subclass of a UIViewController. It also has an outlet that is connected to the table view, but it is not called tableView but menuTable. Then of course you have to call

self.menuTable.selectRowAtIndexPath(index, animated: true, scrollPosition: UITableViewScrollPosition.Middle)

to select a row of that table view.

The strange error messages are caused by the fact that self.tableView can also be understood by the compiler as a "curried function" (compare http://oleb.net/blog/2014/07/swift-instance-methods-curried-functions/).

Solution 3 - Ios

Use below code,after loading your table view with data:

let rowToSelect:NSIndexPath = NSIndexPath(forRow: 0, inSection: 0);  //slecting 0th row with 0th section
self.tableView.selectRowAtIndexPath(rowToSelect, animated: true, scrollPosition: UITableViewScrollPosition.None);

now,you have to manually call didSelectRowAtIndexPath: delegate method using below code:

self.tableView(self.tableView, didSelectRowAtIndexPath: rowToSelect); //Manually trigger the row to select

Thanks.

Solution 4 - Ios

Swift 3.x

if you want to do it at the 'cell-creation', you can do it like this

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = TableViewCell()
    let item = items[indexPath.row]
    
    cell.textLabel?.text    = item.title
    
    if (item.checked) {
        tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
    }
    
    return cell
}

Solution 5 - Ios

Using Swift 2.x, as described by Pankaj purohit answers the correct method is:

func tapRowAtIndex(index:Int) {
        let rowToSelect:NSIndexPath = NSIndexPath(forRow: index, inSection: 0)
        self.tableView.selectRowAtIndexPath(rowToSelect, animated: true, scrollPosition: UITableViewScrollPosition.None)
        self.tableView(self.tableView, didSelectRowAtIndexPath: rowToSelect)
}

Keep in mind that if you call this method from an external class for example, you dont know when tableView has finished its loading, so what's the possibilities?, how to workaround this problem? :

Step one: create a class boolean var

var automatingTap: Bool = false

Step two: check when the table finish its loading and launch an "end operations" method:

func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) 
{
    let lastRowIndex = tableView.numberOfRowsInSection(0)
    if indexPath.row == lastRowIndex - 1 {
       endOperations()
    }
}
    
func endOperations() 
{
   print("finished loading")
   if automatingTap {
        tapRowAtIndex(0)
        automatingTap = false
   }
}

Step three: call my tableView class from another class

for example:

override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {
    if segue!.identifier == "DetailsTableView" {
        let viewController:ViewController = segue!.destinationViewController as ViewController
        viewController.automatingTap = true
    }
}

Solution 6 - Ios

Reusable function with validation of table size

Swift 4 and 5

This reusable function works and validate the size of table.

func selectRow(tableView: UITableView, position: Int) {
    let sizeTable = tableView.numberOfRows(inSection: 0)
    guard position >= 0 && position < sizeTable else { return }
    let indexPath = IndexPath(row: position, section: 0)
    tableView.selectRow(at: indexPath, animated: true, scrollPosition: .middle)
}

you can use it in this way

selectRow(tableView: myTableView, position: pos)

or you can implement this extension:

extension UITableView {
    func selectRow(row: Int, section: Int = 0) {
        let sizeTable = self.numberOfRows(inSection: section)
        guard row >= 0 && row < sizeTable else { return }
        let indexPath = IndexPath(row: row, section: section)
        self.selectRow(at: indexPath, animated: true, scrollPosition: .middle)
    }
}

and you can use it in this way:

mytableView.selectRow(row: pos, section: 0)

or

mytableView.selectRow(row: pos)

Solution 7 - Ios

Swift 4.2:

Select one or more Rows

let ndx:IndexSet = [1]
// or:  let ndx:IndexSet = [1, 2, 3]; // etc
tableview?.selectRowIndexes(ndx, byExtendingSelection: false);

Deselect a Single Row

tableview?.deselectRow(current)

Note that if you have (func tableViewSelectionDidChange(...)) implemented, that will be triggered by the above.

Also see Charlton Provatas' answer at https://stackoverflow.com/a/48696458/352920 for an extension to NSTableView, that provides a simple

tableview?.selectRow(at:) 

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMikeeView Question on Stackoverflow
Solution 1 - IosSourabh SharmaView Answer on Stackoverflow
Solution 2 - IosMartin RView Answer on Stackoverflow
Solution 3 - IosPankaj purohitView Answer on Stackoverflow
Solution 4 - IosSanduView Answer on Stackoverflow
Solution 5 - IosAlessandro OrnanoView Answer on Stackoverflow
Solution 6 - IosblackerView Answer on Stackoverflow
Solution 7 - Iosrip...View Answer on Stackoverflow